久しぶりにMPLABアセンブラによるPICのプログラミングの勉強を再開します。
MPLAB IDE v9.82, MPASM v5.51, PICKit3の環境で、PIC16F1827のI2C LCD表示器AQM0802Aの表示テストをします。
回路図です。AQM0802Aは秋月電子のモジュールを使います。このモジュールにはI2Cプルアップ抵抗が内蔵されています。ICSPでプログラムの書き込みテストをします。電源は、PICKit3から3.3Vを供給します。
PIC16F1827はMSSPモジュールを2つ持っています。今回はMSSP1を使います。
クロックは、4MHzとします。
入出力設定は、I2CのSDAとSCLになるRB1とRB4は、入力に他は出力に設定します。
I2Cの設定をします。
まず、SSP1CON1レジスタのbit5 SSP1EN=1,bit3:bit0=1000としてI2C Master Modeに設定します。
次に、SSP1STAレジスタで、I2Cの速度を設定します。bit7のSMP=1として、I2C Master Modeの時の標準速度100KHzに設定します。
この速度にするために、SSP1ADDレジスタの値を設定します。
計算式は、ADD=Fosc/(4*clock) - 1
Fosc=4000000hZ(4MHz),clock=100000Hz(100KHz)とすると
ADD=4000000/(4*100000) -1 =9 となり、SSP1ADDに9を設定します。
スタートコンディションとストップコンディションは、SSP1CON2で設定します。
今回は、単純化して、I2C slaveデバイスからのACKは確認しません。また、slaveデバイスは1個のため、信号の衝突回避もしていません。
プログラムです。
----------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PIC16F1827 AQM0802A TEST
; 2025.1.27
; JH7UBC Keiji Hata
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LIST P=PIC16F1827
INCLUDE P16F1827.INC
__CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_19 & _LVP_OFF
ERRORLEVEL -302 ;ERRORメッセージ302を表示しない
CBLOCK 020h
COMMAND
CHAR
CNT1ms
CNTms
X
Y
ENDC
;定数定義
#DEFINE LCDADD 07Ch ;AQM0802AのI2Cアドレス
#DEFINE LINE1 080h
#DEFINE LINE2 0C0h
SETUP
;クロック設定
BANKSEL OSCCON
MOVLW b'01101000' ;PLLなし、4MHz,Fosc
MOVWF OSCCON
;入出力設定
BANKSEL ANSELA
CLRF ANSELA ;AN0-AN4 使用しない
CLRF ANSELB ;AN5-AN11使用しない
BANKSEL TRISA
CLRF TRISA ;RA5は入力、他は出力
MOVLW b'00010010' ;RB1とRB4は入力、他は出力
MOVWF TRISB
;I2C初期化
BANKSEL SSP1CON1
MOVLW b'00101000' ;SSPEN=1,I2C Master Mode
MOVWF SSP1CON1
BANKSEL SSP1STAT
BSF SSP1STAT,SMP ;標準速度モード(100KHz)
BANKSEL SSP1ADD
MOVLW 09h ;Fosc/(4*Clock)-1,Clock=100KHz,Fosc=4MHz
MOVWF SSP1ADD
;LCD初期化
MOVLW 028h ;028h=40
CALL DELAY_ms ;40ms wait
MOVLW 038h
CALL WRITE_COMMAND ;8bit,2line
MOVLW 039h
CALL WRITE_COMMAND ;IS=1,extention mode set
MOVLW 014h
CALL WRITE_COMMAND ;Internal OSC Frequency
MOVLW 070h
CALL WRITE_COMMAND ;Contrast set
MOVLW 056h
CALL WRITE_COMMAND ;Power/ICON/Contrast Control
MOVLW 06Ch
CALL WRITE_COMMAND ;Follower control
MOVLW 0C8h ;0C8=200
CALL DELAY_ms ;200ms wait
MOVLW 038h
CALL WRITE_COMMAND ;IS=0,extention mode cancel
MOVLW 0Ch
CALL WRITE_COMMAND ;Display ON
MOVLW 01h
CALL WRITE_COMMAND ;Clear Display
MOVLW 2
CALL DELAY_ms ;2ms wait
MAIN
MOVLW 'J'
CALL WRITE_CHARACTER
MOVLW 'H'
CALL WRITE_CHARACTER
MOVLW '7'
CALL WRITE_CHARACTER
MOVLW 'U'
CALL WRITE_CHARACTER
MOVLW 'B'
CALL WRITE_CHARACTER
MOVLW 'C'
CALL WRITE_CHARACTER
BANKSEL X
MOVLW 2 ;CURSORをX=2,Y=1に移動
MOVWF X
MOVLW 1
MOVWF Y
CALL CURSOR_XY
MOVLW 'H'
CALL WRITE_CHARACTER
MOVLW 'e'
CALL WRITE_CHARACTER
MOVLW 'l'
CALL WRITE_CHARACTER
MOVLW 'l'
CALL WRITE_CHARACTER
MOVLW 'o'
CALL WRITE_CHARACTER
LOOP
GOTO LOOP
GOTO MAIN
;LCDにコマンドを送る
WRITE_COMMAND
BANKSEL COMMAND
MOVWF COMMAND
CALL I2C_START
MOVLW LCDADD
CALL I2C_WRITE
MOVLW 00h
CALL I2C_WRITE
MOVFW COMMAND
CALL I2C_WRITE
CALL I2C_STOP
RETURN
;LCDに文字を送る
WRITE_CHARACTER
BANKSEL CHAR
MOVWF CHAR
CALL I2C_START
MOVLW LCDADD
CALL I2C_WRITE
MOVLW 40h
CALL I2C_WRITE
MOVFW CHAR
CALL I2C_WRITE
CALL I2C_STOP
RETURN
;Clear Display
CLEAR_DISPLAY
MOVLW 01h
CALL WRITE_COMMAND
MOVLW 2
CALL DELAY_ms
RETURN
;Return Home
HOME_DISPLAY
MOVLW 02h
CALL WRITE_COMMAND
MOVLW 2
CALL DELAY_ms
RETURN
;カーソルをX,Yにセット
CURSOR_XY
BANKSEL X
MOVFW Y
IORLW 00h
BTFSS W,Z ;Y=0ならYOへ Y!=0ならY1へ
GOTO Y1
Y0
MOVLW LINE1
ADDWF X,W
CALL WRITE_COMMAND
RETURN
Y1
MOVLW LINE2
ADDWF X,W
CALL WRITE_COMMAND
RETURN
;スタートコンディション
I2C_START
BANKSEL SSP1CON2
BSF SSP1CON2,SEN
BTFSC SSP1CON2,SEN
GOTO $-1
RETURN
;ストップコンディション
I2C_STOP
BANKSEL PIR1
BCF PIR1,SSP1IF
BANKSEL SSP1CON2
BSF SSP1CON2,PEN
BTFSC SSP1CON2,PEN
GOTO $-1
BANKSEL PIR1
BCF PIR1,SSP1IF
RETURN
;I2Cに1BYTE送信
I2C_WRITE
BANKSEL PIR1
BCF PIR1,SSP1IF
BANKSEL SSP1BUF
MOVWF SSP1BUF
BANKSEL PIR1
BTFSS PIR1,SSP1IF
GOTO $-1
RETURN
;任意のms待つ WREGに1から255をセットしてコールする
DELAY_ms
BANKSEL CNTms
MOVWF CNTms
LOOP2
CALL LOOP1ms
DECFSZ CNTms
GOTO LOOP2
RETURN
;1ms待つ
LOOP1ms
BANKSEL CNT1ms
MOVLW 0F9h ;0F9h=249
MOVWF CNT1ms
LOOP1
NOP
DECFSZ CNT1ms,F
GOTO LOOP1
RETURN
END
----------------------------------
ブレッドボードです。
1行目に「JH7UBC」2行目(X=2,Y=1)に「Hello」が表示されました。