Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Pic16f84a interrupt problem

Status
Not open for further replies.

Monchichack

Newbie level 2
Joined
Nov 4, 2009
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
UK
Activity points
1,370
Hi,

I am trying to make an adjustable timer with 3 7-segment led display. The 7 segment works and the switches work but I cannot get TMR0 to cause an interrupt in the program. If I run a dead end loop after the start initialisation bypassing the rest of the code the interrupt works fine. It seems the rest of my code is somehow preventing TMR0 from running but I do not understand how?

Also when I set RB0 out = 1 I need to put a delay afterwards for it to take effect. Does anyone know why this is? If I run a command

bsf RB0 works fine
nop
nop

bsf RB1
bsf BR0 works fine

bsf RB0
bsf RB1 does not enable RB0?


Pic16f84a
Here is my code:
Any help would be much appreciated.


list p=16F84A
#include <p16F84A.inc>

__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC


org 00

;***** VARIABLE DEFINITIONS
Timer1 EQU d'10'
Timer2 EQU d'11'
w_temp EQU 12
status_temp EQU 13
Hundredsmark EQU 14
Tensmark EQU 15
Unitsmark EQU 16
flag EQU 17
timer EQU 18
Function EQU 19
Hundredsspace EQU 20
Tensspace EQU 21
Unitsspace EQU 22

#define SW PORTB,2 ;change tris register to i/p before testing sw and remember to change it back to o/p after!
#define Test PORTB,3
#define Mode PORTB,0

goto Start

;**************************************************************************************************
org 04
Isr
bcf STATUS,RP0
movwf w_temp
movfw STATUS
movwf status_temp

movlw b'00000000'
tris PORTB
nop
nop
nop
nop
nop
movlw b'11111111'
xorwf PORTB,f

movfw status_temp
movwf STATUS
swapf w_temp,f
swapf w_temp,w
bcf INTCON,T0IF
retfie



;Subroutines

Delay movlw d'120'
movwf Timer2
Loop movlw d'120'
movwf Timer1
Loopy decfsz Timer1,f
goto Loopy
decfsz Timer2,f
goto Loop
retlw 0



Display
addwf PCL,f
retlw b'11111100' ;0
retlw b'01100000' ;1
retlw b'11011010' ;2
retlw b'11110010' ;3
retlw b'01100110' ;4
retlw b'10110110' ;5
retlw b'10111110' ;6
retlw b'11100000' ;7
retlw b'11111110' ;8
retlw b'11110110' ;9

modedisplay
addwf PCL,f
retlw b'01100000' ;1
retlw b'11011010' ;2


;******************************************************************************************************************
Counterfixmark
movlw b'1001'
subwf Tensmark,w
btfsc STATUS,Z
goto TensFixmark
incf Tensmark
clrf Unitsmark
goto displayloop

TensFixmark
movlw b'1001'
subwf Hundredsmark,w
btfsc STATUS,Z
goto HundredsFixmark
incf Hundredsmark
clrf Tensmark
clrf Unitsmark
goto displayloop

HundredsFixmark
clrf Unitsmark
clrf Tensmark
clrf Hundredsmark
goto displayloop


Counterdownfixmark
movlw b'0'
subwf Tensmark,w
btfsc STATUS,Z
goto TensdownFixmark
decf Tensmark
movlw d'9'
movwf Unitsmark
goto displayloop

TensdownFixmark
movlw b'0'
subwf Hundredsmark,w
btfsc STATUS,Z
goto HundredsdownFixmark
decf Hundredsmark
movlw d'9'
movwf Tensmark
movwf Unitsmark
goto displayloop

HundredsdownFixmark
movlw d'9'
movwf Unitsmark
movwf Tensmark
movwf Hundredsmark
goto displayloop
;*****************************************************************************************************************
Counterfixspace
movlw b'1001'
subwf Tensspace,w
btfsc STATUS,Z
goto TensFixspace
incf Tensspace
clrf Unitsspace
goto displayloop

TensFixspace
movlw b'1001'
subwf Hundredsspace,w
btfsc STATUS,Z
goto HundredsFixspace
incf Hundredsspace
clrf Tensspace
clrf Unitsspace
goto displayloop

HundredsFixspace
clrf Unitsspace
clrf Tensspace
clrf Hundredsspace
goto displayloop


Counterdownfixspace
movlw b'0'
subwf Tensspace,w
btfsc STATUS,Z
goto TensdownFixspace
decf Tensspace
movlw d'9'
movwf Unitsspace
goto displayloop

TensdownFixspace
movlw b'0'
subwf Hundredsspace,w
btfsc STATUS,Z
goto HundredsdownFixspace
decf Hundredsspace
movlw d'9'
movwf Tensspace
movwf Unitsspace
goto displayloop

HundredsdownFixspace
movlw d'9'
movwf Unitsspace
movwf Tensspace
movwf Hundredsspace
goto displayloop

;********************************************************************************************************************

Start
;pic starts up in bank 0
clrf PORTA ;clear general purpose registers
clrf PORTB
clrf Hundredsmark
clrf Tensmark
clrf Unitsmark
clrf Hundredsspace
clrf Tensspace
clrf Unitsspace
clrf timer
bcf flag,1 ;used to start program off at 0. Possibly phase out once startup values are taken from rom
clrf Function ;so function starts on 1
clrf TMR0
bsf STATUS,RP0
movlw b'00001' ;ra4 = O/P. RA1-3 transistors. RA0 = x
tris PORTA
movlw b'11000111' ;TMR0 prescaled by 256 & assigned to TMR0. WPU dissabled
option
movlw b'10100000'
movwf INTCON ;setup interrupt on timer 0
goto displayloop


;****************************************************************************************************


Mark

Countupmark

movlw b'1001' ;make sure counter does not overflow
subwf Unitsmark,w
btfsc STATUS,Z
call Counterfixmark ; goto instead of clrf so counter 0 is used
incf Unitsmark,f
incf timer
goto displayloop
countdownmark
movlw b'0' ;make sure counter does not overflow
subwf Unitsmark,w
btfsc STATUS,Z
call Counterdownfixmark ; goto instead of clrf so counter 0 is used
decf Unitsmark,f
decf timer
goto displayloop


Gap

Countupspace

movlw b'1001' ;make sure counter does not overflow
subwf Unitsspace,w
btfsc STATUS,Z
call Counterfixspace ; goto instead of clrf so counter 0 is used
incf Unitsspace,f
incf timer
goto displayloop
countdownspace
movlw b'0' ;make sure counter does not overflow
subwf Unitsspace,w
btfsc STATUS,Z
call Counterdownfixspace ; goto instead of clrf so counter 0 is used
decf Unitsspace,f
decf timer
goto displayloop
;*****************************************************************************************************







Main
btfss Mode ;test mode switch
goto countdown
incf Function ;2 modes - inc/dec mark - inc/dec gap
btfsc Function,1 ;make sure mode does not go over 2
clrf Function ;removed because 0 bit will toggle each button press anyway
bcf STATUS,RP0
bsf PORTA,3
bsf PORTA,2
bcf PORTA,1
;movlw b'1101' ;switch on hundreds o/p
;movwf PORTA
movfw Function
call modedisplay
movwf PORTB
modeloop call Delay
btfsc Mode ;Mode sw bounce
goto modeloop

countdown bsf STATUS,RP0
movlw b'11111111' ;Change PORTB to SW input RB0 = MODE
tris PORTB
bcf STATUS,RP0 ;move to porta for switch i/p
nop ;wait to allow change to take effect
nop
nop
nop
btfss Test ;test if countdown button is pressed?
goto countupsw
bsf flag,1
btfsc Function,0
goto countdownmark
goto countdownspace

countupsw
btfss SW ;test if count up button is pressed?
goto displayloop
bsf flag,1
btfsc Function,0
goto Countupmark
goto Countupspace

;********************************************************************************************************
scroll bsf STATUS,RP0 ;scroll mode allows mode sw to be used for mode or fast scroll without sw bounce
movlw b'11111111' ;Change PORTB to SW input. RB0 = MODE
tris PORTB
bcf STATUS,RP0 ;move to porta for switch i/p
nop ;wait to allow change to take effect
nop
nop
nop
btfss Test ;test if countdown button is pressed?
goto countupsw
bsf flag,1
goto countdown
;*********************************************************************************************************



displayloop bsf STATUS,RP0
movlw b'00000001' ;rb0 = MODE. RB1-7 = 7 seg LED
tris PORTB
bcf STATUS,RP0 ;move to porta for switch i/p
nop ;wait to allow change to take effect
nop
nop
nop
bcf STATUS,RP0
bsf PORTA,3
bsf PORTA,2
bcf PORTA,1
;movlw b'1101' ;strobing hundreds tens and units
;movwf PORTA
btfss Function,0
goto jumpy
movfw Hundredsmark
goto contli
jumpy movfw Hundredsspace
contli call Display
movwf PORTB
call Delay

next bcf PORTA,3
bsf PORTA,2
bsf PORTA,1
;movlw b'0111'
;movwf PORTA
btfss Function,0
goto jumping
movfw Tensmark
goto cont
jumping movfw Tensspace
cont call Display
movwf PORTB
call Delay

bsf PORTA,3
bcf PORTA,2
bsf PORTA,1
;movlw b'1011'
;movwf PORTA
btfss Function,0
goto jumped
movfw Unitsmark
goto contiui
jumped movfw Unitsspace
contiui call Display
movwf PORTB
call Delay

btfss flag,1 ;only run bounce if flag is set meaning sw has been pressed
goto Main
btfsc Mode ;if mode sw is pressed counter will inc/dec fast without waiting for sw bounce
goto scroll
bsf STATUS,RP0
movlw b'11111111' ;Change PORTB to input mode. RB0 = MODE
tris PORTB
bcf STATUS,RP0 ;move to porta for switch i/p
nop ;wait to allow change to take effect
nop
nop
nop
btfsc SW ;switchbounce using the routine as a delay and thus keeping led's on
goto displayloop
btfsc Test
goto displayloop
bcf flag,1
goto Main

END

Added after 26 minutes:

Thanks if you have been looking at this for me but someone has answered my question on another forum. I will post his answer as if helped me and may help others. He was reffering to slightly different code but I believe it was the timer1 and timer2 delay naming which was causing the trouble and I was overwriting the system variables....


Hi,

You will be hard pressed to see / make use of timer 0 on a scope - try to use the Mplab Debuggers, Mplab Sim with breakpoints in your code as I did in that screenshot, it also allows you to single step through each line of code.

The problem with your variables is their addresses, would suggest you always specify all eight bits doing it that way, it is however generally more common to address them in hex.
Would also suggest against using timer1 and timer2 as names for those variables as they could cause confusion with the Pic timer1 and timer2 .

your code

w_temp EQU b'1010'
timer1 EQU b'1011'
timer2 EQU b'1100'
status_temp EQU b'1101'


for clarity try

= w_temp EQU 0x0A


but -

If you look at the pic18f84a datasheet, memory section, you will see that the available user ram space starts at 0x0C, so you have been trying to overwite the systems variables - perhaps why things are not working.
 

Hi,

I do use both sites, so am not following you around , will not reply again.

Just that you seem to have failed to see the points I was trying to get across before.

Here is that same code this time corrected, with notation, so that the ISR also works, as you can see from the Sim screen shot that it has got into the ISR routine because bit 2 of the INTCON register, the interrupt, has been turned on.
The red dot is the breakpoint and the green arrow is when the simulator executes the code and then stops when it gets to the break point.

Hope that gets you going.
 
I have changed my code to include all of your points and it works perfectly, I will make sure I use them in the future.

It is a little bit embarrasing to look at the size of it for such a simple task,, I am sure I could have made some clever use of flags to reduce the number of subroutines.

Thanks again

Chris
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top