kuroの覚え書き

96の個人的覚え書き

PIC16F819のポートBのみでLCDを表示する



これでちょっとはまってますが、なんとかプログラムかけた。

未だ実機テストはしてない。できたらだいぶ進歩するんだけど。


#ブレッドボードでバラックテストしてみたところきちんとLCDに表示された。めでたし。

次はとりあえずAD変換を試してみて温度計を完成させよう。

でもシリアル通信はやっぱりUSARTのある機種でやることにしよう。


やっぱり旬はPIC16F88かな。


LIST P=PIC16F819
INCLUDE "P16F819.INC"
__CONFIG _BODEN_OFF & _WDT_OFF & _PWRTE_ON & _LVP_OFF & _INTRC_IO & _MCLR_OFF

;イレーズ時は上記の値は、3FFFなので、すべて1がデフォルト値になる。 *要注意箇所
;CP : プログラムメモリのコードプロテクト
; 1:プロテクト オフ _CP_OFF
; 0:プロテクト オン _CP_ALL
;CCPMX : CCP1の出力ピンの指定
; 1:RB2ピンとする _CCP1_RB2
; 0:RB3ピンとする _CCP1_RB3
;DEBUG : ICDによるデバッグモード許可指定
; 1:デバッグモード禁止 (RB6、RB7は汎用入出力) _DEBUG_OFF
; 0:デバッグモード許可 (RB6、RB7はデバッガ専用) _DEBUG_ON
;WRT1:0 : プログラムメモリの書き込み許可指定
; PIC16F818の場合
; 11:全範囲書き込み許可
; 10:000から1FFの範囲を禁止 残りは許可
; 01:全範囲禁止
; PIC16F819の場合
; 11:全範囲書き込み許可 _WRT_ENABLE_OFF
; 10:000から1FFの範囲を禁止 残りは許可 _WRT_ENABLE_512
; 01:000から3FFの範囲を禁止 残りは許可 _WRT_ENABLE_1024
; 00:000から5FFの範囲を禁止 残りは許可 _WRT_ENABLE_1536
;CPD : データEEPROMのコードプロテクト
; 1:プロテクト オフ _CPD_OFF
; 0:プロテクト オン _CPD_ON
;LVP : 低電圧書き込み許可指定
; 1:許可 (RB3がPGMピンとなる) _LVP_ON
; 0:禁止 (RB3は汎用入出力ピンとなる) _LVP_OFF *
;BOREN : ブラウンアウトリセットの許可指定
; 1:BOR許可 _BODEN_ON
; 0:BOR禁止 _BODEN_OFF
;MCLRE : MCLRピンの使用方法指定
; 1:MCLRピンとして使用(外部リセット端子となる) _MCLR_ON *
; 0:RA5ピンとして使用 (汎用入力ピンとなる) _MCLR_OFF *
; (MCLRは内部で電源にプルアップ)
;PWRTEN: パワーアップタイマの許可指定
; 1:PWRT禁止 _PWRTE_OFF
; 0:PWRT許可 _PWRTE_ON *
;WDTEN : ウォッチドッグタイマの許可指定
; 1:WDT動作許可 _WDT_ON
; 0:WDT動作禁止 _WDT_OFF *
;FOSC2:0: システムクロックの指定
; 111:EXTRC 外部RC発振モード _EXTRC_CLKOUT
; OSC2ピンはクロック出力
; 110:EXTRC 外部RC発振モード _EXTRC_IO
; OSC2ピンはRA6として汎用入出力
; 101:INTRC 内蔵クロックモード _INTRC_CLKOUT
; OSC2ピンはクロック出力 OSC1ピンは汎用入出力
; 100:INTRC 内蔵クロックモード _INTRC_IO
; OSC2ピンはRA6として汎用 OSC1ピンもRA7として汎用
; 011:EXTCLK 外部発振器モード _EXTCLK
; OSC2ピンはRA6として汎用
; 010:HS HSモード _HS_OSC
; 001:XT XTモード _XT_OSC
; 000:LP LPモード _LP_OSC

CBLOCK 020H ;先頭の番地を指定
CNT0
CNT1
DSPDT
ENDC ;定義終わり
LCD_PW EQU 0
LCD_RS EQU 1
LCD_RW EQU 2
LCD_E EQU 3

ORG 0000H
;メイン
;初期設定
CLRF PORTB ;PORTBをクリア
BSF STATUS,RP0 ;ページ変更(Bank 1へ)
MOVLW 0H ;RBをすべて出力に設定
MOVWF PORTB
MOVLW 070H ;01110000
MOVWF OSCCON ;クロックを8MHzにセット
;OSCCON: OSCILLATOR CONTROL REGISTER (ADDRESS 8Fh)
;bit6-4が周波数指定用ビット。ほかは基本的に0でよい
;bit7 Unimplemented: Read as ‘0’
;bit6-4 IRCF2:IRCF0: Internal Oscillator Frequency Select bits
; 111 = 8MHz (8MHz source drives clock directly)
; 110 = 4MHz
; 101 = 2MHz
; 100 = 1MHz
; 011 = 500kHz
; 010 = 250kHz
; 001 = 125kHz
; 000 = 31.25kHz (INTRC source drives clock directly)
;bit3 Unimplemented: Read as ‘0’
;bit2 IOFS: INTOSC Frequency Stable bit
; 1 =Frequency is stable
; 0 =Frequency is not stable
;bit1-0 Unimplemented: Read as ‘0’

MOVLW 06H ;00000110
MOVWF ADCON1 ;PORTAをすべてデジタルIOに
;ADCON1: A/D CONTROL REGISTER 1 (ADDRESS 9Fh)
;bit7 ADFM: A/D Result Format Select bit
; 1 = Right justified, 6 Most Significant bits of ADRESH are read as ‘0’
; 0 = Left justified, 6 Least Significant bits of ADRESL are read as ‘0’
;bit6 ADCS2: A/D Clock Divide by 2 Select bit
; 1 = A/D clock source is divided by 2 when system clock is used
; 0 = Disabled
;bit5-4 Unimplemented: Read as ‘0’
;bit3-0 PCFG<3:0>: A/D Port Configuration Control bits
; PCFG AN4 AN3 AN2 AN1 AN0 Vref+ Vref- C/R
; 0000 A A A A A AVDD AVSS 5/0
; 0001 A VREF+ A A A AN3 AVSS 4/1
; 0010 A A A A A AVDD AVSS 5/0
; 0011 A VREF+ A A A AN3 AVSS 4/1
; 0100 D A D A A AVDD AVSS 3/0
; 0101 A VREF+ D A A AN3 AVSS 3/1
; 0110 D D D D D AVDD AVSS 0/0
; 0111 D D D D D AVDD AVSS 0/0
; 1000 A VREF+ VREF- A A AN3 AN2 3/2
; 1001 A A A A A AVDD AVSS 5/0
; 1010 A VREF+ A A A AN3 AVSS 4/1
; 1011 A VREF+ VREF- A A AN3 AN2 3/2
; 1100 A VREF+ VREF- A A AN3 AN2 3/2
; 1101 D VREF+ VREF- A A AN3 AN2 2/2
; 1110 D D D D A AVDD AVSS 1/0
; 1111 D VREF+ VREF- D A AN3 AN2 1/2
;C/R = Number of analog input channels/Number of A/D voltage references

BCF STATUS,RP0 ;ページ変更(Bank 0へ戻す)

CALL LCD_INI

;[LCD文字位置] (16進)の指定
; |01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|
; ---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
; 01 |80|81|82|83|84|85|86|87|88|89|8A|8B|8C|8D|8E|8F|
; ---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
; 02 |C0|C1|C2|C3|C4|C5|C6|C7|C8|C9|CA|CB|CC|CD|CE|CF|
; ---+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
MOVLW 081H ;例えば1行目2文字目
MOVWF DSPDT
CALL LCD_CMD
;キャラクターコード送信(表示)
MOVLW 'A' ;例えば「A」
MOVWF DSPDT
CALL LCD_DATA

MOVLW 0C1H ;例えば2行目2文字目
MOVWF DSPDT
CALL LCD_CMD

MOVLW 'B' ;例えば「B」
MOVWF DSPDT
CALL LCD_DATA

SLEEP ;終了

;キャラクターコード送信(表示)サブルーチン
LCD_DATA
CALL LCD_BUSY
BSF PORTB,LCD_RS
BSF PORTB,LCD_E
MOVLW 0FH ;00001111
ANDWF PORTB,1 ;RB4〜7クリア
BTFSC DSPDT,7 ;送信
BSF PORTB,7
BTFSC DSPDT,6
BSF PORTB,6
BTFSC DSPDT,5
BSF PORTB,5
BTFSC DSPDT,4
BSF PORTB,4
BCF PORTB,LCD_E
BCF PORTB,LCD_RS

BSF PORTB,LCD_RS
BSF PORTB,LCD_E
MOVLW 0FH ;00001111
ANDWF PORTB,1 ;RB4〜7クリア
BTFSC DSPDT,3 ;送信
BSF PORTB,7
BTFSC DSPDT,2
BSF PORTB,6
BTFSC DSPDT,1
BSF PORTB,5
BTFSC DSPDT,0
BSF PORTB,4
BCF PORTB,LCD_E
BCF PORTB,LCD_RS
RETURN
;LCD_E送信サブルーチン
LCD_CMD
CALL LCD_BUSY

BSF PORTB,LCD_E
MOVLW 0FH ;00001111
ANDWF PORTB,1 ;RB4〜7クリア
BTFSC DSPDT,7 ;送信
BSF PORTB,7
BTFSC DSPDT,6
BSF PORTB,6
BTFSC DSPDT,5
BSF PORTB,5
BTFSC DSPDT,4
BSF PORTB,4
BCF PORTB,LCD_E

BSF PORTB,LCD_E
MOVLW 0FH ;00001111
ANDWF PORTB,1 ;RB4〜7クリア
BTFSC DSPDT,3 ;送信
BSF PORTB,7
BTFSC DSPDT,2
BSF PORTB,6
BTFSC DSPDT,1
BSF PORTB,5
BTFSC DSPDT,0
BSF PORTB,4
BCF PORTB,LCD_E
RETURN

;LCDジーチェック
LCD_BUSY
BSF STATUS,RP0
MOVLW 080H ;RB7を入力に変更
MOVWF PORTB
BCF STATUS,RP0

BSF PORTB,LCD_RW
BSF PORTB,LCD_E
LP_BZ BTFSC PORTB,7
GOTO LP_BZ
BCF PORTB,LCD_E
BCF PORTB,LCD_RW
BSF STATUS,RP0
MOVLW 0H ;RB7を出力に戻す
MOVWF PORTB
BCF STATUS,RP0
RETURN

;LCD初期化
LCD_INI
CLRF CNT0 ;汎用カウンター0をリセット
MOVLW 080H ;10000000
MOVWF CNT1 ;汎用カウンター1にセット
BSF PORTB,LCD_PW ;LCD電源オン
WAIT0 DECFSZ CNT0,F ;LCD受付OKになる頃まで待つ
GOTO WAIT0
DECFSZ CNT1,F
GOTO WAIT0
MOVLW 029H ;00101001 4ビットモード、+E+PW
MOVWF PORTB
BCF PORTB,LCD_E ;これで4ビットモードになる

MOVLW 028H ;00101000 ファンクションセット設定
MOVWF DSPDT
CALL LCD_CMD
MOVLW 0CH ;00001100 表示オン/オフコントロール
MOVWF DSPDT
CALL LCD_CMD
RETURN

END