Quote Originally Posted by Art View Post
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.