Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Unable to get interrupt from TMR0

Status
Not open for further replies.

Monchichack

New Member
Hi,

I am not new to programming micro controllers but I have never got above the hobby level so everytime I revisit them I have to re-learn.

I am currently having problems receiving an interrupt from TMR0. I have set up a small test program to test the interrupt and also the TMR0 interrupt flag (INTCON,TOIF) but neither seem to be triggering? It is embarrasing to say I have actually been staring at this for 2 days now which is probably my downfall in resolving this issue.


Here is the code,
I am sure I am making a stupid mistake and I would be grateful to anyone who points it out.




list p=16F84A ; list directive to define processor
#include <p16F84A.inc> ; processor specific variable definitions

__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC



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


org 00 ; processor reset vector
goto Start

org 04
goto ISR


Init clrf PORTA
clrf PORTB
clrf TMR0
bsf STATUS,RP0
movlw b'00000000'
tris PORTB
movlw b'00000'
tris PORTA
movlw b'11000111'
option
bcf INTCON,T0IF
movlw b'10100000'
movwf INTCON
retlw 0




Delay
movlw D'44'
movwf timer2
del_loop1 movlw D'44'
movwf timer1
del_loop2 decfsz timer1,F
goto del_loop2
decfsz timer2,F
goto del_loop1
retlw 0



ISR
bcf STATUS,RP0
movwf w_temp
movfw STATUS
movwf status_temp

movlw b'00000000' ;if interrupt occurs PORTB is
movwf PORTB ;cleared
call Delay

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




Start call Init





Main call Delay
bcf STATUS,RP0
movlw b'00000'
movwf PORTA
movlw b'11111111' ;Sets PORTB on
movwf PORTB
call Delay
btfss INTCON,T0IF
goto Main
bcf INTCON,T0IF
movlw b'00000000' ;If TOIF bit is triggered PORTB is
movwf PORTB ;cleared
call Delay
goto Main



End



Also,, while I have your attention:

The final program I am trying to write is going to switch an output port on for 10ms - 9.99 seconds and switch it off for 10ms to 9.99s. Both periods need to be independently adjusted and displayed on 3 7-segment displays when doing so. I have the displys working but I am currently holding the code in 3 registers for hundreds, tens and units and my timer inc/dec will be in another 2 files which I am not sure how to link?

Am I overlooking an easier way to do this program?



Any advise would be appreciated.


Thanks in advance

Chris
 

Wp100

Well-Known Member
Hi,

Not going to have chance to rewrite the code for you but a few pointers might help.

Your ISR routine should be at Org 004 - so no need for the goto ISR
Avoid using Calls from within the ISR, set a flag instead for doing things in the main code loop.

Timer0 nornallly needs setting up with things like the prescaler, enable etc. as do the Interrupts - they need enabling too.
 

Monchichack

New Member
Thanks for the reply.

I have moved my ISR and removed the call from within my ISR but I thought I have already set up TMR0 prescalers in the OPTION reg and enabled the TMR0 and GIE interrupts via the INTCON register? Is there another register I am overlooking?

Thanks

Chris
 

Wp100

Well-Known Member
Hi,

Sorry, missed those settings first time around.

Your code is looking for the timer0 overflow by two means, by the ISR and direcly in your code by testing the overflow flag.

If you run your code in Sim it never seems to get either overflow, but if you remove your Delay routine you can see it clearly is generating the overflow.

Not sure yet why the ISR is not being inovked, but your code does need a lot of work.

You might find this link / delay routines of use
 

Attachments

  • ScreenShot.jpg
    ScreenShot.jpg
    69.3 KB · Views: 91

Monchichack

New Member
Hi,

Thanks for the delay code generator but I am strobing 3 7-segment displays which also double up as switch inputs and I hope to add more features as I progress so I would like to keep the delay independent from the code to prevent the LED's flickering etc.

I chose to check for the interrupt via two means to help narrow down the problem (didnt help)..

I know my code is inefficient and lacking technique but it is getting better (cant get any worse:).

I have tryed many things to get the interrupt working but it is as stubborn as I am and stopping me in my tracks so any help would be much appreciated.
 

Monchichack

New Member
Hi,

I am aware of the Trisa PortA error but it still works and I have been unable to find a replacement command for it that works? I would be happy to know the new command for this function.

I have been following the program structures from a book written by John Morton who includes his variables before the org command? It seems to have worked up until now but after absorbing the tutorial you pointed me to I think I will put an org command before them.

I am using MPLAB v8.10.





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

__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC


org 00 ; processor reset vector

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

goto Start

org 04;interrupt vector
ISR
bcf STATUS,RP0
movwf w_temp
movfw STATUS
movwf status_temp

movlw b'00000000'
movwf PORTB
nop ;to make transitions easier to see on my ancient scope
nop
nop
nop

movfw status_temp
movwf STATUS
swapf w_temp,f
swapf w_temp,w
bcf INTCON,T0IF ;clear timer0 int flag
retfie ; return from interrupt ENABLING GIE


Start

Init clrf PORTA
clrf PORTB
clrf TMR0
bsf STATUS,RP0
movlw b'00000000'
tris PORTB
movlw b'00000'
tris PORTA
movlw b'11000111'
option
bcf INTCON,T0IF
movlw b'10100000'
movwf INTCON

Main
bcf STATUS,RP0
movlw b'00000'
movwf PORTA
movlw b'11111111'
movwf PORTB
btfss INTCON,T0IF
goto Main
bcf INTCON,T0IF
movlw b'00000000'
movwf PORTB
nop ;to make transitions easier to see on my ancient scope
nop
nop
nop
goto Main



End
 

Monchichack

New Member
This is my recent attempt but it still does not work?

I expect to see PORTB go low for a period if the interrupt occured or if the T0IF bit was set.

Any ideas?
 

Monchichack

New Member
I take it back.

It is working now but pretty hard to capture on my scope without delays.

Thanks for your time and pointers to some excellent resources!

Regards

Chris
 

Wp100

Well-Known Member
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.
 

Monchichack

New Member
Thanks WP100.

Your advice is very helpful.

I also took the time to sit down and give MPLAB sim a chance and have realised it is the way forward!
 
Status
Not open for further replies.

EE World Online Articles

Loading
Top