Witam,
Nie wiem dlaczego, ale mam dość dziwną i niejasną dla mnie sytuację. Próbuję odebrać dane przez USART z wykorzystaniem przerwania. Robiłem już to setki razy zarówno dla AVR, PIC, Freescale i nigdy nie miałem z tym najmniejszego kłopotu.
Używam kompilatora gcc 4.3.2 (WinAVR-20081205) z następującymi parametrami kompilacji: avr-gcc -mmcu=atmega8 -Wall -gdwarf-2 -DF_CPU=4000000 -Os
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
-Wp,-M,-MP,-MT,main.o,-MF,dep/main.o.d -c ../main.c -o main.o
uC pracuje z wykorzystaniem wewnętrznego oscylatora o częstotliwości 4MHz.
Wysyłanie oraz odbieranie znaków w aktywnej pętli działa bez najmniejszego problemu. Kłopoty się zaczynają, gdy próbuję to zrobić w obsłudze przerwania. Wygląda na to, iż ani razu przerwanie nie jest wywoływane. Dodam, iż jeżeli korzystam z aktywnego czekania podczas gdy włączone są przerwania, dane również nie są odbierane. Oto mój kod:
//-----------------------------------------------------
#include <avr\io.h>
#include <avr\interrupt.h>
#include <avr\signal.h>
volatile unsigned char data_rx = 1;
/////////////////////////////////////////////////////// // Inicjalizacja interfejsu /////////////////////////////////////////////////////// void usart_init(int baud_rate) { // Ustawienie bauda UBRRH = (baud_rate >> 8); UBRRL = baud_rate;
// Ustawienia USART UCSRB = (1 << RXEN) // Wlaczenie odczytywania | (1 << TXEN) // Wlaczenie wysylania | (1 << RXCIE); // Wlacz przerwanie odczytywania
// Ustawienia transmisji UCSRC = (1<<URSEL) // Odycztywanie rejestru UCSRC | (1<<USBS) // 2 bity stopu | (3<<UCSZ0); // 8 bitowy znak }
/////////////////////////////////////////////////////// // Wysłanie danych /////////////////////////////////////////////////////// void usart_send_char(unsigned char data) { // Poczekaj az zwolni sie bufor transmisji while ( !( UCSRA & (1<<UDRE)) ) ; // Umiesc dane w buforze UDR = data; }
/////////////////////////////////////////////////////// // Odebranie danych /////////////////////////////////////////////////////// char usart_receive_char() { // Czekaj az dane beda gotowe while ( !(UCSRA & (1<<RXC)) ) ; // Pobierz dane return UDR; }
/////////////////////////////////////////////////////// // Obsługa przerwania odbioru /////////////////////////////////////////////////////// ISR(USART_RXC_vect) { PORTB &= ~(1 << PB0); // Zgas diode data_rx = UDR; // Pobierz dane }
/////////////////////////////////////////////////////// // main() /////////////////////////////////////////////////////// int main() { unsigned char tmp; // Led uC DDRB |= (1 << PB0); PORTB |= (1 << PB0);
// Inicjalizacja interfejsu USART usart_init(25); // Baud rate dla 4Mhz i 9600 bps
// Wlacz wszystkie przerwania sei();
while(1) ;
return 0; }
//-----------------------------------------------------
Będę bardzo wdzięczny za wszelkie sugestie.