楽天市場
[無料でホームページを作成] [通報・削除依頼]

番外 続ATTINY13A ソフトシリアル


Ralph Doncaster様の BBUart.Sのコードに刺激を受けて、
前ページ 「番外 続ATTINY13A ソフトシリアル」 に記述したコードを更に短縮できないか検討しました。

<BBUart.S>
https://code.google.com/p/picoboot/source/browse/trunk/BBUart.S

<picoboot>
https://code.google.com/p/picoboot/


<結果>
力技を用いて可読性も低下しましたが、何とか1ワード短縮することが出来ました。(トータルのサイズは27ワード)


DDRBレジスタの設定で1ワード
1バイト受信で16ワード
1バイト送信で10ワード


<考えかた>
AVLのアプリケーションノート AVR305: Half Duplex Compact Software UART由来の送信ルーチンでは
スタートビットをCarry=1の状態,ストップビットをCarry=0の状態に割り当てているため、
極性の整合性をとるために送信データ自体をビット反転させる必要がありました。

スタート/ストップビットとCarryの関係を反転させれば送信データの反転が不要となり、コードを1ワード短縮することができるのですが、ATTINYには8ビットレジスタと数値の加算命令が無いことに捕われて、今までATTINYでビットディレイ後にCarry=1で復帰させる方法を思いつきませんでした。(PICのソフトシリアルでは既にCarry=1で復帰する仕様になっています。)

PICと従来のATTINYのコードを以下に示します。

[PICの場合:加算が出来るためZ=1,Carry=1で戻る]
bwait2:
                movlw   .256-((xtal/.4)/baud-.15)/.8
                addlw    0x01
                btfss      STATUS,Z
                goto       $-2
                retlw      0x09

[ATTINYの場合:加算が出来ないのでZ=1,Carry=0で戻る]
bwait2:
                ldi         rs,(xtal/baud-22)/6
                subi       rs,1
                brne      PC-1
                ret

そこで何とかCarry=1で戻る方法を思いつきました。以下のコードを使用します。
ディレイカウンタの初期値を1減らしてrsレジスタの値が-1になるまでループさせます。
bwait2:
                 ldi         rs,(xtal/baud-22)/6-1
                 subi       rs,1
                 brcc       PC-1
                 ret



以下にアセンブラコードを示します。
①レジスタを3つ使用します。
②[n]はサイクル数を示します。
③bwait2ルーチンの中にcnレジスタの減算命令が含まれていることにご注意ください。

.cseg
.equ    xtal      =    9600000  ;Hz
.equ    baud    =    9600       ;bps

.def    rs      =R17            ;ビットディレイカウンター
.def    cn     =R18            ;ビットループカウンター
.def    rxd    =R19            ;送受信バッファー

        #define TX      3                 ; ATTINY13A TX Data output pin (i.e. 2 = PORTB,2)
        #define RX      4                 ; ATTINY13A RX Data input pin (i.e. 3 = PORTB,3)
        #define Direct_TX               ; RS-232C TX Direct Connection(No use MAX232)
        #define Direct_RX               ; RS-232C RX Direct Connection(No use MAX232)

        .org   XXXX
        SBI    DDRB,TX                    ; set TX Port

; ********************************************************************
;
;        RS-232C Send 1byte
;
;        rxdに値をセットして呼び出す(16ワード)
;
; ********************************************************************

SendL:
    #ifdef  Direct_TX
           CBI       PORTB,TX               ; set TX initial level
    #else
           SBI       PORTB,TX
    #endif
            LDI      cn,2*(1+8+1)          ; 10-bit Data
            RJMP    PC+5                      ; Start bit
            ROR     rxd                         ; Rotate Right through Carry    [1] 1+5+6N+16+2=6N+24

     #ifdef    Direct_TX
            BRCC    PC+2                       ;                                          [5]
            CBI       PORTB,TX                ; set TX='0' if Carry='1'
            BRCS    PC+2                       ;
            SBI       PORTB,TX                ; set TX='1' if Carry='0'
     #else
            BRCC    PC+2
            SBI       PORTB,TX                ; set TX='1' if Carry='1'
            BRCS    PC+2
            CBI       PORTB,TX                ; set TX='0' if Carry='0'
     #endif

            RCALL   bwait                      ; wait 1 bit and Carry='1'         [3+3+3N+5+3N+5]
            BRNE    PC-6                        ; loop                                    [2]
bwait:                                             ; wait 1 bit
            RCALL   bwait2
bwait2:                                            ; wait 1/2bit
            LDI       rs,(xtal/baud-22)/6-1                     ;[1] 1+(1+2)*N-1+1+4=3N+5
            SUBI     rs,1                                              ;[1]
            BRCC     PC-1                                            ;[2/1]
            DEC       cn                                               ;[1]
            RET                                                          ;[4]


; ********************************************************************
;
;        RS-232C Recieve 1byte
;
;        受信データはrxdに返る(10ワード)
;
; ********************************************************************

RcvL:                                               ; wait Start bit
        #ifdef  Direct_RX
                SBIS      PINB,RX
        #else
                SBIC      PINB,RX
        #endif
                RJMP      RcvL
                RCALL    bwait2                 ; wait 1/2 bit
                LDI        cn,2*(1+8)           ; 9-bit Data
                ROR       rxd                      ; set Data                             [1] 1+6N+16+2+2=6N+21
                RCALL    bwait                   ; wait 1 bit and Carry='1'       [6N+16]

        #ifdef  Direct_RX
                SBIC      PINB,RX                ; Carry reverse                      [2]
        #else
                SBIS      PINB,RX
        #endif
                CLC
                BRNE      PC-4                     ; loop                                 [2]
                RET




























































































.