|
Отстает секундомер, ATmega8 |
|
|
|
Oct 23 2010, 08:34
|

Местный
  
Группа: Свой
Сообщений: 377
Регистрация: 31-01-09
Пользователь №: 44 202

|
Отстает секундомер на 2 минуты за полчаса. И в протеусе и в железе примерно так же. Резонатор керамический 1 МГц, ATmega8L. Компилятор WinAvr. Что не так? Код #include <avr/io.h> #define F_CPU 1000000 #include <util/delay.h> #include <avr/interrupt.h> #include <string.h> #include <stdlib.h> #include <lcd_lib.h> #include <lcd_lib.c> #include <avr/signal.h>
unsigned int counter; // счетчик для секундомера: 488 прерываний = 1 секунда unsigned char sec,minut,hour; // сек.,мин.,часы для секундомера unsigned char c[5];
ISR(TIMER0_OVF_vect) { counter++; if (counter==488) { Lcd_Goto(0,0); Lcd_WriteData('t'); Lcd_WriteData('i'); Lcd_WriteData('m'); Lcd_WriteData('e'); Lcd_WriteData(' '); itoa(hour,c,10); if (hour<10) { Lcd_WriteData('0'); Lcd_WriteData(c[0]); } else { Lcd_WriteData(c[0]); Lcd_WriteData(c[1]); } Lcd_WriteData(':'); itoa(minut,c,10); if (minut<10) { Lcd_WriteData('0'); Lcd_WriteData(c[0]); } else { Lcd_WriteData(c[0]); Lcd_WriteData(c[1]); } Lcd_WriteData(':'); itoa(sec,c,10); if (sec<10) { Lcd_WriteData('0'); Lcd_WriteData(c[0]); } else { Lcd_WriteData(c[0]); Lcd_WriteData(c[1]); } Lcd_WriteData(' '); Lcd_WriteData(' '); Lcd_WriteData(' '); counter=0; sec++; if (sec==60) { sec=0; minut++; if (minut==60) { minut=0; hour++; } } } }
int main (void) { Lcd_Init(); DDRD = 0b00000001; sei(); // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 125,000 kHz TCCR0=0x02; TCNT0=0x00; TIMSK=0b00000001; // разреш. прерыв. timer0 while (1) { } return 0; }
Эскизы прикрепленных изображений
|
|
|
|
|
Oct 23 2010, 08:43
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(LexRoss @ Oct 23 2010, 12:34)  Отстает секундомер на 2 минуты за полчаса. ... Код .... ISR(TIMER0_OVF_vect) { .... Lcd_Goto(0,0); Lcd_WriteData('t'); Lcd_WriteData('i'); Lcd_WriteData('m'); .... Загляните в функции вывода на дисплей. Там увидите либо задержку либо опрос готовности. Как вы думаете а) зачем это сделано? б) сколько это занимает времени? (круглый) ЗЫ Прерывания (особенно железные) - это как выстрел. откидал регистры и забыл(С) Исключение составляет когда программа сделана по принципу переключения логики. основной код, прерываем - логически переключаемся на другую тему, возвращаемся к нормальному циклу...(надеюсь не сумбурно пояснил исключение  )
|
|
|
|
|
Oct 23 2010, 09:17
|

Местный
  
Группа: Свой
Сообщений: 377
Регистрация: 31-01-09
Пользователь №: 44 202

|
Вынес вывод на экран в main. Вроде лучше стало. Керамический резонатор, т.к. другого не нашел. Питание от батарейки, поэтому 1мгц. Цитата И когда вынесите процедуру вывода на экран наружу, установите часы минуты секунды как volatile. Зачем volatile ? Цитата Ну, естественно, вывод - по отдельному флагу, тоже volatile. Т.е. некая переменная, которая устанавливается, когда меняется счетчик секунд. В майне вы ея опять в ноль будуте устанавливать после вывода. Ничего не понял  Теперь даже спешат немного. За полчаса на 15сек.
|
|
|
|
|
Oct 23 2010, 14:41
|

Местный
  
Группа: Свой
Сообщений: 377
Регистрация: 31-01-09
Пользователь №: 44 202

|
Цитата(ILYAUL @ Oct 23 2010, 17:56)  Почему бы просто не задействоать асинхронный таймер с 32,768 Кгц если уж стоит задача СЕКУНДОМЕР На самом деле будет велокомпьютер. 32,768 в данном случае мало. Сейчас положу в холодильник, посмотрю как будет плавать от температуры, если не сильно, то программно подкорректирую.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|