Страница 1 из 2

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

Добавлено: Чт май 16, 2013 16:16:46
dbf-334
Всем привет! :)

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

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

Добавлено: Чт май 16, 2013 16:31:57
korsaj
Подбираете наиболее близкое значения для таймера, это значение должно давать промежутки времени меньше нужного интервала. Дальше выравниваете интервал пустыми командами, циклами задержки, а может и первым и вторым, зависит от того насколько меньше полученный интервал от нужного.

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

Добавлено: Чт май 16, 2013 16:47:06
akl
Как точно нужно отсчитывать временные интервалы? Как вариант: настраиваете Т0 на счет Fclk и прерывание по переполнению, организуете счетчик переполнений и компаратор. Каждые 64мкс будет прерывание, наращиваете счетчик, сравниваете с компаратором. Получаете таймер с периодом 64мкс. Можно в предпоследнем прерывании по переполнению включить OCR0A, куда предварительно записать нужное число. Тогда можно отмерять интервалы с дискретом 0.25мкс.

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

Добавлено: Чт май 16, 2013 17:11:51
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 и вести расчет времени возникновения прерывания таймера в зависимости от установленного кварца?

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

Добавлено: Чт май 16, 2013 17:14:22
dbf-334
akl писал(а): Как вариант: настраиваете Т0 на счет Fclk
Про это можно подробнее, я не очень силен в программировании МК... :)

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

Добавлено: Чт май 16, 2013 19:30:27
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 и т.д.). Рекомендую обратиться к документации произодителя.

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

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

dbf-334, на тини4313 есть 16 битный таймер.
4000000 / 64 = 62500
или
4000000 / 256 = 15625
При делителе таймера на 64 или 256 можно использовать режим таймера CTC и получить прерывание 1 раз в секунду.

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

Добавлено: Чт май 16, 2013 20:07:11
dbf-334
Спасибо всем большое! :)
Стал лучше понимать, как этим нужно пользоваться. В выходные обязательно попробую Ваш совет. :tea:

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

Добавлено: Чт май 16, 2013 20:28:05
ploop
Да, а добавив к этому коррекцию каждый час/сутки (грубую и точную) можно добиться неплохой точности хода на обычном кварце. У меня получилась секунда в 4-5 месяцев (при стабильной температуре, разумеется. Часы дома)

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

Добавлено: Чт май 16, 2013 20:38:26
uk8amk
Kavka писал(а):4 миллиона делиться на цело на все коэффициенты с приведённой вами картинки кроме 1024.
Да, но кроме самого коэф-та есть еще сам счетчик с ТОП=256. Поэтому если предделитель не равен 1, то нужно использовать режим CTC чтобы получить целое число тактов.

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

Добавлено: Чт май 16, 2013 20:52:36
dbf-334
Надо будет про режимы работы таймера еще почитать. ;) Спасибо!

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

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

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

Добавлено: Чт май 16, 2013 21:09:58
pokk
ploop, А из за чего может возникать погрешность хода ? можете не много рассказать про коррекцию ?

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

Много всяких предделителей можно использовать.
Изображение
8948079.zip
(195.17 КБ) 221 скачивание

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

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

Удобнее, конечно, когда в МК есть отдельный блок RTC, т.е. встроенные часы. Они имеют отдельное питание, кварц и прочее. Контроллер, при необходимости, просто считывает время с них.

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

Добавлено: Пт май 17, 2013 06:46:24
pokk
Благодарю за пояснения.

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

Добавлено: Пт май 17, 2013 11:31:27
orinoko
Есть ещё один вариант полученя заданной частоты, в лоб, без специальных режимов таймера. Рассмотрим текущую задачу. начальная частота 4 МГц = 256*125*125. Используем таймер0. Ставим предделитель на 256. В прерывании записываем в TCNT0 число 256-125=131, и далее уже доп. программный счётчик на 125 (однобайтный). Таким образом прерывание реже будет вызываться - 125 раз в сек.

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

Добавлено: Пт май 17, 2013 18:35:03
borys
Немного добавлю к пояснению ploop. Число 32768 есть просто 2 в степени 15. То есть, пятнадцать раз делим на 2
и получаем 1 Герц. На двойку делить проще всего. Так было выбрано в стародавние времена, когда самыми доступ-
ными были элементы И-НЕ и D-триггеры. Оказалось удобным и осталось до сих пор.

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

Добавлено: Вт май 21, 2013 14:20:32
Alexeyslav
В прерывании записываем в TCNT0 число 256-125=131
И получаем неконтроллируемое увеличение периода таймера на десяток-другой(и гораздо больше если прерывание возникнет в момент обработки другого) тактов на основной частоте. Ведь момент с возникновения прерывания до присваивания ему нового числа будет утерян - таймер после присваивания сбросит предделитель и начнет счет заново, то что насчитал предделитель после прерывания и до присваивания будет утеряно. Этот факт очень легко не заметить а потом удивляться неточности хода часов, перекладывая вину на кварц.

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

Добавлено: Вт май 21, 2013 14:26:47
ibiza11
можно ссылку на эту информацию? я не нашел в описании предделителя таймера AVR информации о его сбросе при изменении значения счетного регистра.
знаю, что можно вручную его сбросить, но чтобы он сам сбрасывался - не слышал. И скорее всего не услышу...

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

Добавлено: Вт май 21, 2013 14:38:11
orinoko
Изменение значения таймера никак не влияет работу предделителя. За сброс предделителя отвечает флаг PSR10 регистра GTCCR. Понятно, что изменить число в таймере нужно до того, как оно увеличится на единицу, т.е. не позже 256 тактов МК. Я же не сказал, что моё решение - это круто. Это одно из вариантов. Естественно, нужно не забывать про эту фичу. А чтобы избежать этой фичи, таймер перевести в режим CTC

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

Добавлено: Вт май 21, 2013 14:42:19
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 представляет прямой доступ к счетчику. запись в него блокирует на один такт таймера схему сравнения. но про предделитель ничего нет.