7.シリアル通信について

 

 PIC16F88にはシリアル通信機能(AUSART,非同期通信機能とも称す)が備わっています。 この機能は古くからコンピュータ間の通信やデバイスとの通信に一般的に使われてきたもので今でこそTCP/IP通信やUSB接続が主流になりましたが、パソコンとの通信機能として利用できます。(パソコン側にシリアル通信機能(RS−232Cコネクタ)が無くともパソコンとの間に変換アダプタを接続すると、問題なくUSB通信として利用できる。)

ここでは、このシリアル通信機能を利用する為のプログラミング方法を解説します。 シリアル通信の仕組みについては市販本を参照してください。

PIC16F88のシリアル通信機能を有効にする方法と受信エラーのリカバリー方法を中心に説明します。

 

7.1 コーディング例

このコーディングはシリアル・ポートから受信した以下のフォーマットのデータ(6バイト長)を基に模型車の左右のモータ(2CH)を独立にPWM制御で前後にコントロールできるようにしています。(このコーディングは全コーディングからシリアル通信機能関連を抜粋したもので、このままでは使えません。)

 

<送受信データ・フォーマット>

AABBCCDDEEFF (6バイト長)

;                           **・・・・・・・・・・・・・・・・pre-amble(AA)

**・・・・・・・・・・・・・・ID

**・・・・・・・・・・・・CH1データ 1st.command(右モータ駆動データ)

**・・・・・・・・・・1st.command(reverse) (エラー検出用)

**・・・・・・・・CH2データ 2nd.command(左モータ駆動データ)

**・・・・・・2nd.command(reverse) (エラー検出用)

 

;******************************************

; Initialize Routine

;******************************************

INIT

              BSF                     STATUS,RP0                   ;bank1

;set clock

              MOVLW              070H                                 ;internal clock 8 MHz

              MOVWF              OSCCON                    ;

;initialize PORTs

              MOVLW              030H                                 ;init ports

            MOVWF              TRISA                               ;

              MOVLW              0DH                                 

            MOVWF              TRISB                               ;

;

              MOVLW              0FFH                                 ;set FF to TMR2

              MOVWF              PR2                                   ;

              BSF                     PIE1,TMR1IE                   ;enable TMR1 interrupt                 

四角形吹き出し: TXSTA、SPBRGレジスタに非同期、パリチィ無しの8ビット長、2400BPSを設定。 パリチィ無しに設定したのは、確実にデータを受信する為、コマンドと逆コマンドを2バイト受信し、受信後に比較して、正しく受信したことを確認する方式とした為です。              BSF                     PIE1,TMR2IE                ;enable TMR2 interrupt

;initialize ADC

              MOVLW              010H                                 ;set AN4(CDS)

              MOVWF              ANSEL                          ;

;initialize USRT

              MOVLW              0H                                     ;async,8bit,no-parity

              MOVWF              TXSTA                               ;

              MOVLW              .51                                     ; 2400bps

              MOVWF              SPBRG                              ;

              CLRF                   OPTION_REG                  ;permit week-pullup of PORTB          

              BCF                     STATUS,RP0                     ;bank0

;Stert TMR2

              CLRF                   TMR2                                ;set zero to TMR2

              MOVLW              01BH                               ;start TMR2 counter ( prescaler 1/4

              MOVWF              T2CON                           ;,postscaler 1:16 (8.2ms))

              BSF                     T2CON,TMR2ON             ;start TMR2

;Stert TMR1

              CLRF                   INTCH                              ;reset int. timer

              CLRF                   INTCL                               ;

              MOVLW              030H                                 ;ready TMR1(262 ms interval)

              MOVWF              T1CON                              ;

四角形吹き出し: RCSTAレジスタに受信開始を設定。;start recieve

              MOVLW              090H                                 ;start recieve

              MOVWF              RCSTA                              ;

;

              MOVLW              03H                                   ;clear contorl flags

              MOVWF              CFLAG                              ;

              MOVLW              .1                                       ;set both duty

              MOVWF              DUTYR                             ;

              MOVWF              DUTYL                              ;

              CLRF                   PORTA                              ;clear ports

            CLRF                   PORTB                              ;

;

              MOVLW              0C0H                                 ;enable all interrupts

              MOVWF              INTCON                                          ;

;

;******************************************

; Main Routine                               

;******************************************

;

MAIN

              BCF                     CFLAG,DID                      ;clear detected ID

              BCF                     PORTB,LEDR                   ;light off LED(R)

;check darkness

              CALL                   MCDS                               ;measure CDS value

              MOVLW              .200                                   ;check darkness

              SUBWF               DATA1H,F                        ;

              BTFSS                 STATUS,C                         ;

              GOTO                  MAIN0                              ;

;snooze 

              BCF                     CFLAG,STPM                   ;set stop bit]

              MOVLW              .10                                     ;

              MOVWF              CNT2                                 ;

SNOOZE

              BSF                     PORTA,LEDY                   ;light on yellow LED

              MOVLW              .1                                       ;snooze for 262 sec.

              CALL                   WAITT                              ;

              BCF                     PORTA,LEDY                   ;light off yellow LED

              MOVLW              .4                                       ;snooze for 10 sec.

              CALL                   WAITT                              ;

              DECFSZ              CNT2,F                             ;

              GOTO                  SNOOZE                           ;loop

;go reverse

              BSF                     CFLAG,RWD                    ;set reverse

              BSF                     CFLAG,LWD                     ;

              MOVLW              .63                                     ;set both duty (full speed)

              MOVWF              DUTYR                             ;

              MOVWF              DUTYL                              ;

              BSF                     CFLAG,STPM                   ;start motion

              MOVLW              .8                                       ;wait for 2 sec.

              CALL                   WAITT                              ;

;rotation

              BCF                     CFLAG,RWD                    ;set forward

              BSF                     CFLAG,LWD                     ;

              MOVLW              .63                                     ;set both duty

              MOVWF              DUTYR                             ;

              MOVWF              DUTYL                              ;

              MOVLW              .16                                     ;wait for 4 sec.

              CALL                   WAITT                              ;

              BCF                     CFLAG,STPM                   ;stop motion

              GOTO                  MAIN23                            ;

;

;recieve signal                  

MAIN0

              BTFSS                 CFLAG,TOVR                   ;check time over

              GOTO                  MAIN01                            ;

              BCF                     CFLAG,TOVR                   ;clear time over

              BCF                     T1CON,TMR1ON             ;stop TMR1

四角形吹き出し: 1番目のデータを受信(シリアル通信機能を励起させる為に一般的にAA(10101010)のデータを先頭に付ける)              BCF                     CFLAG,STPM                   ;stop motion        

MAIN01                           

              CALL                   RDATA                              ;recieve pre-amble

              SUBLW               0AAH                                ;check pre-amble(AA)

              BTFSS                 STATUS,Z                         ;

              GOTO                  MAIN                                ;

;check ID

MAIN1

四角形吹き出し: 2番目のデータを受信(デージイ接続などの場合、自分向けのデータか、他のデバイス向けのデータかどうかを判定する為にID(01)をチェックする。
このIDを変更することで、理論上最大256個のデバイスにデータを配信できる。
自分向けのデータでなければ無視する。
              CALL                   RDATA                              ;recieve ID=1

              SUBLW               01H                                   ;check ID

              BTFSS                 STATUS,Z                         ;

              GOTO                  MAIN                                ;

;recieve command

MAIN2

              BSF                     CFLAG,DID                      ;detect ID

              BSF                     PORTB,LEDR                   ;light on LED(R)

;recieve 1st.command

              CALL                   RDATA                              ;recieve 1st.command

              MOVWF              RDATAS                            ;save received data

              MOVF                 CCODE,W                         ;check c-code

              BTFSS                 STATUS,Z                         ;

              GOTO                  MAIN                                ;

;receive 1st.command (reverse)

              CALL                   RDATA                              ;receive reverse-command

              MOVWF              RDATAS1                          ;save received reverse data

四角形吹き出し: 退避しておいた第1コマンドの逆データをCOMP命令で元のコマンドに戻し、比較することでデータの正誤を判定する。 エラーであれば、無視する。              COMF                 RDATAS1,W                     ;

              SUBWF               RDATAS,W                       ;check error of transmit

              BTFSS                 STATUS,Z                         ;

              GOTO                  MAIN                                ;

              MOVF                 CCODE,W                         ;check c-code

              BTFSS                 STATUS,Z                         ;

              GOTO                  MAIN                                ;

              CALL                   RCVC                                ;decode command

;receive 2nd.command

              CALL                   RDATA                              ;receive 2nd.command

              MOVWF              RDATAS                            ;save received data

              MOVF                 CCODE,W                         ;check c-code

              BTFSS                 STATUS,Z                         ;

              GOTO                  MAIN                                ;

;receive 2nd.command (reverse)

              CALL                   RDATA                              ;receive reverse-command             

              MOVWF              RDATAS1                          ;save received reverse data

              COMF                 RDATAS1,W                     ;

              SUBWF               RDATAS,W                       ;check error of transmit

              BTFSS                 STATUS,Z                         ;

              GOTO                  MAIN                                ;

              MOVF                 CCODE,W                         ;check c-code

              BTFSS                 STATUS,Z                         ;

              GOTO                  MAIN                                ;

              CALL                   RCVC                                ;decode command

;start motion

MAIN22

              BSF                     CFLAG,STPM                   ;start motion

;continue timer

MAIN23

              MOVLW              .8                                       ;renew wait timer (2 sec.)

              MOVWF              INTCL                               ;

              CLRF                   INTCH                              ;

              BCF                     CFLAG,TOVR                   ;reset time over flag

              BSF                     T1CON,TMR1ON             ;start TMR1

              CALL                   TIM100U                          ;wait for 100 uS 

              GOTO                  MAIN                                ;

;

;********************************

;Receive Command

;********************************

; input: RDATAS

;  mdxx|xxxx

;  m.............target motor (0:right, 1:left)

;   d............direction of motor (0:forward, 1:reverse)

;    xx xxxx.....speed of motor

;                                                      

RCVC

;set direction and speed of motor

              RLF                     RDATAS,F                         ;check target motor

              BTFSC                STATUS,C                         ;

              GOTO                  MAIN21                            ;

;for right motor

              BCF                     CFLAG,RWD                    ;preset forward of right motor

              RLF                     RDATAS,W                       ;

              BTFSC                STATUS,C                         ;

              BSF                     CFLAG,RWD                    ;set reverse

;

              RRF                     RDATAS,F                         ;

              MOVLW              03FH                                 ;set speed of right motor

              ANDWF              RDATAS,W                       ;

四角形吹き出し: このデータを基に割込み処理(省略)の中で右モータに繋がったブリッジドライバを制御(PWM)              MOVWF              DUTYR                             ;

              RETURN                                                       ;

;for left motor

MAIN21

              BCF                     CFLAG,LWD                     ;preset forward of left motor

              RLF                     RDATAS,W                       ;

              BTFSC                STATUS,C                         ;

              BSF                     CFLAG,LWD                     ;set reverse

;

              RRF                     RDATAS,F                         ;

              MOVLW              03FH                                 ;set speed of left motor

四角形吹き出し: このデータを基に割込み処理(省略)の中で左モータに繋がったブリッジドライバを制御(PWM)              ANDWF              RDATAS,W                       ;

              MOVWF              DUTYL                              ;

              RETURN                                                       ;

;

;******************************************

; Transmit Data                              

;******************************************

;

TDATA

              BSF                     STATUS,RP0                   ;bank1

TDATA1

              BTFSS                 TXSTA,TRMT                   ;check ready

              GOTO                  TDATA1                            ;

              BCF                     STATUS,RP0                     ;bank0

              MOVWF              TXREG                              ;transmit data

              RETURN

;          

;******************************************

; Receive Data                                

;******************************************

;

RDATA

              BTFSC                PIR1,RCIF                        ;check recv ready

              GOTO                  RDATA2                            ;

;

              BTFSS                 CFLAG,TOVR                   ;check time over

              GOTO                  RDATA                              ;

              BCF                     CFLAG,STPM                   ;stop motion

              GOTO                  RDATA                              ;

;            

RDATA2

四角形吹き出し: データ受信後、まずRCSTAレジスタのフレーミング・エラーとオーバーラン・エラーをチェックし、エラーが無ければWレジスタに受信データを格納して戻る。              BTFSC                RCSTA,FERR                    ;check framing err

              GOTO                  FRAME                             ;

              BTFSC                RCSTA,OERR                   ;check overrun err

              GOTO                  OVERR                             ;

              CLRF                   CCODE                             ;set normal code

              MOVF                 RCREG,W                         ;pick up recv data

              RETURN

;

; Error Recovery

FRAME

四角形吹き出し: フレーミング・エラーはRCREGレジスタを空にすることでリセットできる。
RCREGレジスタのデータは過去に受信したテータを最大2バイト分保持しているので、2回読み捨てすることで、受信機能は回復する。
              MOVF                 RCREG,W                         ;remove error data

              MOVF                 RCREG,W                         ;

              BCF                     RCSTA,FERR                    ;clear framing err

              MOVLW              "F"                                     ;set error code

              MOVWF              CCODE                             ;

              CLRW                                                            ;

              BTFSC                RCSTA,OERR                   ;check overrun err

              GOTO                  OVERR                             ;

              RETURN

;

OVERR

四角形吹き出し: オーバーラン・エラーはRCSTAレジスタのCRENビットをクリアした後、再度セットすることで回復する。 念のために、RCREGレジスタのデータも読み捨てる。              BCF                     RCSTA,CREN                   ;reset error status

              BSF                     RCSTA,CREN                   ;

              BCF                     RCSTA,OERR                   ;clear overrun err

              MOVF                 RCREG,W                         ;remove error data

              MOVF                 RCREG,W                         ;

              MOVLW              "V"                                     ;set error code

              MOVWF              CCODE                             ;

              CLRW                                                            ;

              RETURN

 

7.2 後書き

今回はシリアル通信機能を説明しましたが、特に受信機能のエラーリカバリー処理は必須で、不安定な長い通信路を介して届くデータに誤りがあることが多く、エラーが発生すると、すぐに機能が停止してしまいます。 それを素早く回復させ、データの再受信に備える必要があります。 

特に説明はしませんが、送信機能はただデータを送出するだけですから、初期設定に問題がなければ、TXREGレジスタに送信したいデータを送り込めば自動的に送出されます。(Transmit Dataサブルーチンを参照してください。)

以上