-
1. Data: 2009-01-04 16:31:11
Temat: Atmega8 i USART
Od: Piotr <p...@g...com>
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.
--
Piotr Piwko
http://www.embedded-engineering.pl/