Witam, tworzę pewien projekt i spotykam się z tak zwaną rozbieżnością między teorią a praktyką.
Używam 2 timerów, z których jeden generuje sekundę a drugi chcę aby generował coś najbliższe 24kHz
Timer generujący sekunde to 16bitowy timer1 z preskalerem 1024, kwarc 16MHz, z wartością początkową wyliczoną przeze mnie 0xc2f6, którego sprawdzałem z zegarkiem i po 5 minutach sekundy sie nie rozjeżdżaja wiec mniemam, że jest możliwie najbliższy sekundzie jak tylko sie da to osiągnąć z takim kwarcem.
Podsumowując kod, chcę aby na lcd wyświetlał mi ile cykli na sekundę faktycznie wywołuje timer0. Wyniki jednak odbiegają od teorii o kilkanaście procent. Czy robię coś źle w rozumowaniu czy tak poprostu jest, że w C nie ma się kontroli nad ilością operacji, nawet jeżeli nadaje timerom wartość początkową w pierwszej instrukcji obsługi przepełnienia.?
Używam 2 timerów, z których jeden generuje sekundę a drugi chcę aby generował coś najbliższe 24kHz
Timer generujący sekunde to 16bitowy timer1 z preskalerem 1024, kwarc 16MHz, z wartością początkową wyliczoną przeze mnie 0xc2f6, którego sprawdzałem z zegarkiem i po 5 minutach sekundy sie nie rozjeżdżaja wiec mniemam, że jest możliwie najbliższy sekundzie jak tylko sie da to osiągnąć z takim kwarcem.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include "lcd.c"
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#define cbi(port, bit) (port) &= ~(1 << (bit))
#define TCN_T0 0xb5
unsigned long T=0;
SIGNAL(SIG_OVERFLOW0) // przepelnienie timera0
{
TCNT0 = TCN_T0; //ustawienie wartosci poczatkowej
T++;
jakieś tam kilka poleceń
}
int main( void )
{
DDRC=255;
lcd_init(LCD_DISP_ON); //inicjacja wyswietlacza
sei();
//timer1 do zliczania km/h 16 bitowy :
TCNT1 = 0xc2f6; // wartosc poczatkowa, T=1s c2f6
TCCR1A = 0x00; // T/C1 w trybie czasomierza
TCCR1B = _BV(CS10)|_BV(CS12); // preskaler ck/1024
//timer0 do zliczania obrotow silnika i synchronizacji z kolem zebatym 8 bitowy
TCNT0 = TCN_T0;
TCCR0 = _BV(CS01) ; // preskaler ck/8
TIMSK = _BV(TOIE0); //wlacza obsluge przerwan T/C0
while(1) //petla glowna
{
if ((_SFR_BYTE(TIFR) & _BV(TOV1)) == _BV(TOV1)) {//co 1 s
TCNT1 = 0xc2f6;
TIFR = _BV(TOV1);
lcd_puts(ltoa(T,buffer,10));
T=0;
}}
Podsumowując kod, chcę aby na lcd wyświetlał mi ile cykli na sekundę faktycznie wywołuje timer0. Wyniki jednak odbiegają od teorii o kilkanaście procent. Czy robię coś źle w rozumowaniu czy tak poprostu jest, że w C nie ma się kontroli nad ilością operacji, nawet jeżeli nadaje timerom wartość początkową w pierwszej instrukcji obsługi przepełnienia.?