普段使う20ピンや28ピンのAVRには、UARTピンが1組しかない。64ピンとかになれば2組とか付いているけど。

んで昨日からDontronicsのUARTかUSBで制御できる小型LCDをいじっているんだけど、いつもシリアル通信でデバッグしているのに、UARTがLCDに占有されているせいでデバッグができない。

仕方ないので、信号用のトランジスタ2SC1815と10kΩの抵抗を使って、UARTセレクタ(分岐させる回路)を作った。

usart selectorusart selector



■トランジスタで信号を分岐させる

transistor 2SC1815transistor 2SC1815

ベースに電圧がかかっている間、コレクタからエミッタに電流が抜ける。

なので、マイコンのUARTのTXDを2つのトランジスタのコレクタ接続。エミッタをPCのシリアルポートに接続。マイコンのPD2,3はそれぞれのトランジスタのベースに接続する。

PD2,3のそれぞれ、電圧のかかっている方にシリアル通信が送られる。

■avr-gccでプログラム

main()の中でこうすると

for(;;){
usart_selTxd(0);//出力ピン選択
usart_sendStr(&qute;marutaka¥r¥n&qute;);
usart_selTxd(1);
usart_sendStr(&qute;zanmai¥r¥n&qute;);
}

こういう風に、別々のCOMポートに出力される。

usart selector

mainより先に宣言しておく関数。

/*TXDピンの出力先を選択する*/
voidusart_selTxd(charn){
loop_until_bit_is_set(UCSR0A,UDRE0);//送信データレジスタ空きまで待機
switch(n){
case0:
cbi(PORTD,PD3);
sbi(PORTD,PD2);
break;
case1:
cbi(PORTD,PD2);
sbi(PORTD,PD3);
break;
}
}
/*UARTで文字列送信*/
voidusart_sendStr(char*str){
while(*str!=NULL){
loop_until_bit_is_set(UCSR0A,UDRE0);//送信データレジスタ空きまで待機
UDR0=*str++;//1文字送信、1文字進む
}
}

PD2,3のHIになっている方のCOMポートに出力される。

AVRのUARTは、UDRレジスタに書き込んだ後しばらくしてからTXDから送信される。UART専用のハードウェアで、物理的に別スレッドになっている。だからUDRに書き込む前にUCSRAのUDREビットをチェックして、UDRが空いているか確認しなければならない。

ところでATMega48からUDRやUCSRAが、UDR0やUCSR0Aとかに変わったんだけど、28ピンAVRでも2系統のUSARTが付くのだろうか?

今は名前があるだけで、UDR1やUCSR1Aはまだ無いな。