今回は、シリアル通信(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
おすすめの記事