I start to play with one of this cheap 4 digit 7 segment display. The display is driven by two 74HC595 which one is for segments and the other is for common cathodes (digits).
Here is the schematic:
I writed a simple code using Darrel's interrupts. Code multiplexing the digits using TMR1 interrupt.
It works OK, but I think that code is not as elegant. It looks rough, because I'm not a skilled programmer.
Can someone explain to me a better way to do this task?
Here is my code:
'****************************************************************
'* Name : 4 bit 7 segment display *
'* Author : LouisLouis *
'* Notice : Copyright (c) 2018 *
'* : All Rights Reserved *
'* Date : 18. 2. 2018 *
'* Version : 1.0 *
'* Notes : *
'* MCU : PIC 12F1840 *
'****************************************************************
#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
__config _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _BORV_19 & _LVP_OFF
#ENDCONFIG
DEFINE OSC 32 ; Use internal clock
OSCCON = 110000
CLKRCON = 0
Include "modedefs.bas"
INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts
TRISA = %0000
ANSELA = 00
OPTION_REG.7=0 ; Enable internal pull-ups
LPIN var porta.2 ; Latch
DPIN var porta.4 ; Data
CPIN var porta.5 ; Clock
segment var byte
value var word
place var byte[4]
ones var word
tens var word
hundreds var word
thousands var word
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _DISP, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
T1CON = $1
;---[simple counter 0 - to 9999]------------------------------------------------
Main:
for value = 0 to 9999
pause 100
next value
value = 0
GOTO Main
;---[TMR1 - interrupt handler]--------------------------------------------------
DISP:
T1CON.0 = 0 ; stop timer
TMR1H = 111100
TMR1L = 011111
T1CON.0 = 1 ; restart timer
;---[extract ones and show]-----------------------------------------------------
ones = value//10
lookup ones, [000000,111001,100100,110000,011001,010010,000010,111000,000000,010000],segment
LOW LPIN
Shiftout DPIN, CPIN, MSBFIRST,[segment,01]
high lpin
pause 4
;---[extract tens and show]-----------------------------------------------------
tens = value/10
tens = tens//10
lookup tens, [000000,111001,100100,110000,011001,010010,000010,111000,000000,010000],segment
LOW LPIN
Shiftout DPIN, CPIN, MSBFIRST,[segment,10]
high lpin
pause 4
;---[extract hundreds and show]-------------------------------------------------
hundreds = value/100
hundreds = hundreds//10
lookup hundreds, [000000,111001,100100,110000,011001,010010,000010,111000,000000,010000],segment
LOW LPIN
Shiftout DPIN, CPIN, MSBFIRST,[segment,00]
high lpin
pause 4
;---[extract thousands and show]------------------------------------------------
thousands = value/1000
place = 00
lookup thousands, [000000,111001,100100,110000,011001,010010,000010,111000,000000,010000,001000],segment
LOW LPIN
Shiftout DPIN, CPIN, MSBFIRST,[segment,00]
high lpin
@ INT_RETURN
it adds unnecessary bloat for this app
'****************************************************************
'* Name : 4 bit 7 segment display *
'* Author : RICHARD *
'* Notice : *
'* : *
'* Date : 18. 2. 2018 *
'* Version : 1.0 *
'* Notes : *
'* MCU : PIC 12F1822 @32MHZ *
'****************************************************************
#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
__config _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _BORV_19 & _LVP_OFF
#ENDCONFIG
goto overasm
ASM
seg_val
CHK?RP _TM_TMP
MOVWF _TM_TMP
SUBLW 0x21
btfsc STATUS, C
retlw 0 ;" "
MOVF _TM_TMP,W
SUBLW 0x2f
btfsc STATUS, C
retlw 64 ;"-"
MOVF _TM_TMP,W
MOVLW 0X40
SUBWF _TM_TMP,W
btfsC STATUS, C
GOTO TM_ALPHA
MOVF _TM_TMP,W
ANDLW 0X0F
GOTO TM_LU
TM_ALPHA
ANDLW 0xdf ;ucase
SUBLW 6
btfsS STATUS, C
retlw 0 ;ERROR
MOVLW 0X37
SUBWF _TM_TMP,W
ANDLW 0xdf ;ucase
TM_LU
BRW
retlw 0X3F ;0
retlw 6
retlw 0X5B
retlw 0X4F
retlw 0X66
retlw 0X6D
retlw 0X7D
retlw 7
retlw 0X7F
retlw 0X67 ;9
retlw 0X77 ;A
retlw 0X7C ;b
retlw 0X39 ;C
retlw 0X5E ;d
retlw 0X79 ;E
retlw 0X71 ;F
endasm
overasm:
DEFINE OSC 32 ; Use internal clock
ANSELA=0
SSP1CON1=$22
SSP1STAT=$40
OSCCON=$70
DEFINE INTHAND _DISP
TRISA = %111000
@LPORT=LATA
LPIN CON 2 ;var LATa.2 ; Latch
DPIN var porta.0 ; Data SDO
CPIN var porta.1 ; Clock SCK
segment var byte
value var word
d_index var byte
buff var byte[5]
seg_buff var byte[4]
seg_cnt var byte
seg_dat var byte
tmp var byte
TM_TMP var byte
d_pointer var byte
timer1_reload con 33543 ;4mS
PIR1.0=0
INTCON=$C0
PIE1.0=1
T1CON = $1
d_index=0
;---[simple counter 0 - to ffff]------------------------------------------------
Main:
for value = 0 to 65535
arraywrite buff ,[HEX4 value,0]
gosub load_seg
pause 100
next value
value = 0
GOTO Main
load_seg :
for seg_cnt=0 to 3
seg_dat= buff[seg_cnt]
asm
MOVE?BA _seg_dat
L?CALL seg_val
MOVE?AB _seg_dat
endasm
seg_buff[seg_cnt]= seg_dat
next
return
;---[TMR1 - interrupt handler]--------------------------------------------------
DISP:
asm
MOVE?CT 0, T1CON, TMR1ON ; 1 stop timer
MOVLW LOW(_timer1_reload) ; 1 Add TimerReload to the
ADDWF TMR1L,F ; 1 value in Timer1
BTFSC STATUS,C ; 1/2
INCF TMR1H,F ; 1
MOVLW HIGH(_timer1_reload) ; 1
ADDWF TMR1H,F ; 1
MOVE?CT 1, T1CON, TMR1ON ; 1 start timer
MOVE?CB high _seg_buff, FSR0H ;load highbyte
MOVE?CB low _seg_buff, FSR0L ;load low byte
MOVE?BA _d_index
ADDWF FSR0L,F
MOVF INDF0,W
;L?CALL seg_val
MOVE?AB _segment
MOVE?BB _d_index ,_tmp
BANKSEL _tmp
INCF _tmp,F
MOVLW 16
BANKSEL _d_pointer
movwf _d_pointer
BcF STATUS ,C
N_BIT
BANKSEL _d_pointer
RRF _d_pointer,F
BANKSEL _tmp
DECFSZ _tmp,F
GOTO N_BIT
BANKSEL _d_index
INCF _d_index,F
MOVLW 3
ANDWF _d_index,F
BANKSEL LPORT
BCF LPORT ,_LPIN
BANKSEL PIR1
BCF PIR1,3
BANKSEL _segment
MOVF _segment,W ;COMMENT USED TO INVERT DATA FOR COMMON cathode DISPLAY
;COMF _segment,W ;COMMENT USED TO INVERT DATA FOR COMMON ANODE DISPLAY
BANKSEL SSP1BUF
movwf SSP1BUF
BANKSEL PIR1
BTFSs PIR1,3
GOTO $-1
BANKSEL _d_pointer
COMF _d_pointer,W ;COMMENT USED FOR COMMON cathode DISPLAY
;MOVF _d_pointer,W ;COMMENT USED FOR COMMON ANODE DISPLAY
BANKSEL PIR1
BCF PIR1,3
BANKSEL SSP1BUF
movwf SSP1BUF
BANKSEL PIR1
BTFSs PIR1,3
GOTO $-1
BANKSEL LPORT
BSF LPORT ,_LPIN
BANKSEL PIR1
BCF PIR1 ,0
RETFIE
endasm
Main:
for value = 0 to 65535
arraywrite buff ,[HEX4 value]
gosub load_seg
seg_buff[2]=seg_buff[2]|128 ; place a dp in digit 2
pause 100
next value
value = 0
GOTO Main


Menu

Re: 16F690 MCLR as Input
many thanks Henrik to clarify this post.
jackberg1 - 27th October 2025, 20:42that make more sense to me now with further test, when the pin RA3
has nothing connected to it, the input is floating thus
when adding a pulldown it's...