Микроконтроллеры AVR - применение и Краткий Курс - часть 10

 
1 14 15 16 17 18 38
RU Ignis Caelum #30.01.2011 21:23  @alex_zeed#30.01.2011 16:50
+
-
edit
 

Ignis Caelum

опытный

Кто-нибудь оценивал точность внешних кварцов (12 Мгц,18, 24 ) ?
у меня получалось лишние или нехватающие тики в соотношении 1/10000.
Лучше быть оптимистом и ошибаться, чем пессимистом, который всегда прав.  4.04.0
+
-
edit
 

Xan

координатор

I.C.> Кто-нибудь оценивал точность внешних кварцов (12 Мгц,18, 24 ) ?
I.C.> у меня получалось лишние или нехватающие тики в соотношении 1/10000.

Примерно так и есть.
В доках на обычные кварцы несколько десятков миллионных, это и получится 1/10000.
2...5 миллионных — это уже специальные генераторы.
 7.07.0
+
-
edit
 

Ignis Caelum

опытный

I.C.>> Кто-нибудь оценивал точность внешних кварцов (12 Мгц,18, 24 ) ?
I.C.>> у меня получалось лишние или нехватающие тики в соотношении 1/10000.
Xan> Примерно так и есть.
Xan> В доках на обычные кварцы несколько десятков миллионных, это и получится 1/10000.
Xan> 2...5 миллионных — это уже специальные генераторы.

как на этом фоне смотрятся часовые генераторы (32768 Гц) ?
набегающая ошибка у них намного меньше.
Лучше быть оптимистом и ошибаться, чем пессимистом, который всегда прав.  8.0.552.2158.0.552.215
+
-
edit
 

Xan

координатор

I.C.> как на этом фоне смотрятся часовые генераторы (32768 Гц) ?
I.C.> набегающая ошибка у них намного меньше.

Ну как намного меньше?
1...2 секунды в сутки — это примерно 20 миллионных, обычная точность.
Более точные встречаются реже.

А в чём проблема случилась?
Обычно кварцевой точности с избытком хватает.
 7.07.0
+
-
edit
 

Ignis Caelum

опытный

Xan> А в чём проблема случилась?
Xan> Обычно кварцевой точности с избытком хватает.
часы в устройстве на атмеге с кварцем накапливают ошибку размером примерно 1/10000 относительно часов на компьютере.
Лучше быть оптимистом и ошибаться, чем пессимистом, который всегда прав.  8.0.552.2158.0.552.215
RU Андрей Суворов #31.01.2011 13:32  @Ignis Caelum#30.01.2011 21:23
+
-
edit
 

Андрей Суворов

координатор

I.C.> Кто-нибудь оценивал точность внешних кварцов (12 Мгц,18, 24 ) ?
I.C.> у меня получалось лишние или нехватающие тики в соотношении 1/10000.

Я как раз сейчас строю приёмник станции РБУ. в инете есть две схемы - Полякова, попроще с умножителем добротности, и Анкудинова, посложнее, с кварцевым фильтром и двойным преобразованием частоты.

Если будет хороший источник опоры, можно подогнать частоту кварца конденсатором.
Вот схема Анкундинова:

Вот схема Полякова:
404
 8.08.0
Это сообщение редактировалось 31.01.2011 в 13:41
UA alex_zeed #31.01.2011 14:11  @Андрей Суворов#31.01.2011 13:32
+
-
edit
 

alex_zeed

втянувшийся

А.С.> Если будет хороший источник опоры, можно подогнать частоту кварца конденсатором.
А можно просто коррекцию сделать - условно говоря, раз в какое-то время (минуты) прибавлять-отнимать нужное кол-во миллисекунд к счетчику. Подобного плана коррекцию встречал в советских кварцевых часах.
 3.6.133.6.13
+
-
edit
 

MartKot

втянувшийся

Кто тут у нас с помощью МК на жисть зарабатывает? В чём прикол у А.В. Евстифеева в формуле ADC = (Uin*1024)/Uref для перевода значений АЦП Меги в вольты? У Меги АЦП 10bit, значит, результат преобразования лежит в пределах min=0, max=1023. Пусть Uref=5В, Uin=5В, тогда ADC = 1024, а это уже 11bit. Получается, умножать надо на 1023, а не на 1024. ?
Прикреплённые файлы:
 
Простите,-спросили Мартовского Кота,-действительно ли в марте месяце? Какая чушь,- ответил Мартовский Кот,- и март месяц не исключение! http://martkot.embedders.org  

Xan

координатор

MartKot> Пусть Uref=5В, Uin=5В, тогда ADC = 1024

Не, не так. АЦП = 1023
Для напруги примерно от 4.9975 и выше АЦП выдаёт 1023 = 1111111111

А для напруги ниже 0.0025 — 0000000000
0.0025 ... 0.0075 — 0000000001
0.0075 ... 0.0125 — 0000000010
4.9875 ... 4.9925 — 1111111101
4.9925 ... 4.9975 — 1111111110
выше 4.9975 — 1111111111

Вычти из Uin Uref/2048 и формула будет вести себя хорошо! :)

ADC = ((Uin * 1024) - 0.5) / Uref
 7.07.0

MartKot

втянувшийся

Xan> Для напруги примерно от 4.9975 и выше АЦП выдаёт 1023 = 1111111111
Xan> выше 4.9975 — 1111111111
Xan> Вычти из Uin Uref/2048 и формула будет вести себя хорошо! :)
Xan> ADC = ((Uin * 1024) - 0.5) / Uref

Тогда, так что ли получается:
ADC = (4,9975*1024)/5= 1023,488 ->1023 (получается правильно)
ADC = (4,9975*1023)/5= 1022,4885 ->1022
А 2048 откуда? Точность преобразования?
Простите,-спросили Мартовского Кота,-действительно ли в марте месяце? Какая чушь,- ответил Мартовский Кот,- и март месяц не исключение! http://martkot.embedders.org  

Xan

координатор

MartKot> А 2048 откуда? Точность преобразования?

Это половинка ступеньки = половина шага квантования.

Ну вот если АЦП однобитный, то он при напруге ниже 2.5 вольт должен выдавать ноль, а выше — единицу.
Или я этим только запутаю? :)

У реального АЦП ступеньки только в среднем 0.005 вольта.
Если аккуратно померить, то их величина колеблется в пределах 0.001 ... 0.009. Это если фирма гарантирует "no missing code".
А если не гарантирует, то вполне могут быть и меньше нуля, и больше 0.010.
 7.07.0

MartKot

втянувшийся

Xan> Или я этим только запутаю? :)
Да не, нормально! Теперь всё понял. Я подошёл к формуле АЦП с "аналоговой" точки зрения, не учитывая процесс преобразования, а надо было с "цифровой" :)
Простите,-спросили Мартовского Кота,-действительно ли в марте месяце? Какая чушь,- ответил Мартовский Кот,- и март месяц не исключение! http://martkot.embedders.org  
RU Ignis Caelum #18.04.2011 12:27
+
-
edit
 

Ignis Caelum

опытный

Тема: как на МК АТМЕГА задавать красивые временные промежутки.

Несколько раз у участников форума встречал реализации устройств на атмеге с очень странными временными промежутками, используемыми для записи данных. Чаще всего - 61 раз в секунду.
понятно что технике всеравно, но как то не красиво :). Плохо переводится в термины старика Герца.
счетчики в МК имеют функционал, позволяющий решить этот вопрос - получение любой заданной частоты.

Для этого надо отказаться от прерывания по переполнению, а использовать прерывание по совпадению с заранее заданным числом.
Расчет этого числа выглядит следующим образом:
Период между прерываниями T = ((1024 * 180) * / 18 432 000) = 0.01 сек ==> для установления частоты срабатывания прерывания 100 Гц следует использовать прескалер 1024 и число сравнения 180.

Бывает что не влазит необходимое число (остаток от деления нацело) в 8-битный счетчик - использую тогда 16битный.
И надо не забыть . что верктор прерывания теперть

Пример.
.cseg
.org 000
rjmp _reset
.org OC2addr
rjmp _interrupt_timer_overcount
//....//

_timer_init: ; устанавливает делитель частоты и запускает таймер
ldi r16, low(cT2top -1 ) ; загружаю (180-1)
mOut OCR2 , r16 ; установлю TOP для TCNT2 при котором он будет обнуляться
mIn r16, TIMSK
ori r16, (1<< OCIE2) ; разрешает прерывание по совпадению Timer2 и OCIE1A
mOut TIMSK, r16

ldi r16, (1<<WGM21) ; устанавливает режим CTC (назначение битов WGM между счетчиками отличаются)
ori r16, (1<<CS22)|(1<<CS21)|(1<<CS20) ; устанавливает делитель частоты 1024
mOut TCCR2,r16
// счетчик запустился
ret

//....//
_interrupt_timer_overcount:
код, выполняемый через заданный промежуток времени.
ret
Лучше быть оптимистом и ошибаться, чем пессимистом, который всегда прав.  8.0.552.2158.0.552.215
RU Massaraksh #18.04.2011 13:06  @Ignis Caelum#18.04.2011 12:27
+
-
edit
 

Massaraksh

аксакал
★☆
I.C.>...
Ага, принцип понятен.

I.C.>...с очень странными временными промежутками...61 раз в секунду.
Тут всё просто, 4000000/65536=61.035...
Я исходил при измерении частоты из принципа разумной достаточности - при работе ёмкостного датчика частота меняется не более, чем в 2 раза. Сигнал датчика (частота) вешается на прерывание int0 и там просто инкрементируется. А 61 раз в секунду происходит подсчет и сброс.
UA Serge77 #18.04.2011 13:17  @Ignis Caelum#18.04.2011 12:27
+
-
edit
 

Serge77

модератор

I.C.> счетчики в МК имеют функционал, позволяющий решить этот вопрос - получение любой заданной частоты.
I.C.> Для этого надо отказаться от прерывания по переполнению, а использовать прерывание по совпадению с заранее заданным числом.

Такой функционал в Меге8 только в одном таймере, а у меня он занят под ШИМ. Поэтому осталось 61, хотя и хотел поменять.
RU Ignis Caelum #18.04.2011 13:18  @Massaraksh#18.04.2011 13:06
+
-
edit
 

Ignis Caelum

опытный

I.C.>>...с очень странными временными промежутками...61 раз в секунду.
Massaraksh> Тут всё просто, 4000000/65536=61.035...
Massaraksh> Я исходил при измерении частоты из принципа разумной достаточности - при работе ёмкостного датчика частота меняется не более, чем в 2 раза. Сигнал датчика (частота) вешается на прерывание int0 и там просто инкрементируется. А 61 раз в секунду происходит подсчет и сброс.

Почему такой промежуток - понятно. просто не эстетично :).
1. на int0 вешать не надо, можно было сразу завести на TCNT1 - аппаратный 16 битный счетчик.
2. убери из подпрограммы прерывания int0 команды cli и sei. они лишние.

кратко блок схема реализованная у меня в устройстве.
я считаю количество тиков измеряемой частоты за заданный период 0,01. и общее количество тактов процессора прошедшего за во время этик тиков. от фронта до фронта.
Искомая частота это Fизм = CNTизм * Fproc / CNTproc.
Лучше быть оптимистом и ошибаться, чем пессимистом, который всегда прав.  8.0.552.2158.0.552.215
RU Ignis Caelum #18.04.2011 13:19  @Serge77#18.04.2011 13:17
+
-
edit
 

Ignis Caelum

опытный

Serge77> Такой функционал в Меге8 только в одном таймере, а у меня он занят под ШИМ. Поэтому осталось 61, хотя и хотел поменять.
1. такой функционал во всех трех таймерах.
2. есть идея как отказаться от шима. попробуем - о результатах сообщу.
Лучше быть оптимистом и ошибаться, чем пессимистом, который всегда прав.  8.0.552.2158.0.552.215
PL GOGI #18.04.2011 13:26  @Ignis Caelum#18.04.2011 13:19
+
-
edit
 

GOGI

координатор
★★★★
Не вижу какой-то надобности во временных интервалах, кратных десяти.
На конечном этапе постройки графика и скажем вычисления полного импульса абслотно по барабану 60 или 100 раз в секунду выборка. Мы получаем или график или число, никак не связанное с частотой выборки.
1  
RU Ignis Caelum #18.04.2011 13:37  @GOGI#18.04.2011 13:26
+
-
edit
 

Ignis Caelum

опытный

GOGI> Не вижу какой-то надобности во временных интервалах, кратных десяти.
конечно нет. но удобней для понимания.

В конечном устройстве на внутренние часы завязаны несколько процессов.
каждый процесс отрабатывает со своей частотой. кто-то 100 Гц, кто-то, 40 Гц, кто-то 10 Гц. Временные промежутки между событиями опять же задаются в секундах.
проще сделать, чем каждый раз помнить коэффициенты пересчета.

P.S.
Данный пост был не вызван не попыткой обращения в свой веру, а желанием поделиться приемом, которым пользуюсь. (я просто разместил объяву... )
Лучше быть оптимистом и ошибаться, чем пессимистом, который всегда прав.  8.0.552.2158.0.552.215
RU Massaraksh #18.04.2011 13:54  @Ignis Caelum#18.04.2011 13:37
+
-
edit
 

Massaraksh

аксакал
★☆
I.C.> Данный пост был не вызван не попыткой обращения в свой веру, а желанием поделиться приемом, которым пользуюсь. (я просто разместил объяву... )
Да понятно, я спросил - ты ответил.
I.C.> убери из подпрограммы прерывания int0 команды cli и sei. они лишние.
Привычка.
Это сообщение редактировалось 18.04.2011 в 16:04
RU Massaraksh #19.05.2011 08:32  @Massaraksh#18.04.2011 13:54
+
-
edit
 

Massaraksh

аксакал
★☆
В помощь определяющим апогей.
Блок усреднения данных высотомера, работающего по принципу, описанному Serge77, по скользящему среднему на 2,4,8,16,32,64,128 точек и хранение их за последние 5 секунд.



code text
  1. ;--------------------------регистры
  2. ;
  3. ;       $060-$15F - кольцевой буфер (рабочий) для вычисления усредненных данных на
  4. ;                   (2^N) N=1...7 значений (A)
  5. ;       $160-$28C - кольцевой буфер последних 150 значений (300 байт)
  6. ;                   сглаженных данных в SRAM (Б)
  7. ;
  8. ;       r0  - N
  9. ;       r1  - счетчик начала отсчета скользяшего среднего
  10. ;       r2  - текущее смещение в буфере (A) (Low)
  11. ;       r3  - рабочий
  12. ;       r4  - рабочий
  13. ;       r5  - рабочий
  14. ;       r6  - рабочий
  15. ;       r7  - текущее смещение в буфере Б (High)
  16. ;       r8  - текущее смещение в буфере Б (Low)
  17. ;       r9  -
  18. ;       r10 -
  19. ;       r11 -
  20. ;       r12 -
  21. ;       r13 -
  22. ;       r14 -
  23. ;       r15 -
  24. ;       r16 -
  25. ;       r17 - рабочий
  26. ;       r18 -
  27. ;       r19 -
  28. ;       r20 - Сумма ADC (Low)
  29. ;       r21 - Сумма ADC (High)
  30. ;       r22 -
  31. ;       r23 -
  32. ;       r24 -
  33. ;       r25 -
  34. ;       r26 - регистр X (Low)
  35. ;       r27 - регистр X (High)
  36. ;       r28 -
  37. ;       r29 -
  38. ;       r30 -
  39. ;       r31 -
  40. ;
  41. ;--------------------------------Начальные установки
  42.         clr r20
  43.         clr r21
  44.         clr r1
  45.         clr r7
  46.         clr r8
  47.         clr r2
  48.         sei
  49. idle:   rjmp idle            ;---Idle
  50.  
  51. ................................................
  52.  
  53. ;------------------------Сюда приходит суммированное 64 раза значение АЦП (r21:r20)
  54.           inc r2           ;--------увеличиваем указатель в буфере усреднения
  55.           inc r2
  56.           rcall power
  57.           add r6,r6
  58.           cp  r2,r6
  59.           brne ac1
  60.           clr r2           ;--------конец буфера? на начало
  61. ac1:      ldi r26,$060
  62.           clr r27
  63.           clr r17
  64.           add r26,r2
  65.           adc r27,r17
  66.           st X+,r20        ;--------запись полученного значения в кольцевой буфер усреднения
  67.           st X+,r21
  68.           inc r1
  69.           rcall power
  70.           cp  r1,r6       ;--------пора начинать усреднение?
  71.           brne accno       ;--------рано
  72. ;--------------------------------Подсчет суммы в цикле
  73.           ldi r26,$060
  74.           clr r27
  75.           push r21
  76.           push r20
  77.           clr r20
  78.           clr r21
  79.           clr r4
  80.           clr r3
  81.           clr r17
  82. ac2:      ld r6,X+
  83.           ld r5,X+
  84.           add r20,r6      ;--------сложение 2-ух трёхбайтных чисел
  85.           adc r21,r5
  86.           adc r4,r3
  87.           rcall power
  88.           inc r17
  89.           cp r17,r6
  90.           brne ac2
  91. ;-----------------------получили сумму, делим 3-х байтовое число на 2^N
  92.           clr r17
  93. ac3:      ror r4
  94.           ror r21
  95.           ror r20
  96.           inc r17
  97.           cp r17,r0
  98.           brne ac3
  99. ;--------------------------теперь всегда усреднять
  100.           rcall power
  101.           mov r1,r6
  102.           dec r1
  103. ;--------------------------запись в кольцевой буфер сглаженных значений за последние 5 секунд
  104. ;--------------------------(это у меня 5 секунд, потому что 30 опросов в секунду)
  105. ;--------------------------иначе буфер надо расширить
  106.           ldi r26,$60
  107.           ldi r27,1
  108.           add r26,r8
  109.           adc r27,r7
  110.           st X+,r20
  111.           st X+,r21
  112. ;----------указатель смещаем
  113.           clr r4
  114.           inc r4
  115.           inc r4
  116.           clr r3
  117.           add r8,r4
  118.           adc r7,r3
  119. ;----------по кольцу
  120.           mov r17,r8
  121.           cpi r17,$2C
  122.           brne accno
  123.           mov r17,r7
  124.           cpi r17,1
  125.           brne accno
  126.           clr r7
  127.           clr r8
  128. ;-----------------------------запись r20,r21 в EEPROM
  129. accno:    pop r20
  130.           pop r21
  131. ..........................
  132. ;-------------------------------п/п возведения в степень
  133. ;
  134. ;        r0 - N
  135. ;        r6 - 2^^N
  136. ;
  137. power:   push r17
  138.          ldi r17,2
  139.          mov r6,r17
  140.          clr r5
  141. pow1:    inc r5
  142.          cp r5,r0
  143.          breq powfin
  144.          push r0
  145.          push r1
  146.          push r18
  147.          mov r18,r6
  148.          fmul r18,r17
  149.          ror r1
  150.          ror r0
  151.          mov r6,r0
  152.          pop r18
  153.          pop r1
  154.          pop r0
  155.          rjmp pow1
  156. powfin:  pop r17
  157.          ret
Это сообщение редактировалось 20.05.2011 в 05:38
UA Serge77 #19.05.2011 09:01  @Massaraksh#19.05.2011 08:32
+
-
edit
 

Serge77

модератор

Massaraksh> Блок усреднения данных высотомера, работающего по принципу, описанному Serge77, по скользящему среднему на 8 точек и хранение их за последние 5 секунд.

Думаю, для определения апогея лучше усреднять не 8-10 точек, а намного больше. Наверно нужно усреднять точки за 0.5-1 секунду полёта. Попробую сегодня на своих полётных данных.
RU Massaraksh #19.05.2011 09:09  @Serge77#19.05.2011 09:01
+
-
edit
 

Massaraksh

аксакал
★☆
Serge77> Думаю, для определения апогея лучше усреднять не 8-10 точек, а намного больше. Наверно нужно усреднять точки за 0.5-1 секунду полёта. Попробую сегодня на своих полётных данных.
Тогда будет запаздывание на ту же секунду. А за секунду ракета сколько может пролететь...

Upd: Хотя, изменения в алгоритме для этого будут минимальными - константы поменять.
Это сообщение редактировалось 19.05.2011 в 09:25
UA Serge77 #19.05.2011 10:09  @Massaraksh#19.05.2011 09:09
+
-
edit
 

Serge77

модератор

Massaraksh> Тогда будет запаздывание на ту же секунду.

Да, будет.

Massaraksh> А за секунду ракета сколько может пролететь...

5 м
AD Реклама Google — средство выживания форумов :)
RU Alexeev Max #19.05.2011 11:53  @Massaraksh#19.05.2011 08:32
+
-
edit
 

Alexeev Max

втянувшийся

Massaraksh> В помощь определяющим апогей.

Я без разрешения немного посоветую :)

Операция деления
;-----------------------получили сумму, делим на 8
ror r4
ror r21
ror r20
ror r4
ror r21
ror r20
ror r4
ror r21 ;------------------результат (r21:r20)
ror r20

ror - это сдвиг вправо, освободившийся бит берется из флага переноса Система команд микроконтроллера avr Команда ROR Соответственно флаг переноса нужно чистить командой clc перед началом каждого этапа деления либо использовать первой операцией логический сдвиг вправо lsr - в освободившийся бит пишется 0 Система команд микроконтроллера avr Команда LSR. В твоем случае деление выдаст полную абракадабру, т.к. на момент начала деления что с флагом переноса неизвестно и при новом сдвиге ror r4 в 7-й бит будет попадать бит от предыдущей операции.

т.е.

code text
  1. ;-----------------------получили сумму, делим на 8
  2.  clc
  3.  ror r4
  4.  ror r21
  5.  ror r20
  6.  clc
  7.  ror r4
  8.  ror r21
  9.  ror r20
  10.  clc
  11.  ror r4
  12.  ror r21 ;------------------результат (r21:r20)
  13.  ror r20

либо
code text
  1. ;-----------------------получили сумму, делим на 8
  2.  lsr r4
  3.  ror r21
  4.  ror r20
  5.  lsr r4
  6.  ror r21
  7.  ror r20
  8.  lsr r4
  9.  ror r21 ;------------------результат (r21:r20)
  10.  ror r20
 
1 14 15 16 17 18 38

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru