Exact match. Not showing close matches.
PICList
Thread
'[PIC] LED Digit Multiplexing Timer Interrupt Routi'
2005\10\21@140028
by
markp
|
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
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}>
> 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.
Generaly speaking,m try to avoid the "$" thing.
By using lables the code is easier to read.
{Quote hidden}> 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******
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}>
> 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.
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
> 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}> 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.
2005\10\22@023411
by
Maarten Hofman
> 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
> 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
> 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
> 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
|
*** 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
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
(Also CC'ed off-list directly to "spam_OUTmarkpTakeThisOuT
cannontech.com")
.....markpKILLspam
@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
|
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
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
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
From: "Jan-Erik Soderholm"
{Quote hidden}> (Also CC'ed off-list directly to "
markp
KILLspamcannontech.com")
>
>
.....markpKILLspam
.....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.
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...