Witam!
Postanowiłem przetestować tryb asynchroniczny timera0 z podłączonym kwarcem 32768 Hz na płytce ZL9AVR i uC ZL7AVR.
Napisałem programik
Przy tych ustawieniach Timer0 powinien generować przerwanie co 1 sekundę i wyświetlić na LCD aktualną wartość zmiennej time.
Niestety licznik opóźnia się o ok 2min/godz.
Początkowo program był bardziej rozbudowany i myślałem, że to kwestia zbyt dużego obciążenia atmegi obliczeniami matematycznymi, które były wykonywane pomiędzy obsługą przerwań, ale 16M cykli pomiędzy nimi powinno starczyć na kilkukrotne podzielenie long przez int i wyświetlenie obliczonych wartości na LCD.
Myślałem również, że przyczyną może być "gubienie" wywołania przerwania i brak inkrementacji zmiennej time, ale zmienna jest powiększana i wyświetlana prawidłowo, co sprawdziłem licząc kolejne zmiany przez ok 20 minut.
W innych postach przeczytałem, że kwarc 32768 może mieć odchylenia od zadeklarowanej wartości, ale chyba nie aż takie.
Czy źle zrozumiałem notę Atmegi (słaby angielski) i czegoś zapomniałem ustawić, czy też wina może leżeć po stronie hardware.
Pozdrawiam
Postanowiłem przetestować tryb asynchroniczny timera0 z podłączonym kwarcem 32768 Hz na płytce ZL9AVR i uC ZL7AVR.
Napisałem programik
#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include "HD44780.h"
volatile int time=0;
int main (void){
TCCR0|=(1<<WGM01)|(1<<CS02)|(1<<CS01)|(1<<CS00); //--- Ustawienie Timer0 w tryb CTC i preskaler 1/1024
TIMSK|=(1<<OCIE0); //--- Ustawienie przerwania Timer0 przy porównaniu
OCR0=32; //--- Ustawienie licznika porównania Timer0
ASSR|=(1<<AS0); //--- Ustawienie trybu asynchronicznego Timer0
sei(); //--- Włączenie obsługi przerwań
LCD_Init(); //--- Inicjalizacja i kasowanie LCD
LCD_Clear();
while(1){}
return 0;
}
ISR(TIMER0_COMP_vect){
time++; //--- Zwiększenie licznika
LCD_GoTo(0,0); //--- Ustawienie LCD
//--- Wyswietlenie wartości time na LCD
char bufor[6];
LCD_WriteText(itoa(time,bufor,10));
}Przy tych ustawieniach Timer0 powinien generować przerwanie co 1 sekundę i wyświetlić na LCD aktualną wartość zmiennej time.
Niestety licznik opóźnia się o ok 2min/godz.
Początkowo program był bardziej rozbudowany i myślałem, że to kwestia zbyt dużego obciążenia atmegi obliczeniami matematycznymi, które były wykonywane pomiędzy obsługą przerwań, ale 16M cykli pomiędzy nimi powinno starczyć na kilkukrotne podzielenie long przez int i wyświetlenie obliczonych wartości na LCD.
Myślałem również, że przyczyną może być "gubienie" wywołania przerwania i brak inkrementacji zmiennej time, ale zmienna jest powiększana i wyświetlana prawidłowo, co sprawdziłem licząc kolejne zmiany przez ok 20 minut.
W innych postach przeczytałem, że kwarc 32768 może mieć odchylenia od zadeklarowanej wartości, ale chyba nie aż takie.
Czy źle zrozumiałem notę Atmegi (słaby angielski) i czegoś zapomniałem ustawić, czy też wina może leżeć po stronie hardware.
Pozdrawiam