Witam.
Przymierzam się do budowy regulatora modelarskiego i mam problem ze zliczaniem długości trwania impulsu.
Impuls trwa zazwyczaj od 1ms do 2ms w stanie wysokim (wyzwalany przerwaniem INT0)
FCPU = 1 MHz (8MHz z preskalerem 8 (bit 7 ustawiony))
Licząc, że jeden impuls trwa dokładnie 1 us i przy timerze zliczającym do 10 (startuje od 246 - Timer0) to po przekręceniu się timera uzyskujemy czas 10us. Przy długości impulsów w podanym zakresie timer powinien się przekręcić od 100 do 200 razy. Niestety program zlicza mi od 12 do 24 przekręceń tylko.
Gdzie robię błąd ???
Pozdrawiam. Smok.
Przymierzam się do budowy regulatora modelarskiego i mam problem ze zliczaniem długości trwania impulsu.
Impuls trwa zazwyczaj od 1ms do 2ms w stanie wysokim (wyzwalany przerwaniem INT0)
FCPU = 1 MHz (8MHz z preskalerem 8 (bit 7 ustawiony))
Licząc, że jeden impuls trwa dokładnie 1 us i przy timerze zliczającym do 10 (startuje od 246 - Timer0) to po przekręceniu się timera uzyskujemy czas 10us. Przy długości impulsów w podanym zakresie timer powinien się przekręcić od 100 do 200 razy. Niestety program zlicza mi od 12 do 24 przekręceń tylko.
Gdzie robię błąd ???
Pozdrawiam. Smok.
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define TSC 246 // stała czasowa timera
volatile int x;
volatile int czas;
// funkcja opóźniająca
void czekaj(int i){
while(i>0){
_delay_ms(10);
i--;
}
}
//funkcja wyświetlająca cyfrę na wyświetlaczu
wypisz (int a){
switch (a){
case 0:
LCD_WriteText("0");break;
case 1:
LCD_WriteText("1");break;
case 2:
LCD_WriteText("2");break;
case 3:
LCD_WriteText("3");break;
case 4:
LCD_WriteText("4");break;
case 5:
LCD_WriteText("5");break;
case 6:
LCD_WriteText("6");break;
case 7:
LCD_WriteText("7");break;
case 8:
LCD_WriteText("8");break;
case 9:
LCD_WriteText("9");break;
}
}
// funkcja wyświetlająca integera (0-9999) na wyświetlaczu
drukuj(int a){
int t0,t1,t2,t3;
t0=a/1000;
wypisz(t0);
t1=(a/100)-(t0*10);
wypisz(t1);
t2=(a%100)/10;
wypisz(t2);
t3=a%10;
wypisz(t3);
}
// obsługa przewania timera0
SIGNAL (SIG_OVERFLOW0){
TCNT0=TSC; // zerowanie timera
czas++;
}
// obsługa przerwania zewn. INT0
SIGNAL (SIG_INTERRUPT0){
SREG=1<<7; // zezwolenie na przerwania
czas=0; // zerowanie licznika czasu
while(bit_is_set(PIND,2)){}; // czekaj aż sygnał INT0 ustanie
x=czas;
}
int main(void)
{
TIMSK=1<<TOIE0; // zezwolenie na przerwania z timera 0
TCCR0B=1; // preskaler
TCNT0=TSC; // zerowanie timer1
LCD_Initalize();
LCD_Clear();
czekaj(1);
LCD_WriteText(" Smok 2010");
czekaj(1);
LCD_GoTo(0,1);
czekaj(1);
DDRD=0x00; // PORTD jako wejście
PORTD=0x00; // Bez podciągnięcia do plusa
GIMSK=(1<<6); // włączenie przerwania od INT0
MCUCR=(1<<0 | 1<<1); // zbocze narastające dla INT0
sei(); // włączenie przerwań
while(1){
cli(); // wyłączenie przerwań na czas obsługi wyświetlacza
LCD_GoTo(0,1);
drukuj(x); // wypisanie ilości zliczonego czasu (impulsów)
sei(); // włączenie przerwań
czekaj(1);
}
return 0;
}