Witam,
Napisałem program do odpytywania stanu klawiszy na Atmega16, kwarc-16MHz. Według wyliczeń przerwanie powinno sie pojawiać co 2,5ms, jednak tak nie jest, jest o wiele wolniej (ponad 1s). Analizowałem program i sam juz nie wiem co może być źle. Pomóżcie
Preskaler clk/1024=16000000/1024=15625
1/15624=0,064ms
40*0,064ms=2,5ms
Pozdrawiam
Fuse bity:
Napisałem program do odpytywania stanu klawiszy na Atmega16, kwarc-16MHz. Według wyliczeń przerwanie powinno sie pojawiać co 2,5ms, jednak tak nie jest, jest o wiele wolniej (ponad 1s). Analizowałem program i sam juz nie wiem co może być źle. Pomóżcie
Preskaler clk/1024=16000000/1024=15625
1/15624=0,064ms
40*0,064ms=2,5ms
#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
//switche
#define tau0 256-40;//stala czasowa timera0
volatile unsigned char key=0x00; //informuje o wcisnieci klawisza
volatile unsigned char key_pressed=0x00; //przechowuje wartosc klawisza
enum {WAITING, PUSHING, KEEPING, RELEASEING}; //definicja wartosci wyliczeniowych
volatile unsigned char stan;
/********/
//...
//obsluga lcd
//...
/********/
/****************************************************************************/
// BADANIE SWITCHY
/****************************************************************************/
SIGNAL (SIG_OVERFLOW0) //obsluga przerwania
{
static unsigned char state = WAITING; //zmienna dla stanow klawiszy
unsigned char klawisz=0x00; //tymczasowa wartosc klawisza w danym cyklu przerwania
static unsigned char prev_key=0x00; //przechowuje wartosc poprzedniego klawisza
TCNT0=tau0;
if(!(PIND &1<<PD4))
{
klawisz='e';
}
if(!(PIND &1<<PD6))
{
klawisz='p';
}
if(!(PIND &1<<PD3))
{
klawisz='c';
}
if(!(PIND &1<<PD2))
{
klawisz='l';
}
switch(state) //przelacz stan klawiszy w zaleznoci od wartosci (eliminacja drgan klawiszy)
{
case WAITING:
{
if(klawisz) // jesli krorykolwiek klawisz wcisniety
{
prev_key = klawisz; //zapisz do wartosci poprzedniej (potrzebna dla zprawdzenia klawisza w kolejnym cyklu przerwania)
state = PUSHING; //zmien stan
}
key_pressed = 0x00;
break;
}
case PUSHING:
{
if(prev_key==klawisz) //jesli klawisz = klawiszowi poprzednio zapisanemu
{
key = prev_key; //zapisz wartosc klawisza do zmiennej globalnej 'key'
state = KEEPING; //zmieni stan
}
else
{
state = WAITING; //jesli nierowny to wroc do stanu poprzedniego
prev_key=0x00; //wyczysc wartosc poprzednia klawisza
key_pressed=0x00;
}
break;
}
case KEEPING:
{
if(prev_key==klawisz) {}//key= prev_key; //klawisz caly czas wcisniety, trzymaj wartosc klawisza
else state = RELEASEING; //jesli sie znienil to zmien stan
key_pressed=klawisz;
break;
}
case RELEASEING:
{
if(prev_key!=klawisz) //jesli zmiana klawisza
{
key_pressed = 0;//klawisz; //sygnalizuj gotowosc klawisza do obslugi
state = WAITING; // wroc do poczatku obslugi klawiszy
prev_key=0x00; //wyczysc wartosc poprzednia klawisza
}
else state = KEEPING; //jesli nie ma zmiany wartosci klawisza to wroc do stanu poprzedniego
break;
}
default:
{
state=WAITING;
break;
}
}
}
/****************************************************************************/
// MAIN
/****************************************************************************/
int main(void)
{
unsigned char temp[10];
int liczba=0;
//TIMER0
TIMSK=1<<TOIE0; //zezwolenie na przerwanie od T0
TCCR0=5; //presklaer xtal/1024
TCNT0=tau0; //wpisz stala
DDRA=0xFF;
//switch
DDRD&=~_BV(PD6);
DDRD&=~_BV(PD4);
DDRD&=~_BV(PD3);
DDRD&=~_BV(PD2);
lcd_init();
sei();
while(1)
{
write_command(0xA8);
itoa(liczba,temp,10);
write_text(temp);
switch(key)
{
case'p':
liczba++;
key=0x00;
break;
case'l':
liczba--;
key=0x00;
break;
}
}//end while(1)
return 0;
}
Pozdrawiam
Fuse bity: