MPLAB IDE v8.92 MPASM v5.51 PICKit3の環境で、PIC16F648Aで7セグメントLEDの表示テストをやってみます。
PICが開発された時代、表示器の主流はLEDでした。特に数字を表示するには7セグメントが用いられました。(PIC16F648AにはI2C機能は搭載されていません)
今回は、カソードコモンの3桁7セグメントLEDをを使い、ダイナミック点灯表示します。
回路図です。a~gセグメントは、RB0~RB6に接続します。カソード1Y~3YはRA0~RA2に接続します。今回DPは接続していません。カソードをON/OFFするのは、デジタルトランジスタDTC114です。電流制限抵抗は、1KΩと少し大きくして輝度を抑えています。
プログラムです。数値020h=128を表示します。ダイナミック点灯の間隔は、ちらつきが目立たない程度で5ms間隔としました。
クロックは内蔵の4MHzです。
----------------------------------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PIC16F648A 7seg LED TEST
; 2024.11.10
; JH7UBC Keiji Hata
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LIST P=PIC16F648A
INCLUDE P16F648A.INC
__CONFIG _INTOSC_OSC_NOCLKOUT & _CP_OFF & _CPD_OFF & _WDTE_OFF & _PWRTE_ON & _BOREN_OFF & _LVP_OFF & _MCLRE_OFF
ERRORLEVEL -302
;レジスタ
CBLOCK 020h
CNT_1ms
CNT_5ms
SHIFT
BYTE0
DIGIT12
DIGIT34
WORK1
TEMP
ENDC
;入出力設定
BANKSEL TRISA
CLRF TRISA ;PORTAはすべて出力、ただし、RA5は入力
CLRF TRISB ;PORTBはすべて出力
BANKSEL CMCON
MOVLW b'00000111'
MOVWF CMCON ;コンパレータOFF
;データセットとBCD変換
MOVLW 080h
MOVWF BYTE0
CALL CONV_BCD
;データ表示
MAIN
BANKSEL PORTB
MOVFW DIGIT34
ANDLW 0Fh
CALL BCD2LED
MOVWF PORTB
MOVLW b'00000001'
MOVWF PORTA
CALL LOOP5mS
MOVFW DIGIT12
MOVWF WORK1
MOVWF TEMP
SWAPF TEMP,W
ANDLW 0Fh
CALL BCD2LED
MOVWF PORTB
MOVLW b'00000010'
MOVWF PORTA
CALL LOOP5mS
MOVFW WORK1
ANDLW 0Fh
CALL BCD2LED
MOVWF PORTB
MOVLW b'00000100'
MOVWF PORTA
CALL LOOP5mS
GOTO MAIN
;5ms待つルーチン
LOOP5mS
MOVLW 05h ;05h=5
MOVWF CNT_5ms
LOOP2
CALL LOOP1mS
DECFSZ CNT_5ms
GOTO LOOP2
RETURN
;1ms待つルーチン
LOOP1mS
MOVLW 0F9h ;0F9h=249
MOVWF CNT_1ms
LOOP1
NOP
DECFSZ CNT_1ms,F
GOTO LOOP1
RETURN
;--------------------------------------------
; バイナリからBCDへの変換
;--------------------------------------------
CONV_BCD
BCF STATUS,C ;キャリーをクリア
MOVLW 08h ;8ビットカウンタ
MOVWF SHIFT ;SHIFT=8
CLRF DIGIT12 ;BCDデータクリア
CLRF DIGIT34
LOOP
RLF BYTE0,F ;shift BYTE to DIGIT
RLF DIGIT12,F
RLF DIGIT34,F
DECFSZ SHIFT,F ;end check
GOTO ADJST ;adjust to BCD
RETURN
ADJST
MOVF DIGIT12,W ;DIGIT12 adjust TO BCD
CALL ADJBCD
MOVWF DIGIT12
MOVF DIGIT34,W ;DIGIT34 adjust to BCD
CALL ADJBCD
MOVWF DIGIT34
GOTO LOOP
;**** Each digit adjust to BCD ****
ADJBCD
MOVWF WORK1 ;save
MOVLW 3 ;W+3
ADDWF WORK1,W
MOVWF TEMP
BTFSC TEMP,3 ;Test W+3>7
MOVWF WORK1 ;>7 then W+3 else W
MOVLW 030h ;W+30
ADDWF WORK1,W
MOVWF TEMP
BTFSC TEMP,7 ;Test W+30>7*
MOVWF WORK1 ;>70 then W+30 else W
MOVF WORK1,W
RETURN
BCD2LED
ADDWF PCL,F
RETLW 03Fh ;0
RETLW 006h ;1
RETLW 05Bh ;2
RETLW 04Fh ;3
RETLW 066h ;4
RETLW 06Dh ;5
RETLW 07Dh ;6
RETLW 007h ;7
RETLW 07Fh ;8
RETLW 06Fh ;9
RETLW 040h ;a
RETLW 040h ;b
RETLW 040h ;c
RETLW 040h ;d
RETLW 040h ;e
RETLW 040h ;f
END
----------------------------------------------------------
データの数値はバイナリでBYTE0に保存します。
このデータをBCDに変換してDIGIT12,DIGIT34に格納します。
DIGIT12の下位4ビット、DIGIT34の上位4ビット、DIGIT34の下位4ビットの順に表示を繰り返します。
数値データに対応したLED用のデータ取得は、BCD2LEDルーチンです。
PICでは、配列データから任意のデータを取得するには、このサブルーチンのようにWレジスタにデータをセットしてプログラムカウンタにWレジスタの値を加えたアドレスのデータをWレジスタにセットしてリターンするという方法がとられます。
ブレッドボードです。データ080h=128が表示されました。
※コメント投稿者のブログIDはブログ作成者のみに通知されます