今回は、シリアル通信(UART)に挑戦してみました。
AT90S2313とRaspberryPiとのUSB-シリアル通信用アダプターは以前使用した「KKHMF 2個 USB to UART TTL RS232 PL2303HX ワイヤーアダプタ変換ケーブルRaspberry Pi Arduino用(amazon)」を使用しました。
回路図は下記のとおりです。reset用のプッシュボタンを設けました。

UARTの初期化は、8ビット、ノンパリティ、38400bpsに設定しました。
割り込みは使用せず、ポーリングでシリアル通信を行っています。
ldi r16, 0b00000000 ;CHR9 =0 :data 8bit
out UCR, r16
ldi r16, 12 ;UART Baud Rate 38400 /system clock 8MHz Baud Rate Register =12
out UBRR, r16
ldi r16, 60 ;UART wait (Baud Rate 38400 =12 )*5
uart_wait: nop
nop
dec r16
brne uart_wait
ldi r16, 0b00011000 ;Interrupt Disable,Receiver Enable,Transmitter Enable,data 8bit
out UCR, r16
送信は、UART状態レジスタUSR(UART Status Register)のUART送信データ空きフラグUDRE(UART Data Register Empty)をチェックし、”1”であれば送信データをセットします。
uarttx: sbis USR, UDRE ;Status Register, udre chack
rjmp uarttx
out UDR, r16
ret
受信は、UART状態レジスタUSR(UART Status Register)のUART受信完了フラグRXC(UART Receive Complete)をチェックし、”1"であれば受信データを取得します。
uartrx:
sbis USR, RXC ;Status Register, Rxc chack
rjmp uartrx ;
in r16, UDR
ret
プログラム例として、プログラムコードに埋め込まれたメッセージをUART経由でシリアル端末に出力するとともに、入力されたキーコードをそのまま、端末にエコーするプログラムを用意しました。
プログラムコードに埋め込まれた連続したコードを読み込みするのに便利な命令として、「LPM命令」があります。
LPM命令は、Zレジスターに設定されたアドレスのプログラムコードの内容を読み込むことができます。
LPM命令には、
1、LPM R0←PS(Z) R0暗黙指定
2、LPM Rd,Z Rd←PS(Z) 無変化
3、LPM Rd,Z+ Rd←PS(Z)、Z←Z+1 事後増加
の3種類ありますが、AT90S2313には、1のLPMしかありませんので、何とか工夫して、Zレジスターの増加を行う必要があります。
Zレジスターのインクリメントは、キャリーフラグなしのADD命令でZレジスタの下位を+1して、次にキャリーフラグありのADD命令でZレジスタの上位を+1しました。
z_inc: clc
ldi r16, 0x01
add ZL, r16
ldi r16, 0x00
adc ZH, r16
ret
メッセージを出力するmsgoutは呼ぶ前に設定されたZレジスタで指定されたアドレスの内容をLPM命令でr0に読み込み、0x00でなければUARTで送信し、Zレジスターをインクリメントします。
メッセージを出力し終了したのちは、入力されたキーコードを、そのまま端末にエコーする無限ループに入ります。
ldi ZL, low(2*msg1)
ldi ZH, high(2*msg1)
rcall msgout
ldi ZL, low(2*msg2)
ldi ZH, high(2*msg2)
rcall msgout
loop:
rcall uartrx
rcall uarttx
rjmp loop
msgout: lpm
mov r16, r0
cpi r16, 0x00
breq msgout_end
rcall uarttx
rcall z_inc
rjmp msgout
msgout_end: ret
メッセージは、プログラムコード上に埋め込みしますが、その際に、.db命令は、1行に記述しないと動作がおかしくなります。
msg1:
.db 0x0d,"Hello AVR world!",0x0d,0
msg2:
.db "AT90S2313 Welcome!",0x0d,0x0d,0
全体のプログラムは下記のとおりです。
;AT90S2313 UART (8N1,38400baud)
;
;; AT90S2313 cpu
;; rom 0000h -- 03ffh
;; ram 0000h -- 00dfh
;; eeprom 0000h -- 007fh
;; External clock 8MHz
;;
;; Operating environment
;; Raspberry Pi OS raspbian
;; assemblers avra
;; install [(sudo) apt install avra]
;; file name 2313_uart_msg.asm
;; $ asavr -l 2313_uart_msg.lst 2313_uart_msg.asm
;; $ (sudo) avrdude -v -p m88 -c usbasp -P usb -F -e -U flash:w:2313_uart_msg.hex
;;
.include "/usr/share/avra/2313def.inc"
.CSEG
start:
rjmp reset ;reset
reti ;INT0
reti ;INT1
reti ;Timer/Counter1 CAPT1
reti ;Timer/Counter1 COMP1
reti ;Timer/Counter1 OVF1
reti ;Timer/Counter0 OVF0
reti ;UART RX
reti ;UART UDRE
reti ;UART TX
reti ;Analog Comparator ANA_COMP
reset:
ldi r16, RAMEND ;Stack pointer setting
out SPL, r16
ldi r16, 0b00000000 ;CHR9 =0 :data 8bit
out UCR, r16
ldi r16, 12 ;UART Baud Rate 38400 /system clock 8MHz Baud Rate Register =12
out UBRR, r16
ldi r16, 60 ;UART wait (Baud Rate 38400 =12 )*5
uart_wait: nop
nop
dec r16
brne uart_wait
ldi r16, 0b00011000 ;Interrupt Disable,Receiver Enable,Transmitter Enable,data 8bit
out UCR, r16
ldi ZL, low(2*msg1)
ldi ZH, high(2*msg1)
rcall msgout
ldi ZL, low(2*msg2)
ldi ZH, high(2*msg2)
rcall msgout
loop:
rcall uartrx
rcall uarttx
rjmp loop
msgout: lpm
mov r16, r0
cpi r16, 0x00
breq msgout_end
rcall uarttx
rcall z_inc
rjmp msgout
msgout_end: ret
z_inc: clc
ldi r16, 0x01
add ZL, r16
ldi r16, 0x00
adc ZH, r16
ret
uarttx: sbis USR, UDRE ;Status Register, udre chack
rjmp uarttx
out UDR, r16
ret
uartrx:
sbis USR, RXC ;Status Register, Rxc chack
rjmp uartrx ;
in r16, UDR
ret
msg1:
.db 0x0d,"Hello AVR world!",0x0d,0
msg2:
.db "AT90S2313 Welcome!",0x0d,0x0d,0
アセンブルします。
$ avra -l 2313_uart_msg.lst 2313_uart_msg.asm
AVRA: advanced AVR macro assembler Version 1.3.0 Build 1 (8 May 2010)
Copyright (C) 1998-2010. Check out README file for more info
AVRA is an open source assembler for Atmel AVR microcontroller family
It can be used as a replacement of 'AVRASM32.EXE' the original assembler
shipped with AVR Studio. We do not guarantee full compatibility for avra.
AVRA comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of avra under the terms
of the GNU General Public License.
For more information about these matters, see the files named COPYING.
Pass 1...
/usr/share/avra/2313def.inc(44) : PRAGMA directives currently ignored
/usr/share/avra/2313def.inc(48) : PRAGMA directives currently ignored
/usr/share/avra/2313def.inc(53) : PRAGMA directives currently ignored
/usr/share/avra/2313def.inc(379) : PRAGMA directives currently ignored
/usr/share/avra/2313def.inc(380) : PRAGMA directives currently ignored
/usr/share/avra/2313def.inc(381) : PRAGMA directives currently ignored
/usr/share/avra/2313def.inc(382) : PRAGMA directives currently ignored
/usr/share/avra/2313def.inc(402) : PRAGMA directives currently ignored
Pass 2...
/usr/share/avra/2313def.inc(44) : PRAGMA directives currently ignored
/usr/share/avra/2313def.inc(48) : PRAGMA directives currently ignored
/usr/share/avra/2313def.inc(53) : PRAGMA directives currently ignored
/usr/share/avra/2313def.inc(379) : PRAGMA directives currently ignored
/usr/share/avra/2313def.inc(380) : PRAGMA directives currently ignored
/usr/share/avra/2313def.inc(381) : PRAGMA directives currently ignored
/usr/share/avra/2313def.inc(382) : PRAGMA directives currently ignored
/usr/share/avra/2313def.inc(402) : PRAGMA directives currently ignored
2313_uart_msg.asm(95) : Warning : A .DB segment with an odd number of bytes is detected. A zero byte is added.
2313_uart_msg.asm(98) : Warning : A .DB segment with an odd number of bytes is detected. A zero byte is added.
done
Used memory blocks:
Code : Start = 0x0000, End = 0x004B, Length = 0x004C
Assembly complete with no errors (2 warnings).
Segment usage:
Code : 76 words (152 bytes)
Data : 0 bytes
EEPROM : 0 bytes
AT90S2313にUSBaspで書き込みします。(先頭にsudoが必要な場合もあります)
$ avrdude -v -p 2313 -c usbasp -P usb -F -e -U flash:w:2313_uart_msg.hex
avrdude: Version 6.3-20171130
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch
System wide configuration file is "/etc/avrdude.conf"
User configuration file is "/home/rika/.avrduderc"
User configuration file does not exist or is not a regular file, skipping
Using Port : usb
Using Programmer : usbasp
AVR Part : AT90S2313
Chip Erase delay : 20000 us
PAGEL : P00
BS2 : P00
RESET disposition : dedicated
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
ByteDelay : 0
PollIndex : 3
PollValue : 0x53
Memory Detail :
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom 4 12 64 0 no 128 0 0 4000 9000 0x80 0x7f
flash 4 12 128 0 no 2048 0 0 4000 9000 0x7f 0x7f
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
fuse 0 0 0 0 no 1 0 0 0 0 0x00 0x00
lock 0 0 0 0 no 1 0 0 9000 9000 0x00 0x00
Programmer Type : usbasp
Description : USBasp, http://www.fischl.de/usbasp/
avrdude: auto set sck period (because given equals null)
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.02s
avrdude: Device signature = 0x1e9101 (probably 2313)
avrdude: safemode: Fuse reading not support by programmer.
Safemode disabled.
avrdude: erasing chip
avrdude: auto set sck period (because given equals null)
avrdude: reading input file "2313_uart_msg.hex"
avrdude: input file 2313_uart_msg.hex auto detected as Intel Hex
avrdude: writing flash (152 bytes):
Writing | ################################################## | 100% 2.53s
avrdude: 152 bytes of flash written
avrdude: verifying flash memory against 2313_uart_msg.hex:
avrdude: load data flash data from input file 2313_uart_msg.hex:
avrdude: input file 2313_uart_msg.hex auto detected as Intel Hex
avrdude: input file 2313_uart_msg.hex contains 152 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 0.84s
avrdude: verifying ...
avrdude: 152 bytes of flash verified
avrdude: safemode: Sorry, reading back fuses was unreliable. I have given up and exited programming mode
avrdude done. Thank you.
下記のように出力されたら成功です!(キー入力は任意です)
Hello AVR world!
AT90S2313 Welcome!
asssddd