mega168でUART受信割り込みできた。

回路はmega8の時と同じ。

さっきできなかった理由は割り込みベクタ名が間違ってた為だった。

コンパイル結果をよく見ると SIGNAL(SIG_UART_RECV)の所でwarningが出ていたので、avr-gccのフォルダの中のコードをよく読んだらSIG_USART_RECVになっていた。

コンパイラのバージョンというわけではなく、ATmega8のコードではSIG_UART_RECVで通るのでATmega168以降はSIG_USART_RECVに変わったみたいだ。

あとavr/signal.hは廃止されてavr/interrupt.hに統合される模様。

■関連記事

s.h.log: AVR – MEGA8のUART送受信

s.h.log: AVR – ATMega8でUSARTエコー

■コード

SourceCode, hex, Makefile(avr-gcc 3.4.6)



UARTで受信した文字を割り込みで反応する。それをmainの中で送り返す。

受信した瞬間だけLEDが点灯し、送信し返したら消灯する。

#include<avr/io.h>
#include<avr/interrupt.h>
#defineTRUE1
#defineFALSE0
#defineNULL'¥0'
#definesbi(BYTE,BIT)BYTE|=_BV(BIT)//BYTEの指定BITに1をセット
#definecbi(BYTE,BIT)BYTE&=~_BV(BIT)//BYTEの指定BITをクリア
/**動作設定**/
#defineFOSC8000000//8MHz
/**UART設定**/
#defineBAUD9600//9600bps
#defineMYUBRRFOSC/16/BAUD-1//UART分周率
//#defineUCSR0A_U2X01//倍速フラグ等速ならコメントアウト
#ifdefUCSR0A_U2X0//倍速が定義されているならば
#defineMYUBRRFOSC/16/(BAUD/2)-1//UART分周率(倍速)
#endif
volatilecharusart_recvData;//USARTで受信したデータ
#defineLED_SET()sbi(PORTB,PB0)//基盤上の動作確認LED
#defineLED_CLR()cbi(PORTB,PB0)
/*PORT設定*/
voidport_init(void){
sbi(DDRB,PB0);
}
/*USART設定*/
voidusart_init(unsignedintubrr){
UBRR0H=(unsignedchar)(ubrr>>8);//ボーレート上位8bit
UBRR0L=(unsignedchar)ubrr;//ボーレート下位8bit
UCSR0A=(0<<U2X0);//等速
UCSR0B=(1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);//送受信許可、受信完了割り込み許可
UCSR0C=(0<<UMSEL00)|(3<<UCSZ00)|(1<<USBS0)|(0<<UPM00);
//フレーム設定非同期通信8ビット1ストップビットパリティ無し
}
intmain(void){
port_init();//PORT設定
usart_init(MYUBRR);//USART設定
sei();//全割り込み許可

LED_SET();//起動確認LED

for(;;){
if(usart_recvData){//受信データがある時
loop_until_bit_is_set(UCSR0A,UDRE0);//送信データレジスタ空きまで待機
UDR0=usart_recvData;
usart_recvData=NULL;
LED_CLR();
}
}
}
/**UART受信割り込み**/
SIGNAL(SIG_USART_RECV){
LED_SET();
if(bit_is_clear(UCSR0A,FE0)){//フレーミングエラーが無い時
usart_recvData=UDR0;//受信データをグローバル変数に取得
}
}