目次 > 8章.機能が豊富なPICを使う(PIC16F88) > RS232Cでパソコンと通信 > ソース

RS232Cでパソコンと通信(PIC16F88)

更新日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
; =========================== ここまで ===============================