目次 > 8章.機能が豊富なPICを使う(PIC16F88) > RS232Cでパソコンと通信 > ソース
更新日2009.8.30
以下のソースを取り込んで、アセンブル→PIC書き込み→実行して下さい。
; ========================== ここから ============================== ; ファイル名 RS232C88.asm ; 作成日 2009.7.18 ; 作成者 mit.ueno ; バージョン 1.0 ; ; PIC PIC16F88 ; クロック INTRC 8MHz ; 概要 ; PIC16F88でPCとRS232C通信 ; PCに固定文字列を送信しつつ、 ; PCからの受信文字をLCDに表示 ; 内部クロック8MHz ; 使用ポート ; RA0 LCD DB4 ; RA1 LCD DB5 ; RA2 LCD DB6 ; RA3 LCD DB7 ; ; RB3 LCD RS (4:Register Select) ; RB4 LCD E (6:Enable Signal) ; ; RB2 RX ; RB5 TX ; ; RB1 LED(DEBUG) ; LIST P=16F88 INCLUDE P16F88.INC __CONFIG _CONFIG1, _WDT_OFF & _PWRTE_ON & _INTRC_IO & _LVP_OFF & _MCLR_OFF __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF CBLOCK 020h ;GPR(汎用RAM)定義 CNT50us CNT05ms CNT1ms CNT5ms CNT01s CNT1s char ;LCD出力データ snd_IX ;送信文字列インデックス rcv_char ;RS232C 受信文字 work ENDC RS EQU 03h ;RB3 E EQU 04h ;RB4 ORG 0 GOTO init ; ----------------------------------------------------- ORG 4 ;割込みの入口(未使用) RETFIE ; ----------------------------------------------------- init BSF STATUS,RP0 ;■バンク1に切替え ; <<オシレータ設定>> MOVLW 074h MOVWF OSCCON ; CLOCK=8MHz ; <<ポート設定>> MOVLW 0F0h MOVWF TRISA ; RA0-3は出力 MOVLW 0C5h MOVWF TRISB ; RB1,3-5は出力 ; <<TMR0割込み設定>> MOVLW 80h ; TMR0プリスケーラ:2(0.5μS*2=1.0μS) MOVWF OPTION_REG ; ; <<AN設定>> CLRF ANSEL ;AN未使用 ; <<RS232C設定>> MOVLW 024h MOVWF TXSTA ; 送信有効,非同期,8bit,高速 MOVLW d'51' MOVWF SPBRG ; 9600bps BCF STATUS,RP0 ;■バンク0に切替え MOVLW 090h MOVWF RCSTA ; シリアルポート有効,8bit,連続受信可 CLRF PORTA CLRF PORTB BSF PORTB,1 CALL wait5ms CALL LCD_init CALL LCD_idisp CALL LCD_2line ;LCDの2行目に設定 CLRF snd_IX ; ----------------------------------------------------- main BSF STATUS,RP0 ;■バンク1に切替え BTFSC TXSTA,TRMT ; 送信バッファ空き? GOTO main_send ; Yes BCF STATUS,RP0 ;■バンク0に切替え GOTO main_10 main_send BCF STATUS,RP0 ;■バンク0に切替え BCF PORTB,1 CALL SND232 ;文字列の1文字を送信バッファに格納 GOTO main_90 main_10 BSF PORTB,1 BTFSS PIR1,RCIF ; 受信データあり? GOTO main_90 ; No MOVF RCREG,W ; 受信データ取り出し MOVWF rcv_char CALL LCD_write ; LCDに表示 MOVF rcv_char,W SUBLW 00Dh ; CR? BTFSS STATUS,Z GOTO main_90 ; No CALL LCD_clr2line ; LCDの2行目をクリア CALL LCD_2line ; LCDの2行目に設定 GOTO main_90 main_90 GOTO main ;================= RS232C送信 =============================== SND232 MOVF snd_IX,W CALL SND232V ADDLW 00h BTFSS STATUS,Z GOTO SND232_20 CLRF snd_IX GOTO SND232 SND232_20 MOVWF TXREG ; 送信バッファにデータ格納 INCF snd_IX,F RETURN SND232V ADDWF PCL,F DT "PIC16F88 RS232C test",0Dh,0Ah,00h ;================= LCD初期表示 =========================== LCD_idisp CLRF work LCD_idispL MOVF work,W CALL LCD_idispV ADDLW 00h BTFSC STATUS,Z RETURN CALL LCD_write INCF work,F GOTO LCD_idispL LCD_idispV ADDWF PCL,F DT "PIC16F88 RS232C",00h ;================= LCDの2行目をクリアする =============== LCD_clr2line CALL LCD_2line ;2行目に設定 MOVLW d'16' MOVWF work LCD_clr2line_L MOVLW ' ' CALL LCD_write DECFSZ work,F GOTO LCD_clr2line_L RETURN ;================= LCD表示をクリアする =================== LCD_clear MOVLW 01h CALL LCD_command CALL wait5ms ;LCDのBFをチェックしないので1.53mS以上待つ RETURN ;================= LCDのカーソル位置を先頭に戻す ========= LCD_home MOVLW 080h CALL LCD_command RETURN ;================= LCDのカーソル位置を2行目の先頭に ===== LCD_2line MOVLW 0C0h CALL LCD_command RETURN ;================= LCDのディスプレイをONにする ========= LCD_on MOVLW 0Ch CALL LCD_command RETURN ;================= LCDのディスプレイとカーソルをONにする == LCD_on_cur MOVLW 0Eh CALL LCD_command RETURN ;================= LCDのディスプレイをOFFにする ======= LCD_off MOVLW 08h CALL LCD_command RETURN ;================= LCDにデータを送る ===================== LCD_write MOVWF char BSF PORTB,RS ;RS=1(Data) MOVLW 0F0h ;PORTAの下位4ビットを ANDWF PORTA,F ; クリア SWAPF char,W ;上位 ANDLW 00Fh ;4ビットを IORWF PORTA,F ;PORTA(0-3)にセット(PORTA(4-7)はそのまま) BSF PORTB,E ;LCDにデータ書き込み NOP BCF PORTB,E MOVLW 0F0h ;PORTAの下位4ビットを ANDWF PORTA,F ; クリア MOVF char,W ;下位 ANDLW 00Fh ;4ビットを IORWF PORTA,F ;PORTA(0-3)にセット(PORTA(4-7)はそのまま) BSF PORTB,E ;LCDにデータ書き込み NOP BCF PORTB,E CALL wait50us ;LCDのBFをチェックしないので50uS待つ RETURN ;================= LCDにコマンドを送る =================== LCD_command MOVWF char BCF PORTB,RS ;RS=0(Command) MOVLW 0F0h ;PORTAの下位4ビットを ANDWF PORTA,F ; クリア SWAPF char,W ;上位 ANDLW 00Fh ;4ビットを IORWF PORTA,F ;PORTA(0-3)にセット(PORTA(4-7)はそのまま) BSF PORTB,E ;LCDにデータ書き込み NOP BCF PORTB,E MOVLW 0F0h ;PORTAの下位4ビットを ANDWF PORTA,F ; クリア MOVF char,W ;下位 ANDLW 00Fh ;4ビットを IORWF PORTA,F ;PORTA(0-3)にセット(PORTA(4-7)はそのまま) BSF PORTB,E ;LCDにデータ書き込み NOP BCF PORTB,E CALL wait50us ;LCDのBFをチェックしないので50uS待つ RETURN ;================= LCD初期化 ================================ LCD_init BCF PORTB,RS ;RS=0 BCF PORTB,E ;E=0 MOVLW 003h ;下位4ビットに'3'をセット MOVWF PORTA BSF PORTB,E ;ファンクションセット(1回目) NOP BCF PORTB,E CALL wait5ms ;5mS待つ BSF PORTB,E ;ファンクションセット(2回目) NOP BCF PORTB,E CALL wait5ms ;5mS待つ BSF PORTB,E ;ファンクションセット(3回目) NOP BCF PORTB,E CALL wait5ms ;5mS待つ MOVLW 002h ;4ビットモード MOVWF PORTA ;に BSF PORTB,E ;設定 NOP BCF PORTB,E CALL wait1ms ;1mS待つ MOVLW 028h ;4ビットモード,2行表示,7ドット CALL LCD_command CALL LCD_off ;ディスプレイOFF CALL LCD_clear ;LCDクリア MOVLW 06h ; CALL LCD_command ;カーソルモードセット (Increment) CALL LCD_on ;ディスプレイON,カーソルOFF RETURN ; ******** タイマルーチン ***************************** ; ******** 1sタイマ ******** wait1s MOVLW d'10' MOVWF CNT1s wait1sL CALL wait01s DECFSZ CNT1s,F GOTO wait1sL RETURN ; ******** 100msタイマ ******** wait01s MOVLW d'200' MOVWF CNT01s wait01sL CALL wait05ms DECFSZ CNT01s,F GOTO wait01sL RETURN ; ******** 5msタイマ ******** wait5ms MOVLW d'10' MOVWF CNT5ms wait5msL CALL wait05ms DECFSZ CNT5ms,F GOTO wait5msL RETURN ; ******** 1msタイマ ******** wait1ms MOVLW d'2' MOVWF CNT1ms wait1msL CALL wait05ms DECFSZ CNT1ms,F GOTO wait1msL RETURN ; ******** 0.5msタイマ ******** wait05ms MOVLW d'249' MOVWF CNT05ms wait05msL NOP DECFSZ CNT05ms,F GOTO wait05msL RETURN ; ******** 50usタイマ ******** wait50us MOVLW d'25' MOVWF CNT50us wait50usL NOP DECFSZ CNT50us,F GOTO wait50usL RETURN END ; =========================== ここまで ===============================