Searching \ for '[PIC] LED Digit Multiplexing Timer Interrupt Routi' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/ints.htm?key=interrupt
Search entire site for: 'LED Digit Multiplexing Timer Interrupt Routi'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] LED Digit Multiplexing Timer Interrupt Routi'
2005\10\21@140028 by markp

flavicon
face
I have a three digit LED display for a thermometer.  I had the multiplexing
working fine for the three digits when it was in my main code.  I simply
decremented a variable that was initialized with a value of 3.  For each
value, I turned on the respective digit, delayed for a while, and went to
the next one.  I wanted to make changes to the code that would affect the
time delay between displays so I thought I should put the digit
multiplexing code in a routine that would be called by a
TIMER0 rollover-initiated interrupt.  I tested the scheme with a called
routine that simply toggled an output, and the interrupt stuff all worked
well.

Once I got that far, I started working on the multiplexing math and logic
but have had no success.  This is my first time at using interrupts and I
suspect that I am doing something wrong that is messing up my code.  I show
three versions of my routine below.  The first worked fine and showed me
that I had the interrupt stuff right.  The next two show simple attempts at
asserting three outputs in succession, however without success.  Can
someone tell me the errors of my ways here?!?!?!?!  Plus, is there a
slicker easier way to do this?

Thanks.

Mark Peterson

DISPLAY
     movwf _w          ; Save
     swapf status,w          ; Save
     movwf _status           ; Save
     bcf   intcon,2          ; Clear interrupt bit

     movfw LOOP        ; LOOP to w
     movwf portb       ; Send to port

     LOOPDEC
     decfsz      LOOP        ; Equal to 0?
      goto       $+3         ; No, leave and do it again later.
     movlw d'3'        ; Yes, reinitialize LOOP variable.
     movwf LOOP        ; Yes, reinitialize LOOP variable.

     swapf _status,w   ; Restore.
     movwf status            ; Restore.
     swapf _w          ; Restore.
     swapf _w,w        ; Restore.
     retfie                  ; Return.

With the code above, bits 0 and 1 on Portb step through 11, 10, 01 with
each rollover of TIMER0.  With this success, I moved on to transform the
LOOP count into individual bit assertions.


DISPLAY
     movwf _w          ; Save
     swapf status,w          ; Save
     movwf _status           ; Save
     bcf   intcon,2          ; Clear interrupt bit

     movfw LOOP        ; LOOP to w
     call  DIGIT_T
     movwf portb

     LOOPDEC
     decfsz      LOOP        ; Equal to 0?
      goto       $+3         ; No, leave and do it again later.
     movlw d'3'        ; Yes, reinitialize LOOP variable.
     movwf LOOP        ; Yes, reinitialize LOOP variable.

     swapf _status,w   ; Restore.
     movwf status            ; Restore.
     swapf _w          ; Restore.
     swapf _w,w        ; Restore.
     retfie                  ; Return.

****Tabel located in main code******
DIGIT_T     ; 3 digit display table
     addwf pcl,f       ; Jump into lookup table
           ; _____321'
     retlw b'11111011' ; Segment 3
     retlw b'11111101' ; Segment 2
     retlw b'11111110' ; Segment 1

With the code above, portb bits 0, 1, & 2 are on all the time.  It's a
simple lookup table yet I can't see what I did wrong.


DISPLAY
     movwf _w          ; Save
     swapf status,w          ; Save
     movwf _status           ; Save
     bcf   intcon,2          ; Clear interrupt bit

     bsf   portb,0           ; Turn off 100 digit
     bsf   portb,1           ; Turn off 10 digit
     bsf   portb,2           ; Turn off 1 digit

     movfw LOOP        ; LOOP to w
     sublw d'3'        ; 3 - LOOP in w
     btfss status,2          ; LOOP = 3?
      goto LOOPDEC     ; No, leave.
     bcf   portb,2           ; Yes, turn on 100 digit
     goto  LOOPDEC     ; Yes, leave.

     movfw LOOP        ; LOOP to w
     sublw d'2'        ; 2 - LOOP in w
     btfss status,2          ; LOOP = 2?
      goto LOOPDEC     ; No, leave.
     bcf   portb,1           ; Yes, turn on 10 digit
     goto  LOOPDEC     ; Yes, leave.

     movfw LOOP        ; LOOP to w
     sublw d'1'        ; 1 - LOOP in w
     btfss status,2          ; LOOP = 1?
      goto LOOPDEC     ; No, leave.
     bcf   portb,0           ; Yes, turn on 1 digit
     goto  LOOPDEC     ; Yes, leave.

     LOOPDEC

     decfsz      LOOP        ; Equal to 0?
      goto       $+3         ; No, leave and do it again later.
     movlw d'3'        ; Yes, reinitialize LOOP variable.
     movwf LOOP        ; Yes, reinitialize LOOP variable.

     swapf _status,w   ; Restore.
     movwf status            ; Restore.
     swapf _w          ; Restore.
     swapf _w,w        ; Restore.
     retfie                  ; Return.

With the code above, portb,2 flashes at the rate that TIMER0 rolls over but
bits 0 and 1 are on steady.  Again, it's straight forawrd stuff that works
in regular main code but I can't get to work inside the interrupt-called
routine.


2005\10\21@181627 by Jan-Erik Soderholm

face picon face
Hi.
Just a few things...

First, what processor ?

> DISPLAY
>       movwf _w          ; Save
>       swapf status,w          ; Save
>       movwf _status           ; Save
>       bcf   intcon,2          ; Clear interrupt bit

Use the builtin bit-names instead of "2".
And move this to the line right before RETFIE.

The rest of first code snipped worked, you said...

Second code snippet...
{Quote hidden}

Generaly speaking,m try to avoid the "$" thing.
By using lables the code is easier to read.

{Quote hidden}

Now, the table isn't realy "located" in any "code".
It's just a peice of code someware...


> DIGIT_T     ; 3 digit display table
>       addwf pcl,f       ; Jump into lookup table
>             ; _____321'
>       retlw b'11111011' ; Segment 3
>       retlw b'11111101' ; Segment 2
>       retlw b'11111110' ; Segment 1

Depending on the processor (> 2 Kwords flash) you *could*
have a PCLATH problem here.

>
> With the code above, portb bits 0, 1, & 2 are on all the time.  It's
a
> simple lookup table yet I can't see what I did wrong.
>

Third code snippet...

{Quote hidden}

This part will *always* jump to LOOPDEC. The code
for digit 2 and 1 below will never run, no matter what
the value of LOOP is. The first "goto LOOPDEC"
should probably jump to the code below. And the
same with the first "goto LOOPDEC" below.
If LOOP isn't "3", you should not leave, you should
test if LOOP is "2", right `?


>
>       movfw LOOP        ; LOOP to w
>       sublw d'2'        ; 2 - LOOP in w
>       btfss status,2          ; LOOP = 2?
>        goto LOOPDEC     ; No, leave.
>       bcf   portb,1           ; Yes, turn on 10 digit
>       goto  LOOPDEC     ; Yes, leave.
>

[snipped rest...]



2005\10\21@191331 by Jinx

face picon face
> DISPLAY
>       movwf _w          ; Save
>       swapf status,w          ; Save
>       movwf _status           ; Save
>       bcf   intcon,2          ; Clear interrupt bit

As J-E said, better to use the assigned name for a bit

So, bcf intcon,t0if

J-E suggested moving it to just before the RETFIE. What's
important is that it is cleared somewhere in the ISR and
that IRQs do not come faster than the ISR can process
them

And for those status tests, there are more readable ways
to do it

For btfss status,2 you can use the MPLAB pseudo-op
"skpz" or define your own. eg #define zero  status,2, and
use btfss zero. Similarly with skpnz, skpc, skpnc etc

>        goto       $+3         ; No, leave and do it again later.

Ditto J-E, goto a label. Makes reading program flow a lot
clearer. I am guilty of using goto $-1 (or goto $-2) for a
bit-wait-test loop

> ****Table located in main code******

You HAVE to be sure where that table winds up in memory
or you could have a PCLATH problem, if for example the
table crosses a page boundary. That doesn't sound like your
problem at this time because the program doesn't *appear* to
be crashing. On the face of it it should work. You should
ensure that the section of code is in the bank you want - maybe
you're addressing trisb instead of portb ?

==========================

Example 3

There is no branch in this test to get to the next. Whatever the
result, PC goes to LOOPDEC

{Quote hidden}

2005\10\22@023411 by Maarten Hofman

face picon face
> First, what processor ?

Excellent question.

> >       movfw LOOP        ; LOOP to w
> >       call  DIGIT_T

There is a slight chance of a stack overflow here (depending on processor type).

> > DIGIT_T     ; 3 digit display table
> >       addwf pcl,f       ; Jump into lookup table
> >             ; _____321'
> >       retlw b'11111011' ; Segment 3
> >       retlw b'11111101' ; Segment 2
> >       retlw b'11111110' ; Segment 1
>
> Depending on the processor (> 2 Kwords flash) you *could*
> have a PCLATH problem here.

Not > 2 KWord. Already at 256 word boundaries this could create
problems. You HAVE to make sure where the table is.

Greetings,
Maarten Hofman.

2005\10\22@063318 by Jinx

face picon face
> You HAVE to make sure where the table is

One way to do this, in absolute mode, is through the variable "led_table"

Set it equal to a memory address

led_table = 0x0400 ;a memory address past the end of code

To load PCLATH in your loop routine

movf  high(led_table) ;sets PCLATH to 04
movwf pclath

The table itself is orged in memory

org led_table ;table starts at 0x0400

DIGIT_T    addwf pcl

dt b'11111011',b'11111101',b'11111110' ;dt creates retlw statements

2005\10\22@063728 by Jinx

face picon face
> movf  high(led_table) ;sets PCLATH to 04

Should have a ,w (grrrr, sorry)

movf  high(led_table),w ;sets PCLATH to 04


2005\10\22@064647 by Jinx

face picon face
> movf  high(led_table) ;sets PCLATH to 04

Dammit Janet, I WILL learn to read my own code !!

movlw high(led_table) ;sets PCLATH to 04
movwf pclath

Using movf high(led_table),w won't return high(led_table). It
will return the variable at address 04

2005\10\24@123042 by markp

flavicon
face
*** This is my second submission of this question.  I never did see it
posted on my digest pages so I am assuming it never made it through.
Forgive me if some of you did receive it.

I have a three digit LED display for a thermometer.  I had the multiplexing
working fine for the three digits when it was in my main code.  I simply
decremented a variable that was initialized with a value of 3.  For each
value, I turned on the respective digit, delayed for a while, and went to
the next one.  I wanted to make changes to the code that would affect the
time delay between displays so I thought I should put the digit
multiplexing code in a routine that would be called by a
TIMER0 rollover-initiated interrupt.  I tested the scheme with a called
routine that simply toggled an output, and the interrupt stuff all worked
well.

Once I got that far, I started working on the multiplexing math and logic
but have had no success.  This is my first time at using interrupts and I
suspect that I am doing something wrong that is messing up my code.  I show
three versions of my routine below.  The first worked fine and showed me
that I had the interrupt stuff right.  The next two show simple attempts at
asserting three outputs in succession, however without success.  Can
someone tell me the errors of my ways here?!?!?!?!  Plus, is there a
slicker easier way to do this?

Thanks.

Mark Peterson

DISPLAY
     movwf _w          ; Save
     swapf status,w          ; Save
     movwf _status           ; Save
     bcf   intcon,2          ; Clear interrupt bit

     movfw LOOP        ; LOOP to w
     movwf portb       ; Send to port that selects which of 3 digits to
display

     LOOPDEC
     decfsz      LOOP        ; Equal to 0?
      goto       $+3         ; No, leave and do it again later.
     movlw d'3'        ; Yes, reinitialize LOOP variable.
     movwf LOOP        ; Yes, reinitialize LOOP variable.

     swapf _status,w   ; Restore.
     movwf status            ; Restore.
     swapf _w          ; Restore.
     swapf _w,w        ; Restore.
     retfie                  ; Return.

With the code above, bits 0 and 1 on Portb step through 11, 10, 01 with
each rollover of TIMER0.  With this success, I moved on to transform the
LOOP count into individual bit assertions.


DISPLAY                 ; Use looping variable and lookup table to sequence
through bits
     movwf _w          ; Save
     swapf status,w          ; Save
     movwf _status           ; Save
     bcf   intcon,2          ; Clear interrupt bit

     movfw LOOP        ; LOOP to w
     call  DIGIT_T     ;
     movwf portb       ; Send to port that selects which of 3 digits to
display

     LOOPDEC
     decfsz      LOOP        ; Equal to 0?
      goto       $+3         ; No, leave and do it again later.
     movlw d'3'        ; Yes, reinitialize LOOP variable.
     movwf LOOP        ; Yes, reinitialize LOOP variable.

     swapf _status,w   ; Restore.
     movwf status            ; Restore.
     swapf _w          ; Restore.
     swapf _w,w        ; Restore.
     retfie                  ; Return.

****Tabel located in main code******
DIGIT_T     ; 3 digit display table
     addwf pcl,f       ; Jump into lookup table
           ; _____321'
     retlw b'11111011' ; Segment 3
     retlw b'11111101' ; Segment 2
     retlw b'11111110' ; Segment 1

With the code above, portb bits 0, 1, & 2 are on all the time.  It's a
simple lookup table yet I can't see what I did wrong.


DISPLAY                 ; Use looping variable and value comparisons to
sequence through bits
     movwf _w          ; Save
     swapf status,w          ; Save
     movwf _status           ; Save
     bcf   intcon,2          ; Clear interrupt bit

     bsf   portb,0           ; Turn off 100 digit
     bsf   portb,1           ; Turn off 10 digit
     bsf   portb,2           ; Turn off 1 digit

     movfw LOOP        ; LOOP to w
     sublw d'3'        ; 3 - LOOP in w
     btfss status,2          ; LOOP = 3?
      goto LOOPDEC     ; No, leave.
     bcf   portb,2           ; Yes, turn on 100 digit
     goto  LOOPDEC     ; Yes, leave.

     movfw LOOP        ; LOOP to w
     sublw d'2'        ; 2 - LOOP in w
     btfss status,2          ; LOOP = 2?
      goto LOOPDEC     ; No, leave.
     bcf   portb,1           ; Yes, turn on 10 digit
     goto  LOOPDEC     ; Yes, leave.

     movfw LOOP        ; LOOP to w
     sublw d'1'        ; 1 - LOOP in w
     btfss status,2          ; LOOP = 1?
      goto LOOPDEC     ; No, leave.
     bcf   portb,0           ; Yes, turn on 1 digit
     goto  LOOPDEC     ; Yes, leave.

     LOOPDEC

     decfsz      LOOP        ; Equal to 0?
      goto       $+3         ; No, leave and do it again later.
     movlw d'3'        ; Yes, reinitialize LOOP variable.
     movwf LOOP        ; Yes, reinitialize LOOP variable.

     swapf _status,w   ; Restore.
     movwf status            ; Restore.
     swapf _w          ; Restore.
     swapf _w,w        ; Restore.
     retfie                  ; Return.

With the code above, portb,2 flashes at the rate that TIMER0 rolls over but
bits 0 and 1 are on steady.  Again, it's straight forawrd stuff that works
in regular main code but I can't get to work inside the interrupt-called
routine.


2005\10\24@141833 by Timothy J. Weber

face
flavicon
face
markp@cannontech.com wrote:
> This is my first time at using interrupts and I
> suspect that I am doing something wrong that is messing up my code.  I show
> three versions of my routine below.  The first worked fine and showed me
> that I had the interrupt stuff right.  The next two show simple attempts at
> asserting three outputs in succession, however without success.

Don't know which chip you're working with or whether your main program
spans banks, but... Shouldn't you be using BANKSEL before accessing
LOOP?  (or some more sophisticated approach)
--
Timothy J. Weber
http://timothyweber.org

2005\10\24@154727 by Jan-Erik Soderholm

face picon face
(Also CC'ed off-list directly to "spam_OUTmarkpTakeThisOuTspamcannontech.com")

.....markpKILLspamspam@spam@cannontech.com wrote :

> *** This is my second submission of this question.  I never did see
it
> posted on my digest pages so I am assuming it never made it through.
> Forgive me if some of you did receive it.

Some of us ? :-)
The whole list got it.
And there was 5,6 maybe 7 replyes posted with
some severe errors pointed out.

It's your problem, check the archives...

Best Regards,
Jan-Erik.



2005\10\27@165359 by markp

flavicon
face
Thank you to those who pointed out errors in my display routine.  I
implemented those with success and moved on.  Unfortunately, I've run into
another problem.

For testing and development, I simply assigned fixed values to my display
digits.  I know the math I did earlier works so I took it out to shorten
the program so that readers can focus on the code that is giving me
trouble.   If I make the assignment inside the TIMER0-interrupt-intiated
DISPLAY routine, the program works great and I get a perfect 123 on the
display consistently.  It also works perfectly if I make the assignment at
beginning of the program along with my other variable initializations.
However, if I make the assignment in my main program loop, I get a good 123
display only about half of the time.  The rest of the time, 1, 2, or all 3
digits will flash the bootup routine FLASH sequence endlessly.  I cannot
figure where I am doing something on the edge that causes the program's
behavior to be inconsistent.  You can see the locations where I placed the
test assignments in my code below.  Any ideas?

Thanks.  Mark Peterson


;=================================================================
;
;     Project:    Indicator Device
;     File:       Indicator_1.asm
;     Programmer: Mark Peterson
;     Device:     Microchip PIC16C773
;
; Modification History:
;
; Original        10-10-05    MJP
;
;
     list  p=16c77
     radix hex

;     cpu equates (memory map)

porta equ   0x05  ; Analog input, button input.
                 ;  RA0 - Oil temperature input
                 ;  RA1/4 - Not used

portb equ   0x06  ; Indication & control output.
                 ;  bit0 - Digit 100 Output
                 ;  bit1 - Digit 10 Output
                 ;  bit2 - Digit 1 Output
                 ;  bit3/7 - Not used

portc equ   0x07  ; Indication & control output.
                 ;  bit0 - 7-segment LED - a
                 ;  bit1 - 7-segment LED - b
                 ;  bit2 - 7-segment LED - c
                 ;  bit3 - 7-segment LED - d
                 ;  bit4 - 7-segment LED - e
                 ;  bit5 - 7-segment LED - f
                 ;  bit6 - 7-segment LED - g
                 ;  bit7 - Not used

; System Variables
timer0      equ   0x01
pcl   equ   0x02
status      equ   0x03
adcon0      equ   0x1f
adresh      equ   0x1e
adresl      equ   0x9e
intcon      equ   0x0b

trisa equ   0x85
trisb equ   0x86
trisc equ   0x87
adcono      equ   0x1f
adcon1      equ   0x9f
option_reg  equ   0x81
refcon      equ   0x9b
lvdcon      equ   0x9c

; Loop and Temporary Variables
COUNT1      equ   0x20  ; Time delay looping variable
COUNT2      equ   0x21  ; Time delay looping variable
LOOP  equ   0x22        ; Display loop vari used in DISPLAY interrupt
routine
VAR         equ   0x23  ; Misc math variable
COUNT equ   0x24        ; Misc looping variable
_w          equ   0x25  ; Interrupt save value
_status     equ   0x26  ; Interrupt save value

; Program Variables
FLAGS equ   0x30        ; Tracking flags.
                       ;  bit0 - Temperature out of range
                       ;  bit1/7 - Not Used

TEMPH_RAW   equ   0x31  ; Temperature value - raw high byte
TEMPL_RAW   equ   0x32  ; Temperature value - raw low byte
TEMP_H      equ   0x33  ; Temperature value - high byte
TEMP_L      equ   0x34  ; Temperature value - low byte
TEMP        equ   0x35  ; Temperature value - scaled single byte
DIGIT100    equ   0x36  ; Temperature decimal 100's digit
DIGIT10     equ   0x37  ; Temperature decimal 10's digit
DIGIT1      equ   0x38  ; Temperature decimal 1's digit

;---------------------------------------------------
     org   0x00
     goto  start

     org   0x04
     goto  DISPLAY           ; Digit multiplexing display routine

start

; SET UP PORTS
     bsf   status,5    ;Switch to bank 1.

; Define data port A directions, 0 output, 1 input
     movlw b'00011111'
     movwf trisa

; Define data port B directions, 0 output, 1 input
     movlw b'00000000'
     movwf trisb

; Define data port C directions, 0 output, 1 input
     movlw b'00000000'
     movwf trisc

; Define porta AI and DI/O bits
;
; 1-------  Right justified format
; -011----  Ext Vref+ high and Vss low references
; ----1011  AN9/4=DI, AN03/0=AI
     movlw b'10111011'
     movwf adcon1

; Define OPTION bits
; 0-------  Pull ups enabled by values
; -0------  Interrupt on falling edge
; --0-----  Use internal clock
; ---0----  Interrupt on L-H transition
; ----0---  Prescaler assigned to timer
; -----111  Prescaler = 256
     movlw b'00000111'
     movwf option_reg

     bcf   status,5    ; Switch back to bank 0.

; Define INTCON bits
; 1-------  Enable global interrupts
; -0------  Disable peripheral interrupts
; --0-----  Disable TMR0 overflow interrupt
; ---0----  Disable RBO external interrupt
; ----0---  Disable RB port change interrupt
; -----0--  TMR0 overflow flag, 1 yes, 0 no
; ------0-  RB0 external interrupt occured, 1 yes, 0 no.
; -------0  RB port bit state change, 1 yes, 0 no.
     movlw b'10000000'
     movwf intcon


;;;;;;;     INITIALIZE VARIABLES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     clrf  FLAGS       ; Clear all flag bits
     clrf  portb       ; All outputs off
     clrf  portc       ; All outputs off
     movlw d'3'        ; Display routine variable
     movwf LOOP        ; Display routine variable

; Force test values - Works 100% of the time when enabled here
;     movlw d'3'        ; Write test value to digit.
;     movwf DIGIT1      ; Write test value to digit.
;     movlw d'2'        ; Write test value to digit.
;     movwf DIGIT10     ; Write test value to digit.
;     movlw d'1'        ; Write test value to digit.
;     movwf DIGIT100    ; Write test value to digit.

     call  FLASH       ; Boot up flash sequence

     clrf  timer0      ; Clear timer0
     bsf   intcon,5    ; Enable Timer interrupt

     goto  MAIN        ; Skip over lookup table


BIN2SEG           ; 7-segment display table
     addwf pcl,f       ; Jump into lookup table
           ; _gfedcba'
     retlw b'11000000' ; Segment for 0
     retlw b'11111001' ; Segment for 1
     retlw b'10100100' ; Segment for 2
     retlw b'10110000' ; Segment for 3
     retlw b'10011001' ; Segment for 4
     retlw b'10010010' ; Segment for 5
     retlw b'10000010' ; Segment for 6
     retlw b'11111000' ; Segment for 7
     retlw b'10000000' ; Segment for 8
     retlw b'10011000' ; Segment for 9


MAIN  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Force test values - Upon power up or rest, works fine 50% of the time
; when enabled here and displays a flashing "123".   The rest of the time
; it appears the bootup FLASH routine runs endlessly with 1, 2, 3, or no
; digits being displayed.  There appears to be no pattern to when it works
; or fails.
     movlw d'3'        ; Write test value to digit.
     movwf DIGIT1      ; Write test value to digit.
     movlw d'2'        ; Write test value to digit.
     movwf DIGIT10     ; Write test value to digit.
     movlw d'1'        ; Write test value to digit.
     movwf DIGIT100    ; Write test value to digit.

     goto  MAIN


DISPLAY           ; Three digit display/multiplexing routine

     movwf _w          ; Save w
     swapf status,w    ; Save status
     movwf _status     ; Save status

     bsf   portb,2     ; Turn off 100 digit
     bsf   portb,1     ; Turn off 10 digit
     bsf   portb,0     ; Turn off 1 digit

; Force test values - Works 100% of the time when enabled here
;     movlw d'3'        ; Write test value to digit.
;     movwf DIGIT1      ; Write test value to digit.
;     movlw d'2'        ; Write test value to digit.
;     movwf DIGIT10     ; Write test value to digit.
;     movlw d'1'        ; Write test value to digit.
;     movwf DIGIT100    ; Write test value to digit.
;
     D100  ; Need 100 digit on?
     movfw LOOP        ; LOOP to w
     sublw d'3'        ; 3 - LOOP in w
     btfss status,2    ; LOOP = 3?
      goto D10         ; No, check next.
     bcf   portb,2     ; Yes, turn on 100 digit
     movfw DIGIT100    ; Yes, put digit value into w
     call  BIN2SEG     ; Yes, convert value to 7-segment
     movwf portc       ; Yes, send value to digit display
     goto  LOOPDEC     ; Yes, leave.

     D10         ; Need 10 digit on?
     movfw LOOP        ; LOOP to w
     sublw d'2'        ; 2 - LOOP in w
     btfss status,2    ; LOOP = 2?
      goto D1          ; No, check next.
     bcf   portb,1     ; Yes, turn on 10 digit
     movfw DIGIT10     ; Yes, put digit value into w
     call  BIN2SEG     ; Yes, convert value to 7-segment
     movwf portc       ; Yes, send value to digit display
     goto  LOOPDEC     ; Yes, leave.

     D1          ; Need 1 digit on.
     bcf   portb,0     ; Turn on 1 digit
     movfw DIGIT1      ; Yes, put digit value into w
     call  BIN2SEG     ; Yes, convert value to 7-segment
     movwf portc       ; Yes, send value to digit display

     LOOPDEC
     decfsz LOOP ; Equal to 0?
      goto $+3         ; No, leave and do it again later.
     movlw d'3'        ; Yes, reinitialize LOOP variable.
     movwf LOOP        ; Yes, reinitialize LOOP variable.

     bcf   intcon,2    ; Clear interrupt bit
     swapf _status,w   ; Restore status.
     movwf status      ; Restore status.
     swapf _w          ; Restore w.
     swapf _w,w        ; Restore w.
     retfie            ; Return.


;;;;;;; SUB - 100 MILLISECOND DELAY - WITH 4M OSC ;;;;;;;;;;;; C
D_100MS
;     return
     movlw d'254'
     movwf COUNT1
     movlw d'128'
     movwf COUNT2
     decfsz      COUNT2,f
     goto  $-1
     decfsz      COUNT1,f
     goto  $-5
     return

;;;;;;; BOOT UP FLASH SUBROUTINE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                    ;
FLASH                   ; Figure 8 pattern x3
     bcf   portb,0     ; Turn 1s digit on
     bcf   portb,1     ; Turn 10s digit on
     bcf   portb,2     ; Turn 100s digit on
     movlw d'3'        ; Do loop 3 times
     movwf COUNT       ; Do loop 3 times

     FLASHBEGIN
     movlw b'11111110' ; a
     movwf portc
     call  D_100MS
     movlw b'11111101' ; b
     movwf portc
     call  D_100MS
     movlw b'10111111' ; g
     movwf portc
     call  D_100MS
     movlw b'11101111' ; e
     movwf portc
     call  D_100MS
     movlw b'11110111' ; d
     movwf portc
     call  D_100MS
     movlw b'11111011' ; c
     movwf portc
     call  D_100MS
     movlw b'10111111' ; g
     movwf portc
     call  D_100MS
     movlw b'11011111' ; f
     movwf portc
     call  D_100MS

     decfsz      COUNT
     goto  FLASHBEGIN
     movlw b'11111111' ; All segments off
     movwf portc       ; All segments off

     return

     end

;----------------------------------------------------
;
;     Oscillator              XT - 4.0 MHz
;     Watchdog Timer          Off
;     Power Up Timer          On
;     Brown Out Detect  Off
;     Brown Out Voltage N/A
;     Code Protect            Off
;
;====================================================

2005\10\27@183254 by Jinx

face picon face
Hi Mark, one or two things

I see no .inc file being used. Which explains why you have
to define your own register names. SFR bits also have names,
eg GIE and T0IE, and using them would make the code a
lot more readable

Use #define to make your own bit names, eg

#define CHAR100 portb,0
#define CHAR010 portb,1
#define CHAR001 portb,2

Do not use "bsf status,5" to change bank. It is prone to typos
and slows debugging

banksel can be used in MPLAB

banksel trisb ;for example

or even a macro

bank0    macro
        bcf     status,rp0
        bcf     status,rp1
        bcf     status,irp
        endm

bank1    macro
        bsf     status,rp0
        bcf     status,rp1
        bcf     status,irp
        endm

  bank1
  movlw something
  movwf trisb

cblock can be used (but see also the recent thread on RES etc)
for a variable list

  cblock 0x20
  COUNT1   ; Time delay looping variable
  COUNT2   ; Time delay looping variable
 LOOP        ; Display loop var used in DISPLAY interrupt routine
 etc
 endc

>       movlw b'10000000'
>       movwf intcon

GIE has been turned on. If there are any pending interrupts
this could cause mayhem. And if you don't know what the
interrupt source is, you can't clear it. Clear all interrupt and
enable flags, then set the ones you want, before setting GIE

Aren't your LEDs active low ? Shouldn't you be setting
portb and portc to FF ?

>       clrf  portb       ; All outputs off
>       clrf  portc       ; All outputs off

>       D100  ; Need 100 digit on?
>       movfw LOOP        ; LOOP to w
>       sublw d'3'        ; 3 - LOOP in w
>       btfss status,2    ; LOOP = 3?

This is OK, an alternative would be

 movlw d'3'
 xorwf LOOP,w ;XORing equal values = 0
 skpz

>       LOOPDEC
>       decfsz LOOP ; Equal to 0?
>        goto $+3         ; No, leave and do it again later.

Better to goto a label instead of goto $+3

   decfsz LOOP
   goto   isr_exit

isr_exit     bcf   intcon,2    ; Clear interrupt bit  *** bcf intcon,t0ie
***
>       swapf _status,w   ; Restore status.
>       movwf status      ; Restore status.
>       swapf _w          ; Restore w.
>       swapf _w,w        ; Restore w.
>       retfie            ; Return.

2005\10\27@212043 by Jinx

face picon face
I wrote

isr_exit     bcf   intcon,2    ; Clear interrupt bit  *** bcf intcon,t0ie
***

Should be bcf intcon,t0if, not t0ie

You can re-define SFR bits with names that are more appropriate
for a particular program, which may help debugging. It will make
the program more readable, but you have to consider portability
to other PICs sometimes

For example, say you are counting something like mains cycles
on portb,0 using INT. Which is intcon,1 / intcon,intf

#define mains_cycle intcon,intf ;or whatever name you choose

  btfss mains_cycle

eg if polling (interrupts disabled - you could also test portb,0 itself)
or flag testing in an ISR that could be entered via more than one source


2005\10\30@052403 by michael brown

picon face

From: "Jan-Erik Soderholm"


{Quote hidden}

Haven't you been here long enough to see that the list server does
bizarre things?  Not everyone gets all the messages, nor does everyone
get them in the same order.  Sometimes messages disappear for months and
then just show up seemingly out of nowhere.  I often receive replies to
messages before the original message shows up.

> And there was 5,6 maybe 7 replyes posted with
> some severe errors pointed out.
>
> It's your problem, check the archives...

Actually, it's everyone's problem and you didn't need to be so rude
about it.

More... (looser matching)
- Last day of these posts
- In 2005 , 2006 only
- Today
- New search...