
Originally Posted by
Art
It’s not bad except you don’t need 4 copies of the same lookup table. That should be a subroutine.
If possible, there should be four identical subroutines that you feed each digit to.
You’d normally do the display multiplex in the main program, and only use the interrupt to set a flag
that is being watched by the main program to know when a second, or whatever period ticks over.
The interrupt handler should be the smaller routine.
Hello Art,
something like this:
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 = %01110000
CLKRCON = 0
Include "modedefs.bas"
INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts
TRISA = %000000
ANSELA = %0000
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
;---[show HELO for 0,5sec.]-----------------------------------------------------
intro:
segment=12
gosub look
ones=segment
segment=11
gosub look
tens=segment
segment=10
gosub look
hundreds=segment
segment=13
gosub look
thousands=segment
pause 500
;---[simple counter 0 - to 9999]------------------------------------------------
Main:
for value = 0 to 9999
gosub setdisp
pause 10
next value
value = 0
GOTO Main
setdisp:
segment = value//10
gosub look
ones=segment ; extract ones
segment = value/10
segment = segment//10
gosub look
tens=segment ; extract tens
segment = value/100
segment = segment//10
gosub look
hundreds=segment ; extract hundreds
segment = value/1000
gosub look
thousands=segment ; extract thousands
;---[7 segment pattern 0123456789 and letters H E L O]--------------------------
look:
lookup segment, [%11000000,%11111001,%10100100,%10110000,%10011001,%10010010,%10000010,%11111000,%10000000,%10010000,%10000110,%11000111,%11000000,%10001001],segment
return
return
;---[TMR1 - interrupt handler]--------------------------------------------------
DISP:
T1CON.0 = 0 ; stop timer
TMR1H = %11111100
TMR1L = %00011111
T1CON.0 = 1 ; restart timer
;---[multiplex and show]--------------------------------------------------------
LOW LPIN
Shiftout DPIN, CPIN, MSBFIRST,[ones,%0001]
high lpin
pause 2
LOW LPIN
Shiftout DPIN, CPIN, MSBFIRST,[tens,%0010]
high lpin
pause 2
LOW LPIN
Shiftout DPIN, CPIN, MSBFIRST,[hundreds,%0100]
high lpin
pause 2
LOW LPIN
Shiftout DPIN, CPIN, MSBFIRST,[thousands,%1000]
high lpin
@ INT_RETURN
It is a bit slower, but now I can display digits and letters.
Otherwise, I don't think this is a more efficient and elegant code, it must be a better way.
Bookmarks