Problem pojawia się przy obsłudze przycisków w przerwaniu int0. Dwa microswitch'e podłączone mam tak: Jedna strona razem do PD2, czyli wejścia INT0 i z drugiej strony do PB1 i PB0 (każdego oddzielnie).
Robię tak, gdyż chcę usypiać procesor w docelowym układzie i ma on być budzony właśnie przerwaniem INT0 tylko na czas wysłania kodu rc5.
Chcę wykorzystać sztuczkę, której użył mirekk36 w swoim uniwersalnym pilocie. Mianowicie w obsłudze przerwania zmieniam PD2 na wyjście i ustawiam stan wysoki, następnie microswitch'e jako wejścia ze stanem niskim i sprawdzam na którym występuje stan wysoki (podciągnięty z PD2). Robię to, aby rozpoznać który przycisk został wciśnięty.
Tak wygląda kod, który działa w miarę dobrze (bez sprawdzania przycisków).
Kod: Zaznacz cały
int main (void)
{
toggle=0;
DDRD &= ~(1<<SW_INT0); // PD2 wejscie button do INT0
PORTD |= (1<<SW_INT0); // podciagniecie buttona do 1
DDRB |= ( (1<<SW1) | (1<<SW2) | (1<<IR_LED) ); // guziki i dioda jako wyjscie
PORTB &= ~( (1<<SW1) | (1<<SW2) ); // stan niski na guzikach
PORTB |= 1<<IR_LED; // dioda nie swieci
MCUCR |= (1<<ISC01); // INT0 falling
GIMSK |= 1<<INT0; // INT0
sei(); // wlaczenie przerwan
while(1);
return 0;
}
SIGNAL(SIG_INTERRUPT0)
{
cli();
_delay_ms(50);
rc5_send(toggle,0,13);
_delay_ms(200);
sei();
}
Kod: Zaznacz cały
int main (void)
{
toggle=0;
DDRD &= ~(1<<SW_INT0); // PD2 wejscie button do INT0
PORTD |= (1<<SW_INT0); // podciagniecie buttona do 1
DDRB |= ( (1<<SW1) | (1<<SW2) | (1<<IR_LED) ); // guziki i dioda jako wyjscie
PORTB &= ~( (1<<SW1) | (1<<SW2) ); // stan niski na guzikach
PORTB |= 1<<IR_LED; // dioda nie swieci
//MCUCR &= ~(1<<ISC01 | 1<<ISC00); // INT0 low level
MCUCR |= (1<<ISC01); // INT0 falling
GIMSK |= 1<<INT0; // INT0
sei(); // wlaczenie przerwan
while(1);
return 0;
}
SIGNAL(SIG_INTERRUPT0)
{
cli();
_delay_ms(100);
DDRB &= ~( (1<<SW1) | (1<<SW2) ); // guziki jako wejscie
PORTB &= ~( (1<<SW1) | (1<<SW2) ); // stan niski na guziki
DDRD |= 1<<SW_INT0; // pd2 jako wyjscie
PORTD |= 1<<SW_INT0; // stan wysoki
PORTB |= 1<<IR_LED; // dioda nie swieci
if( PINB & (1<<SW1) )
{
_delay_ms(5);
if( PINB & (1<<SW1) )
rc5_send(toggle,0,13);
}
if( PINB & (1<<SW2) )
{
_delay_ms(5);
if( PINB & (1<<SW2) )
rc5_send(toggle,0,12);
}
_delay_ms(200);
DDRD &= ~(1<<SW_INT0); // PD2 wejscie button do INT0
PORTD |= (1<<SW_INT0); // podciagniecie buttona do 1
DDRB |= ( (1<<SW1) | (1<<SW2) | (1<<IR_LED) ); // guziki i dioda jako wyjscie
PORTB &= ~( (1<<SW1) | (1<<SW2) ); // stan niski na guzikach
PORTB |= 1<<IR_LED; // dioda nie swieci
sei();
}Attiny2313 działa na wewnętrznym rezonatorze 8MHz. Generowanie nośnej 36kHz na timer0, odliczanie czasu potrzebnego do kodu rc5 na timer1.
[ Dodano: 2009-06-07, 12:40 ]
Już sobie poradziłem
Dodałem obsługę bitu toggle, która również działa wyświenicie ;P
Procesor w trakcie snu pobiera mniej niż 1uA, więc prąd jest praktycznie pomijalny.