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