JH7UBCブログ

アマチュア無線 電子工作 家庭菜園など趣味のブログです

MPLABアセンブラ PIC16F1827 AQM0802A表示テスト

2025-01-27 20:55:18 | MPLAB アセンブラ
 久しぶりに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」が表示されました。