list p=16f877a ; PIC16F877A 用のプログラムであることを宣言 #include p16f877a.inc ; PIC16F877A 用のヘッダ・ファイルを読み込む __config _HS_OSC & _CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF TMP equ 0x20 MSG_LOOP equ 0x21 org 0x000 bcf STATUS, RP0 ; この2行でバンク0にする bcf STATUS, RP1 clrf PORTC ; LEDが点灯しないように0に clrf PORTD ; 出力は0にしておく clrf PORTE ; 出力は0にしておく movlw B'01000001' ; A-Dコンバータの設定(ADCON0) movwf ADCON0 movlw B'10010000' ; シリアルの設定 movwf RCSTA bsf STATUS, RP0 ; バンク1にする movlw 0xff movwf TRISB ; ポートBはディジタル入力 bcf OPTION_REG, NOT_RBPU ; ポートBのウィーク・プルアップを有効に movlw B'10000000' movwf TRISC ; RXピン(ビット7)以外を出力に clrf TRISD ; 全ピン出力に movlw B'11000000' ; A-Dコンバータの設定(ADCON1), 右詰め movwf ADCON1 movlw B'00100110' ; シリアルの設定 movwf TXSTA movlw D'64' ; ボーレートの設定 movwf SPBRG bcf STATUS, RP0 ; バンク0にする ; 初期設定は終了 ; 電源を入れたときにメッセージを出す call bootmsg call led_off ; ここからメイン・ルーチン main ; 1バイト受信するまで待つ btfss PIR1, RCIF goto $-1 ; エラーかチェックする btfss RCSTA, OERR goto CHK_FERR bcf RCSTA, CREN ; オーバラン・エラーを消す bsf RCSTA, CREN goto main CHK_FERR btfss RCSTA, FERR goto RCV movfw RCREG ; フレーミング・エラーを消して、次の受信を行う goto main RCV movfw RCREG ; 受信した文字をwレジスタにいれ movwf TMP ; TMPに書いておく call TXCHR ; エコーバックする ; コマンドの解釈 sublw '?' ; '?' を受信したら btfsc STATUS, Z call bootmsg ; 起動時のメッセージを出す movfw TMP sublw '1' ; '1' を受信したら btfsc STATUS, Z call ADC1 ; A-D変換して結果を返す movfw TMP sublw '2' ; '2' を受信したら btfsc STATUS, Z call led_on ; LED0を点灯 movfw TMP sublw '3' ; '3' を受信したら btfsc STATUS, Z call led_off ; LED0 を消灯 goto main ;; メイン・ルーチンはここまで ;; 1文字送信サブルーチン TXCHR btfss PIR1, TXIF ; Check if the buffer is empty goto $-1 movwf TXREG return ;; メッセージを送るサブルーチン bootmsg clrf MSG_LOOP bootmsg_0 movfw MSG_LOOP call MSG0 addlw 0 btfsc STATUS, Z return call TXCHR incf MSG_LOOP, f goto bootmsg_0 ; 人に読める形式で1バイトの数値を16進数で送るサブルーチン SEND_HEX ;; 上位4ビットを0からfの文字で送る movwf TMP swapf TMP, w andlw 0xf call HEX call TXCHR ;; 下位4ビットを0からfの文字で送る movfw TMP andlw 0xf call HEX call TXCHR return ; A-D変換してシリアルに返す ADC1 bsf ADCON0, GO ; A-D変換開始 btfsc ADCON0, GO ; A-D変換終了まで待つ goto $-1 movfw ADRESH ; 上位バイトを送る call SEND_HEX ; 下位バイトを送る bsf STATUS, RP0 ; バンク1にする movfw ADRESL bcf STATUS, RP0 ; バンク0にする call SEND_HEX return ;; LEDを点灯する led_on movlw B'00100001' ; LED0は消灯、LED1は点灯 movwf PORTC ; return ;; LEDを消灯する led_off movlw B'00100000' ; LED0は消灯、LED1は点灯 movwf PORTC ; return org 0x300 ;; メッセージを返す MSG0 clrf PCLATH bsf PCLATH, 0 bsf PCLATH, 1 addwf PCL, f retlw 'H' retlw 'E' retlw 'L' retlw 'L' retlw 'O' retlw '\r' retlw '\n' retlw 0 ;; 4ビットの数字を読める文字に変換する HEX clrf PCLATH bsf PCLATH, 0 bsf PCLATH, 1 addwf PCL, f retlw '0' retlw '1' retlw '2' retlw '3' retlw '4' retlw '5' retlw '6' retlw '7' retlw '8' retlw '9' retlw 'A' retlw 'B' retlw 'C' retlw 'D' retlw 'E' retlw 'F' end リスト5-9 Copyright 2005 Noriaki Mitsunaga