Hello Again
So I am in the process of updating my alarm clock project to a PIC because 1. I like the chips better and 2. I have quite a few chips on hand and I want to make multiples. I am trying to get the project back to the point where it was with the AVR but I ran into a hiccup. I am so close to getting to where I was at only 2 more steps to take but I can not get this display to update for the life of me. From all of my debugging endeavors everything is working like it should be through the simulator but when I run it on the chip I get 1 segment on 1 display to light up and it is the wrong segment.
I will admit it is probably from the fact that I converted the code to assembler when previously it was in C. This is not complicated at all it technically should work.
A few pieces of info needed to understand the look up table. The segments are hooked up to the port not by pin order of the display but by pin order of the uC. So this means segment A which is the top segment on the display goes to pin 0. So A..G = 0..6.
This also means that for display selection Display 1's cathode / transistor combo goes to pin 0. So 1..4 = 0..3
Here is the code maybe a PIC expert can see my mistake. But like I said according to the simulator all of the latches are at the values they are suppose to be at the particular point in the program.
There is also some toggle code in the ISR to ensure it was not actually overlapping but everything is more then good.
CODE:
#include <p16f1782.inc>
; configuration fuses
__CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__CONFIG _CONFIG2, (_WRT_OFF & _VCAPEN_OFF & _PLLEN_OFF & _STVREN_ON & _LVP_OFF)
; use decimal as default radix
radix dec
; =============================================================================
; Code Vectors
; =============================================================================
; executed on chip reset
Reset_Vec: code 0x0000
goto Start ; move PC to Start section in Program code block
; executed on interrupt
Interrupt_Vec: code 0x0004
btfsc INTCON, 5 ; check if timer0 overfow interrupt is enabled
bra chk_ovf_flag ; goto timer0 overflow flag check
retfie ; not an interrupt we are interested in exit
chk_ovf_flag:
btfsc INTCON, 2 ; check if interrupt is a timer overflow skip otherwise
goto TMR0_Ovf ; execute timer overflow isr
retfie ; not an interrupt we are interested in exit
; =============================================================================
; Interrupt Service Code Block
; =============================================================================
Interrupt_Service: code
; Timer0 overflow interrupt service routine
TMR0_Ovf:
bcf INTCON, 2 ; clear timer0 overflow interrupt flag
banksel LATB ; bank2
bsf LATB, 4
btfsc LATB, 0 ; if digit 1 is set it was just updated
bra update_dig2 ; update digit 2
btfsc LATB, 1 ; if digit 2 is set it was just updated
bra update_dig3 ; update digit 3
btfsc LATB, 2 ; if digit 3 is set it was just updated
bra update_dig4 ; update digit 4
btfsc LATB, 3 ; if digit 4 is set it was just updated
bra update_dig1 ; update digit 1
bra update_dig1 ; otherwise we need to update digit 1 (first update only)
update_dig1:
bcf LATB, 3 ; in bank2 clear RB4 so we can update digit 1
bsf LATB, 0 ; set RB0 so we can update digit 1
movlw 1 ; grab digit 1 from table
call Digit_tbl
movwf LATA ; in bank2 load digit to display
bcf LATB, 4
retfie
update_dig2:
bcf LATB, 0 ; in bank2 clear RB0 so we can update digit 2
bsf LATB, 1 ; set RB1 so we can update digit 2
movlw 2 ; grab digit 2 from table
call Digit_tbl
movwf LATA ; in bank2 load digit to display
bcf LATB, 4
retfie
update_dig3:
bcf LATB, 1 ; in bank2 clear RB1 so we can update digit 3
bsf LATB, 2 ; set RB2 so we can update digit 3
movlw 0 ; grab digit 0 from table
call Digit_tbl
movwf LATA ; in bank2 load digit to display
bcf LATB, 4
retfie
update_dig4:
bcf LATB, 2 ; in bank2 clear RB2 so we can update digit 4
bsf LATB, 3 ; set RB3 so we can update digit 4
movlw 0 ; grab digit 0 from table
call Digit_tbl
movwf LATA ; in bank2 load digit to display
bcf LATB, 4
retfie
; =============================================================================
; Program Code Block
; =============================================================================
Program: code
; performs program setup logic
Start:
movlw b'01101000' ; set cpu frequency 4 MHZ (1 microsecond / instruction)
; 0------- PLL is disabled
; -1101--- 4 MHZ clock
; -----0--
; ------00 clock selection determined by fuse settings
banksel OSCCON ; bank1
movwf OSCCON
clrf TRISA ; in bank1 set PORTA as output
clrf TRISB ; in bank1 set PORTB as output
movlw b'11010011' ; setup timer internal clock 1:16 prescale
; gives us an overflow once every 4ms
; 11------ not used on timer0
; --0----- internal clock count
; ---1---- not using T0CKI
; ----0--- use prescale
; -----011 1:16 prescale
movwf OPTION_REG
movlw b'10100000' ; enable global interrupt and timer0 overflow interrupt
; 1------- global interrupt enable
; -0------
; --1----- timer0 overflow interrupt enable
; ---0----
; ----0---
; -----000 interrupt flags
movwf INTCON
banksel TMR0 ; bank0
clrf TMR0 ; clear timer
banksel LATA ; bank2
clrf LATA ; make sure PORTA data latch is clear
clrf LATB ; make sure PORTB data latch is clear
; main program loop
loop:
bra loop ; loop forever
; =============================================================================
; 7 Segment Display Digit Lookup Table
; =============================================================================
; We need to ensure our table does not rollover the page boundary
; so we will specify where the data will be located in memory.
Display_Digit_Lookup: code 0x200
; Index into the table with wreg returns value at index in wreg
Digit_tbl:
addwf PCL, f
retlw b'00111111' ; digit 0
retlw b'00000110' ; digit 1
retlw b'01011011' ; digit 2
retlw b'01001111' ; digit 3
retlw b'01100110' ; digit 4
retlw b'01101101' ; digit 5
retlw b'01111101' ; digit 6
retlw b'00000111' ; digit 7
retlw b'01111111' ; digit 8
retlw b'01101111' ; digit 9
end ; end of code