Выбор коэффициента деления таймера 1 в ATmega48

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
metan
Вымогатель припоя
Сообщения: 593
Зарегистрирован: Ср янв 06, 2010 10:01:46

Выбор коэффициента деления таймера 1 в ATmega48

Сообщение metan »

Здравствуйте, уважаемые!
Решил на старости лет познакомиться с микроконтроллерами.
Задумал сделать часы в свою девятку. Нашел мегу48, покурил данный славный сайт, даташит конечно, книжки.
Написал программу часов - термометра, не всю конечно сам, огромный респект и уважуха авторам, делящимся своими разработками (Danko в частности), вытравил плату, запаял, сделал программатор по своей схеме, чтобы не скучно было :), прошил это дело.
Работает, ура!
Поставил в автомобиль и приступил к лётным испытаниям.
Результат плачевный - часы отстают примерно на 2 минуты в сутки. Ужос.

Тактирую от кварца 4 МГц, конденсаторы 22 pF, кварц менял на 8 Мгц, визуально идут в 2 раза быстрее (проверил корректность установки Fuse bits), точность с 8 МГц кварцом не проверял. Пробовал установить другой кварц на 4 МГц, тоже отстают на те же пару минут.
Поправил режим таймера 1 с Normal на CTC, не помогло.
Продраил плату зубной щёткой со спиртом - результат тот же, лучше бы выпил с горя :)

Тикают часы в прерывании таймера 1
Его код инициализации:

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

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 62,500 kHz
// Mode: CTC  top=OCR1A
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x0B;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x02;
OCR1AL=0x71;
OCR1BH=0x00;
OCR1BL=0x00;
Процедура прерывания:

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

// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)    //Прерывание происходит с частотой 62500 Гц / 625(0x271) = 100 раз в сек 
{ 
// TCNT1H=0x00;
// TCNT1L=0x00;
  milliseconds++;
//  PORTC.4 = 1;
  if (milliseconds >= 100 ) { milliseconds = 0; seconds++; }
  if (seconds >= 10) { seconds = 0; ten_seconds++; } 
  if (ten_seconds >= 6) { ten_seconds = 0; minutes++; ign_sens=1; }
  if (minutes >= 10)  {  minutes = 0; ten_minutes++; }  
  if (ten_minutes >= 6) { ten_minutes = 0; hours++; }
  if (hours >= 10) { hours = 0; ten_hours++; }
  if (ten_hours >= 2 && hours == 4)  { ten_hours = 0; hours = 0; }
//  PORTC.4 = 0;   
}
Правда, есть еще прерывание таймера 2 с частотой около 62500 Гц / 256 = 244 Гц
(вывод на индикаторы - семисегментные светодиодные), но это прерывание вроде не должно влиять на точность хода часов, или я не прав?
Больше прерываний нет. Есть еще запреты прерываний в процедуре опроса датчиков DS18B20, но я эти датчики пока не устанавливал, и они не опрашиваются.

Посчитал на калькуляторе процент погрешности часов, выяснил, что его можно скомпенсировать, уменьшив на единичку содержимое регистра OCR1A. Поставил вместо 0x271=625 значение 0x270=624.
Неделю часы идут практически секунда в секунду. Но ведь это вроде неверно! Нет мне покоя :(

Буду очень признателен за любое мнение по поводу - где могла порыться собака.
Реклама
Аватара пользователя
md5sum
Вымогатель припоя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

Re: Выбор коэффициента деления таймера 1 в ATmega48

Сообщение md5sum »

Классическая ошибка...
Частота 62500, 100 раз в сек это 625 (0x271) тиков таймера -> следовательно OCR1=0x270
А не 0x271 как в листинге.

PS: f OCnA = f clk/(2 ⋅ N ⋅ ( 1 + OCRnA )) это для вывода меандра на OCn, а для прерывания соответственно 2 в делителе не нужно
— Не говорите мне что делать и я не скажу куда Вам идти...
Реклама
metan
Вымогатель припоя
Сообщения: 593
Зарегистрирован: Ср янв 06, 2010 10:01:46

Re: Выбор коэффициента деления таймера 1 в ATmega48

Сообщение metan »

md5sum писал(а):Классическая ошибка...
md5sum, большое спасибо за быстрый и исчерпывающий ответ, дружище! :beer:
Вообще-то я подозревал нечто подобное, т.к. поправка в 1 мне где-то уже встречалась.
Очередной пример, как плохо бездумно брать чужие приёмы.
Вот статья с данной ошибкой, на которую я опирался:
[url]http://licrym.org/index.php/Простые_часы[/url]
Еще раз спасибо!
Тему можно закрывать.
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»