TOPへ戻る

20070719 WinAVRのUSART(SIO)シリアルを試してみる3

ATmega168で、受信割り込みがうまく動かなかった問題が、やっと(?)解決しました。
結論は受信割り込みを許可していなかったからでした。
色々ぐぐって調べていたのですが、大体以下のような初期化と関数でできていました。
UCSR0B = (1<<RXEN0)|(1<<TXEN0); // 送受信許可 ISR(USART_RX_vect){ if(bit_is_clear(UCSR0A,FE0)){ // フレーミングエラーが無い時 usart_recvData = UDR0; // 受信データをグローバル変数に取得 } } 今までは受信割り込みが来ませんでいた。
なんで、受信ができるのかが不思議です。

ATmega168では、どうしてみたかといいますと
UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0); // 送受信許可 このように、RXCIE0 を追加しました。
ソースコード
#include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #define FOSC 20000000 // 20MHz #define BAUD 38400 #define MYUBRR FOSC/16/BAUD-1 void nop(int count){ int i; for(i = 0; i < count; i++){ _delay_ms(100); } } /* PORT設定 */ void port_init(void){ DDRB = 0x01; PORTB = 0x00; } /* sio設定 */ void sio_init(unsigned int ubrr){ UBRR0H = (unsigned char)(ubrr>>8); // ボーレート上位8bit UBRR0L = (unsigned char)ubrr; // ボーレート下位8bit UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0); // 送受信許可 UCSR0C = (1<<USBS0)|(3<<UCSZ00); } int main(void){ char a; port_init(); // PORT設定 sio_init(MYUBRR); // SIO設定 sei(); // 全割り込み許可 for(;;){ PORTB = ~PORTB; // LED点滅 nop(10); } } ISR(USART_RX_vect){ if(bit_is_clear(UCSR0A,FE0)){ // フレーミングエラーが無い時 UDR0 = UDR0; // 受信データをエコーバック } } このコードで、ハイパーターミナルで文字を入力すると、エコーバックされることは確認しました。

2007/07/17 初版

TOPへ戻る