概要

ターミナルと接続した後、PICを起動すると最初にPIC側からHelloを送信その後、PIC側が受信状態となり、受信した文字をそのままRS232Cへ送信する。ターミナルでRETURNを押すと今まで入力された文字列が液晶に表示される。
LCD液晶はSC2004及びSC1602を対象としている。液晶モジュールの電源の接続がSC2004とSC1602では逆なので注意。SC1602の場合16文字*2行でしか表示されないので注意。
クロックはUSB-IOで接続済みの12MHzのセラミック振動子を使用しPLLで4倍にしている。書込みはPICKit3を前提とする。
ターミナルソフトの設定は以下のとおりとする。
ボー・レート 19200
データ 8bit
パリティ 無し
ストップ 1bit
フロー制御 無し

回路は次のとおりである。
回路図(PNG) 回路図(PDF) 回路図(DXF)

プログラムの説明

ソースファイル

以下のファイルで構成されている
usart1a.asm ・・・ メインプログラム
lcd.asm   ・・・ LCD表示用ライブラリ Version 1.00
lcd.inc   ・・・ LCD表示用インクルードファイル Version 1.00

ソースファイルのダウンロード usart1a.zip

lcd.asm

主にSC1602向けのLCD液晶表示用のライブラリである。
液晶モジュールと接続するポートはマクロで変更可能である。
busyフラグはチェックせずソフトウェアディレイで対応しているためクロック周波数が変更された場合はディレイの調整が必要
詳細は以下のリンクを参照されたい
lcd.asm

usart1a.asm

メインプログラムである。
IOポートの入出力の設定をし、USART及びLCDの初期化、1文字受信しRS232Cへ送信、ENTERが受信されるまでバッファに文字列を格納しENTER受信後、液晶に文字列を表示する。

; RS232Cサンプルプログラム  Version 1.00
; File:        usart1a.asm
; Target:      PIC18F14K50 48Mhz
; アセンブラ:   Microchip MPASM(v5.51)
; 書き込み:     PICKit 3
; リリース:     2013/10/01 21:00
; 概要
;   PC側のターミナルと通信を行う
;   最初にPICがHelloを送信し、受信した文字を送信する。液晶表示はEnterごとに1行ずつ表示する。
;   19200bps 8bit ストップビット1 パリティなし フロー制御無し
;   PC側のターミナルの受信改行コードはCR+LFに設定する必要がある。
;   PC側のターミナルの送受信文字コードをJISにした場合、半角カタカナを使用可能

        #INCLUDE <p18f14k50.inc>
        #include "lcd.inc"

        ; 水晶発振(12MHz) クロック分周無 PLL有効(*4)
        ; ウォッチドッグタイマ無効 低電圧プログラム書き込みモード無効
        CONFIG FOSC = HS,CPUDIV = NOCLKDIV,PLLEN=ON,WDTEN=OFF,LVP=OFF

LED_ADS EQU PORTC
LED0    EQU 0

;   制御コードの定義

CR_CODE EQU 0dh     ; 復帰
LF_CODE EQU 0ah     ; 改行

        UDATA
BUF     RES 8
ARG1    RES 1
Temp1   RES 1
LCD_WRITE   RES 1      ; writeデータを指定
LCD_TEMP    RES 1
Tcount1 RES 1
Tcount2 RES 1
Tcount3 RES 1
BYTE2HEX_TEMP RES 1
ROWC RES 1  ;行位置
LCD_BUF RES 32

        GLOBAL LCD_WRITE,LCD_TEMP,Temp1,Tcount1,Tcount2,Tcount3

        CODE
        ORG 0
        goto   start    ;   リセット時

start
        clrf    ANSEL   ; RC3-RC0,RA4をデジタル入力バッファに設定
        clrf    ANSELH  ; RB5-RB4,RC7-RC6をデジタル入力バッファに設定
        clrf    SLRCON  ; PORTA,PORTB,PORTCをスルーレートを標準に設定
        clrf    TRISA   ; PORTAを全部出力に設定
        clrf    TRISC   ; PORTCを全部出力に設定する
        clrf    PORTC   ; PORTCを全部0にする。
;       USART初期化
        movlw   b'00100100' ; CSRC=0:非同期 TX9=0:8bit BRGH=1:高速
        movwf   TXSTA
        movlw   b'10010000' ; シリアル 8bit
        movwf   RCSTA
        movlw   d'155'          ; 48MHz/(16*19200)-1=155 19230bps 0.16%
        movwf   SPBRG
        movlw   b'11110000'
        movwf   TRISB   ; RB7-RB4の入出力設定(RB7:TX out RB5:RX in)
        call    lcd_init

;   液晶バッファのクリア
        movlw   d'32'
        movwf   Temp1
        movlw   ' '
        lfsr    FSR1,LCD_BUF

loop1
        movwf   POSTINC1
        decfsz  Temp1       ;   Temp1から1を引き結果が0になるまで繰り返す
        bra     loop1

;       Helloを出力
        movlw   'H'
        rcall   usart_write
        movlw   'e'
        rcall   usart_write
        movlw   'l'
        rcall   usart_write
        movlw   'l'
        rcall   usart_write
        movlw   'o'
        rcall   usart_write
        movlw   CR_CODE
        rcall   usart_write
        movlw   LF_CODE
        rcall   usart_write

        lfsr    FSR0,LCD_BUF
        clrf    ROWC

read_loop
        rcall   usart_read  ;   RS232Cから1文字受信
        movwf   ARG1

        movlw   CR_CODE ;   改行コード
        cpfseq  ARG1
        bra     non_cr_in
        bra     cr_in
non_cr_in
        movf    ARG1,W
        movwf   POSTINC0
        bra     echo1

cr_in   ;   改行が入力された
        incf    ROWC
        btfss   ROWC,0
        bra     row2
;   液晶2行目の内容を1行目に転送する スクロール処理
        lfsr    FSR0,LCD_BUF+d'16' ;  2行目のアドレスを設定
        lfsr    FSR1,LCD_BUF
        call    lcd_disp
        bra     echo1
row2
        lfsr    FSR1,LCD_BUF
        call    lcd_disp
;   液晶バッファのクリア
        movlw   d'32'
        movwf   Temp1
        movlw   ' '
        lfsr    FSR0,LCD_BUF
loop2
        movwf   POSTINC0
        decfsz  Temp1       ;   Temp1から1を引き結果が0になるまで繰り返す
        bra     loop2
        lfsr    FSR0,LCD_BUF

;   受信した文字を送信する
echo1
        movf    ARG1,W
        rcall   usart_write
        goto    read_loop

usart_write ;   USARTへ書き込み
       btfss    TXSTA,TRMT ; TSR空か
       bra      usart_write
       movwf    TXREG
       return

usart_read  ;   USARTから読み取り
       btfss    PIR1,RCIF   ; 受信完了
       bra      usart_read
       btfsc    RCSTA,FERR ; フレミングエラーがない場合次の命令をスキップ
       bra      usart_ferr
       btfsc    RCSTA,OERR ; オーバーランエラーがない場合次の命令をスキップ
       bra      usart_oerr
       movf     RCREG,W
       return
usart_ferr  ;   フレミングエラーが発生
usart_oerr  ;   オーバーフローエラーが発生
       bsf LED_ADS,LED0 ;   LEDを点灯
       return

       END