avr lebegopontos muveletek -frekimero-

Pal Lukacs ekegep at yahoo.com
Mon Sep 18 11:26:51 CEST 2006



Moczik Gabor <pm at progzmaster.hu> wrote:
 
 ............
 
 Helo!
 
 Modositasokat elvegeztem,meg mindent atirtam amit ugy lattam hogy szukseges,de csak nem mukodik renesen.
 
 Ha jelet 10K fole emelem,akkor atallitja aaz idoalapot 0.001 S re,egyszer kijelzi az erteket
  aztan 'megfagy',egy kis ido utan kiirja hogy Freq > 65,535 mHz,vagyis tulcsordul a timer1.
  Hiaba allitom vissza a jelet 10 KHz ala,ugysem valtja vissza az idoalapot csak ha resetelem:(
  A timer1 tulcsordulasnak nem lenne szabad megtortennie,csak ~65 MHz folott,ugyanis az alatt 0.001S ido alatt meg tudja merni
  es a main -loopban biztositva van minden Timer2 ovf. utani TCNT1 torles.
  
 
 Kodot beszurom:
 
 
 /* freq-meter by gtk */
 
 #include <inttypes.h>
 #include <util/delay.h>
 #include <avr/io.h>
 #include <avr/interrupt.h>
 #include <stdlib.h>
 #include <avr/pgmspace.h>
 #include "simple_driver.h"
 
 
 volatile unsigned int cnt1, cnt2;
 volatile unsigned char flag1, flag2;
 unsigned int cnt1_threshold = 1, cnt2_threshold = 0;
 volatile unsigned int imp = 0x0000, tme = 0x0000, t1_overflow_flag = 0x0000;
 uint8_t mask = 0x00, i = 0;
 uint8_t buf[17];
 
 void timer2_isr ();
 
 void
 delay_ms (unsigned int d)
 {
   while (--d)
     {
       _delay_ms (1);
     }
 }
 
 /*
 * timer1 SIG_OVERFLOW1 : impulzusok szamat meri; 65535 -nal overflow
 * ha tulcsordul.
 */
 SIGNAL (SIG_OVERFLOW1)
 {
   cli ();            //int ki        
   TCCR1B &= 0xF8;        //a timer 1 ki
   t1_overflow_flag = 0x01;    //jelezzunk hogy freki > 65,535Mhz
   TCNT1 = 0x00;
   TCCR1B |= 0x07;        //timer 1 indul
   mask = 0x1;            //set mask; ugrik a main-loop-hoz , SEI is ott van
   //sei ();                     //globalis megszakitas engedelyezes
 }
 
 /* Timer 2 SIG_OVERFLOW2: Ido meres; 1S vagy 0.001S 
 * nel overflow.
 */
 
 SIGNAL (SIG_OVERFLOW2)
 {
   cli ();            //megszakitas kikapcs.
   //timer2 kikapcs
   TCCR2 = 0x00;
   imp = TCNT1;            //impulzusok szama
   timer2_isr ();
   mask = 0x01;            //set mask; --> timer2 beallitasa a main-loop-ban (for(;;))
 }
 
 
 void
 timers_init (void)
 {
   TIMSK |= (1 << TOIE2);    //timer2 overflow enabled
 /* 
  * egy-be allitott bitek TCCR1B reg.ben: 
  * CS10,CS11,CS12: kulso orajel forras,felfuto elre lep. 
  * --> 00000111  --> 
 */
   TCCR1B |= 0x07;
   TIMSK |= (1 << TOIE1);    //timer1 overflow enabled
 
   ASSR |= (1 << AS2);        //aszinkron uzemmod bekapcs; clock source from osc. connected to TOSC1 TOSC2.
 }
 
 
 void
 timer2_isr ()
 {
   cnt1++;
   if (cnt1 == cnt1_threshold)
     {
       cnt1 = 0;
       flag1 = 1;
     }
 }
 
 
 int
 main ()
 {
   lcd_init ();
   /*set: disply ,no curs, no c. blink */
   lcd_control (1, 0, 0);
   mask = 0x01;
   /* PORTD / T1 bemenet */
   //DDRD &= ~(1 << PD5);
   DDRD = 0x00;
   PORTD = 0xFF;
   timers_init ();        // init
 
   for (;;)            //main-loop
     {
 /*
 * ha cnt1_threshold = 1000 akkor az idoalap 0.001S, ha cnt1_threshold = 1 akkor idoalap 1S
 *  
 */
       if (flag1)
     {
       flag1 = 0;
 
       //idoalap 1S; meres 999 Hz ig
       if (imp < 1000 && cnt1_threshold == 1)
         {
           sprintf (buf, "Fq: %d Hz", imp);
         }
       //idoalap 1S;  1-10KHz 
       if (imp >= 1000 && cnt1_threshold == 1)
         {
           sprintf (buf, "Fq: %d.%03d Khz", imp / 1000, imp % 1000);
         }
       //idoalap 0.001S ;  11-999KHz 
       if (imp < 1000 && cnt1_threshold == 1000)
         {
           sprintf (buf, "Fq: %d.%03d KHz", imp / 1000, imp % 1000);
         }            
       //idoalap 0.001S;  ~65MHz 
       if (imp >= 1000 && cnt1_threshold == 1000)
         {
           sprintf (buf, "Fq: %d.%03d MHz", imp / 1000000, imp % 1000000);
         }
       lcd_cls ();
       lcd_putstr (buf);
     }
 /*
 * timer1 impulzus szamlalo; ha elmozdult ==>jel erkezett! meresi idot 1S -el indul    
 */
       if (TCNT1 & mask)
     //valoszinu hogy ez nem teljesul 0.001s -nel mert: 
     //ha 10K folott merek (ilyrnkor atallitja az idoalapot 0.001s -ra) rovid ido alatt tulcsordul
     //a timer1, aminek nullazasa ebben a blokkban van!Igy sosem csordulhatna tul 65535Mhz alatt!
     {
       mask = 0x00;
 
       /* meresi idot atallitjuk 0.001S-re,(es jelzest lcd frissiteshez 1S-re) ha az impulzusok szama/sec nagyobb mint 10.000 (10 KHz) */
 
       if (cnt1_threshold == 1 && imp > 10000)
         {
           cnt1_threshold = 1000;    //1S idonkenti jelzes keres freki kijelzeshez,idoalap 0.001S
           //0.001S (1ms)idoalap beallitas
           // elooszto 64
           TCCR2 &= 0xF8;
           TCCR2 |= 0x00;    //0x04;//8 oszto 
           TCNT2 = 223;    //ovf.ig 33.
           //cnt1=0;                 //igy sosem teljesul az 1S keres! 
         }
       else if (cnt1_threshold == 1 && imp <= 10000)
         {
           cnt1_threshold = 1;    //1S idonkenti jelzes keres freki kijelzeshez,idoalap 1S
           //1S idoalap beallitas
           // elooszto 128
           TCCR2 &= 0xF8;
           TCCR2 |= 0x05;
           //TCNT2 kezdeti erteke ; 
           TCNT2 = 0;
           cnt1 = 0;        //nullazzuk,hogy ha cnt1_threshold = 1000 rol visszavalt
           //1-re akkor is idoben teljesuljon az 1S -idonkenti jelzes.
         }
 
       TCNT1 = 0x0;        //Timer1 = 0
       sei ();        //global interrupt enabled , meres indul         
 
       if (t1_overflow_flag)
         {
           lcd_cls ();
           lcd_putstr ("Fq > 65,535 mHz");
           t1_overflow_flag = 0x0000;
         }
     }//end TCNT1 mask
     }//end for
 }//end main
 
 
 

 		
---------------------------------
 All-new Yahoo! Mail - Fire up a more powerful email and get things done faster.


More information about the Elektro mailing list