Правильный счет времени на МК?

Обсуждаем контроллеры компании Atmel.
Ответить
Первый раз сказал Мяу!
Сообщения: 32
Зарегистрирован: Чт мар 06, 2008 10:59:45

Сообщение dbf-334 »

Всем привет! :)

Уважаемые коты, подскажите, как точно считать время на МК? Пользуюсь программой BASCOM и Attiny4313, еще установлен кварц на 4МГц. Мне нужно реализовать точный отсчет времени для таймера, такова задумка устройства. Не могу точно подобрать значение таймера, он убегает на несколько секунд спустя минуту и тем более четверть часа. В часах обычно используется кварц на 32768Гц, а у меня стоит на 4МГц. Может есть какая формула или алгоритм учитывающая эту погрешность поделитесь плиз? Подозреваю, что нужно использовать аппаратный таймер МК (например Timer-0), но с ним тоже не могу точно подобрать тактирование времени... не знаю как сделать. :(
Реклама
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 330
Зарегистрирован: Чт июн 23, 2011 07:55:51

Сообщение korsaj »

Подбираете наиболее близкое значения для таймера, это значение должно давать промежутки времени меньше нужного интервала. Дальше выравниваете интервал пустыми командами, циклами задержки, а может и первым и вторым, зависит от того насколько меньше полученный интервал от нужного.
Реклама
akl
Друг Кота
Сообщения: 4450
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Как точно нужно отсчитывать временные интервалы? Как вариант: настраиваете Т0 на счет Fclk и прерывание по переполнению, организуете счетчик переполнений и компаратор. Каждые 64мкс будет прерывание, наращиваете счетчик, сравниваете с компаратором. Получаете таймер с периодом 64мкс. Можно в предпоследнем прерывании по переполнению включить OCR0A, куда предварительно записать нужное число. Тогда можно отмерять интервалы с дискретом 0.25мкс.
Первый раз сказал Мяу!
Сообщения: 32
Зарегистрирован: Чт мар 06, 2008 10:59:45

Сообщение dbf-334 »

Я так пока выпутываюсь из ситуации:

Код: Выделить всё

//объявляю таймер
Config Timer0 = Timer , [b]Prescale = 1024[/b]
On Timer0 Proc_timer:                                      
Enable Interrupts
Enable Timer0


//блок обработки таймера
Proc_timer:
   //подсветка ЖКИ
   If Temp_lcd_light > 0 Then
      Temp_lcd_light = Temp_lcd_light - 1
      Portb.1 = 0
   Else
      Portb.1 = 1
   End If

   //текст с другой лабудой
   .........

Return
Рассмотрим на примере подсветки экрана. При нажатии на кнопку переменная принимает значение Temp_lcd_light = 60. Из расчета 15*4=60, т.е. мне нужно что бы подсветка индикатора горела "15сек", где значение "4" является моим коэффициентом (нашел методом тыка). Работаю только с целыми числами, без запятой. Далее блок обработки таймера, с учетом коэф. самого таймера Prescale = 1024 при каждом своем переполнении вызавает блок обработки, где Temp_lcd_light уменьшается каждый раз на единицу до нуля. Как только значение Temp_lcd_light становится равным нулю, подсветка гаснет. Таймер соответственно все равно продолжает работать. )) Как еще можно иначе поступить? Пользоваться дополнительными компонентами DS1307 для точного отсчета времени и цеплять к ней кварц на 32678гц не очень бы хотелось.

Вопрос №2: Как правильно пользоваться Prescale и вести расчет времени возникновения прерывания таймера в зависимости от установленного кварца?
Реклама
Эиком - электронные компоненты и радиодетали
Первый раз сказал Мяу!
Сообщения: 32
Зарегистрирован: Чт мар 06, 2008 10:59:45

Сообщение dbf-334 »

akl писал(а): Как вариант: настраиваете Т0 на счет Fclk
Про это можно подробнее, я не очень силен в программировании МК... :)
Реклама
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

dbf-334 писал(а):Уважаемые коты, подскажите, как точно считать время на МК?
Возьмем TIM0. Предделитель N=1 т.к. при других коэф-тах получим нецелые значения.
В секунду получим 4.000.000Hz/256 = 15625Hz, это частота переполнений таймера и возникновения прерываний. Чтобы получить секундный интервал надо организовать программный счетчик на 15625.
Примерно так:

Код: Выделить всё

uint16_t cnt = 15625;//программный счетчик, 16 бит
uint8_t  sec = FALSE;//секундный флаг

interrupt TIM0_OVF( void )
{
  if( cnt > 0 )
  {
  cnt = cnt - 1;
  }
  else
  {
  cnt = 15625;// перезагрузим счетчик
  sec = TRUE;// прошла 1 секунда
  };
}
Аналогичным образом можно построить задержку на несколько секунд/дней/месяцев.
dbf-334 писал(а): Как правильно пользоваться Prescale и вести расчет времени возникновения прерывания таймера в зависимости от установленного кварца?
Прикрепляю формулу из даташита.
Но она может меняться от режима работы(Normal, CTC, Phase corr и т.д.). Рекомендую обратиться к документации произодителя.
Вложения
TIM_OVF_FREQ.PNG
(11.94 КБ) 488 скачиваний
Реклама
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

uk8amk писал(а):при других коэф-тах получим нецелые значения.
Так, для информации :) , 4 миллиона делиться на цело на все коэффициенты с приведённой вами картинки кроме 1024.

dbf-334, на тини4313 есть 16 битный таймер.
4000000 / 64 = 62500
или
4000000 / 256 = 15625
При делителе таймера на 64 или 256 можно использовать режим таймера CTC и получить прерывание 1 раз в секунду.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Первый раз сказал Мяу!
Сообщения: 32
Зарегистрирован: Чт мар 06, 2008 10:59:45

Сообщение dbf-334 »

Спасибо всем большое! :)
Стал лучше понимать, как этим нужно пользоваться. В выходные обязательно попробую Ваш совет. :tea:
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Да, а добавив к этому коррекцию каждый час/сутки (грубую и точную) можно добиться неплохой точности хода на обычном кварце. У меня получилась секунда в 4-5 месяцев (при стабильной температуре, разумеется. Часы дома)
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Kavka писал(а):4 миллиона делиться на цело на все коэффициенты с приведённой вами картинки кроме 1024.
Да, но кроме самого коэф-та есть еще сам счетчик с ТОП=256. Поэтому если предделитель не равен 1, то нужно использовать режим CTC чтобы получить целое число тактов.
Первый раз сказал Мяу!
Сообщения: 32
Зарегистрирован: Чт мар 06, 2008 10:59:45

Сообщение dbf-334 »

Надо будет про режимы работы таймера еще почитать. ;) Спасибо!

Полагаю, число в формуле всегда должно быть целым, путем подбора частоты кварца или значения Prescale таймера. Иначе возникает погрешность из-за остатка в искомом числе... А можно еще программно менять значение кварца, добиваясь получения целого числа по формуле? Например, у меня стоит кварц на 4МГц, а я программно определил его как скажем $crystal =2500000. Т.е. получается, что таймер будет работать опираясь на значение регистра $crystal или все же опираться на 4МГц давая тем самым еще большую погрешность? В случае с командами Wait и Waitms в BASCOM в данной ситуации они начинают по разному вести значение времени задержки в коде программы, опираясь на значение $crystal.

У меня с МК внешний компонент работает только при значении $crystal =1000000 по протоколу 1wire. С коэффициентами таймера целое число никак не получить, тут нужный режим его работы спасет. ))
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Сообщение pokk »

ploop, А из за чего может возникать погрешность хода ? можете не много рассказать про коррекцию ?

Давно меня интересовал вопрос на кой в часах с контролёрами используют кварц на 32 768 Гц.
сейчас мельком глянул, только для того что бы снизить потребляемый ток ?

Много всяких предделителей можно использовать.
Изображение
8948079.zip
(195.17 КБ) 221 скачивание
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

А из за чего может возникать погрешность хода ?
Из-за погрешности частоты кварца. Будь она идеальной, часы ходили бы тоже идеально. Погрешность зависит от собственной погрешности при изготовлении кварца, температуры, напряжения питания, а так же качества монтажа и разводки платы. Напряжение у нас более-менее стабильно, а вот на температуру и всё остальное мы влиять не можем.
Давно меня интересовал вопрос на кой в часах с контролёрами используют кварц на 32 768 Гц
сейчас мельком глянул, только для того что бы снизить потребляемый ток ?
В принципе да. Этот кварц подключается напрямую к асинхронному таймеру МК. Асинхронным он называется потому, что может работать не от основной тактовой шины контроллера, а от своего кварца независимо. Вот его цепляют, а он себе и тикает потихоньку. При этом, если необходимо, можно отключить ненужные блоки МК, а само ядро погрузить в спячку, энергопотребление сильно снижается. А таймер так и будет тикать, как будто он отдельно стоит.

Удобнее, конечно, когда в МК есть отдельный блок RTC, т.е. встроенные часы. Они имеют отдельное питание, кварц и прочее. Контроллер, при необходимости, просто считывает время с них.
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Сообщение pokk »

Благодарю за пояснения.
orinoko

Сообщение orinoko »

Есть ещё один вариант полученя заданной частоты, в лоб, без специальных режимов таймера. Рассмотрим текущую задачу. начальная частота 4 МГц = 256*125*125. Используем таймер0. Ставим предделитель на 256. В прерывании записываем в TCNT0 число 256-125=131, и далее уже доп. программный счётчик на 125 (однобайтный). Таким образом прерывание реже будет вызываться - 125 раз в сек.
Держит паяльник хвостом
Сообщения: 927
Зарегистрирован: Вт сен 07, 2010 19:27:48
Откуда: Ташкент

Сообщение borys »

Немного добавлю к пояснению ploop. Число 32768 есть просто 2 в степени 15. То есть, пятнадцать раз делим на 2
и получаем 1 Герц. На двойку делить проще всего. Так было выбрано в стародавние времена, когда самыми доступ-
ными были элементы И-НЕ и D-триггеры. Оказалось удобным и осталось до сих пор.
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

В прерывании записываем в TCNT0 число 256-125=131
И получаем неконтроллируемое увеличение периода таймера на десяток-другой(и гораздо больше если прерывание возникнет в момент обработки другого) тактов на основной частоте. Ведь момент с возникновения прерывания до присваивания ему нового числа будет утерян - таймер после присваивания сбросит предделитель и начнет счет заново, то что насчитал предделитель после прерывания и до присваивания будет утеряно. Этот факт очень легко не заметить а потом удивляться неточности хода часов, перекладывая вину на кварц.
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

можно ссылку на эту информацию? я не нашел в описании предделителя таймера AVR информации о его сбросе при изменении значения счетного регистра.
знаю, что можно вручную его сбросить, но чтобы он сам сбрасывался - не слышал. И скорее всего не услышу...
Ставим плюсы: )
orinoko

Сообщение orinoko »

Изменение значения таймера никак не влияет работу предделителя. За сброс предделителя отвечает флаг PSR10 регистра GTCCR. Понятно, что изменить число в таймере нужно до того, как оно увеличится на единицу, т.е. не позже 256 тактов МК. Я же не сказал, что моё решение - это круто. Это одно из вариантов. Естественно, нужно не забывать про эту фичу. А чтобы избежать этой фичи, таймер перевести в режим CTC
Последний раз редактировалось orinoko Вт май 21, 2013 14:46:53, всего редактировалось 2 раза.
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Сообщение a_skr »

вот тоже удивился. искал и не нашел. в DS написано:
The Timer/Counter Register gives direct access, both for read and write operations, to the
Timer/Counter unit 8-bit counter. Writing to the TCNT0 Register blocks (removes) the Compare
Match on the following timer clock. Modifying the counter (TCNT0) while the counter is running,
introduces a risk of missing a Compare Match between TCNT0 and the OCR0x Registers.
TCNT0 представляет прямой доступ к счетчику. запись в него блокирует на один такт таймера схему сравнения. но про предделитель ничего нет.
Ответить

Вернуться в «AVR»