avr lebegopontos muveletek -frekimero-

Moczik Gabor pm at progzmaster.hu
Mon Sep 18 12:10:42 CEST 2006


Pal Lukacs wrote:
 > * ha cnt1_threshold = 1000 akkor az idoalap 0.001S, ha cnt1_threshold = 1 
 > akkor idoalap 1S

Ez nem forditva van?

 >          TCCR2 |= 0x00;    //0x04;//8 oszto
 >           TCNT2 = 223;    //ovf.ig 33.
 >           //cnt1=0;                 //igy sosem teljesul az 1S keres!

Pedig kell a cnt1 nullazasa idoalap valtaskor.

Megneztem jobban a kodot, bar nekem nem valami atlathato ez a strukturalas, 
leirom mire gondolok, aztan majd te tudod hogy ugy van-e vagy nem.

Az idoalapot szinkronban kellene valtani, azaz nem csak ugy valamikor, hanem 
amikor az elozo lejart, akkor. Ezt megteheti a megszakitas is, akkor tuti 
nem lesz csuszas benne.

A tmr1 szamolja az impulzusokat, a tmr2 pedig az idoalap, ugye?
Amikor az idoalap lejar, akkor a megszakitasban kellene kiolvasni a tmr1 
erteket, a flag-et csak arra kell hasznalni, hogy jelezze a main()-nek, hogy 
frissitve van a kijelzendo adat. A meres teljes egeszeben megszakitasbol 
mukodjon, mert nagyobb frekinel biztosan nem lesz pontos.

Tovabba a sok megszakitas tiltas/engedelyezes se kell szerintem, meres alatt 
plane nem jo barmi miatt tiltani, mert hibas lehet az eredmeny.


igy gondolom (nem tudok avr specifikus kodot irni, csak elv):

volatile unsigned long  freq;
volatile unsigned short cnt,threshold;
volatile unsigned char  freq_updated_flag, freq_ovf;
volatile unsigned char  ovf_flag;

// szamlalo
void tmr1_isr()
{
     ovf_flag=1;
}

// idoalap. tmr2 tulcsordul 1ms-onkent.
void tmr2_isr()
{
     cnt++;
     if (cnt==threshold) {
         cnt=0;
         if (ovf_flag && threshold==1000) {
             // proba 1ms idoalappal, a foprogramnak egyelore nem jelezzuk
             // hogy frissiteni kell, es a tulcsordulast sem
             threshold=1;
         } else {
             // azert kell masik overflow flag a foprogram reszere,
             // hogy a megszakitasi rendszer hibatlanul mukodjon akkor is
             // ha a foprogram nem kezeli le idoben a kijelzest
             if (ovf_flag) freq_ovf=1; else freq=tmr1;
             freq_updated_flag=1;
         }
         tmr1=0;
         ovf_flag=0;
     }
}

void main()
{
     // 1s
     threshold=1000;
     setup_timers();
     start_timers();
     for(;;) {
         if (freq_ovf) {
             printf("Overflow!");
             freq_ovf=0;
         if (threshold==1) {
             // 1ms
             printf("Freq: %d kHz",freq);
         } else {
             // threshold==1000 -> 1s
             printf("Freq: %d Hz ",freq);
         }
         freq_updated_flag=0;
         while(!freq_updated_flag);
     }
}


-- 
((( Móczik Gábor  )))--((( pm -> @ -> progzmaster -> . -> hu  )))
((( Skype: moczik )))--((( Website: http://www.progzmaster.hu )))



More information about the Elektro mailing list