PDA

View Full Version : Newb timer problems



George
- 6th November 2007, 01:54
Until now any timing I've done I've managed to get by with just using a simple loop, looking at the datasheets and setting registers that I do not understand scares me.

What's happening currently is my program has branches withing the timing loop and these stuff up my timing depending on the situation, so I'm gonna bite the bullet and learn how to use the onboard timers. I'm currently uding a 16f676 and was wanting to use timer0 just to increment a time, i qrote a simple bit of code to see if I'd grasped the concept - obviously not!!!

I set the prescaler to 256 and was going to toggle a red led everytime it interupted so I can see it working

here's what I've got so far - would greatly appreciate any suggestions - thanks - also how do i get the code in that lil code box displayed on here?

[code:]
@ DEVICE PIC16F676, XT_OSC, MCLR_OFF, PROTECT_OFF, BOD_ON, CPD_OFF

DEFINE OSC 4

TRISA = %000000
TRISC = %101100

ANSEL = %10000000 'enable ch7 analog
CMCON = 7 'Disable comparitor
OPTION_REG = %00010111 'set prescaler to 256
INTCON.2 = 0 ' Clear Timer0 int flag
INTCON.5 = 1 ' Enable Timer0 int
TMR0 = 0 ' Set TMR0 to 0.

ON INTERRUPT GOTO int

red var PortA.2

clear
PortA = 0
PortC = 0

Start: 'stay in loop

goto start

int: 'toggle led on interupt
TMR0 = 0
toggle red
resume

GeoJoe
- 6th November 2007, 15:17
You need to clear the interupt flag again before resume.

GeoJoe
- 6th November 2007, 15:21
You should disable the interupts before the interupt routine then enable them again when it is complete.
example:
Disable ' Disable interrupts during interrupt handler
tickint:
Stuff during interupt.................
tiexit: INTCON.2 = 0 ' Reset timer interrupt flag
Resume
Enable ' Enable Interrupts

This is code for 16f877a so the intcon bits are probably different.

George
- 6th November 2007, 20:58
Hey GeoJoe, thanks for the input, I've mad ethe changes but still no joy :-s - the intcon bits are the same according to the data sheet "The T0IF bit
(INTCON<2>) must be cleared in software by the
Timer0 module Interrupt Service Routine before reenabling
this interrupt."
but no luck yet, do you think it might be something to do with running an external clock?
also - how do i place the code in a special little code box on here??

@ DEVICE PIC16F676, XT_OSC, MCLR_OFF, PROTECT_OFF, BOD_ON, CPD_OFF

TRISA = %000000
TRISC = %101100

ANSEL = %10000000 'enable ch7 analog
CMCON = 7 'Disable comparitor
OPTION_REG = %00010111
INTCON.2 = 0 ' Clear Timer0 int flag
INTCON.5 = 1 ' Enable Timer0 int
TMR0 = 0 ' Set TMR0 to 0.

ON INTERRUPT GOTO int

red var PortC.0
green var PortA.2
PDWN var PortC.1
DAT var PortC.2
pwr var PortC.4
Switch var PortC.5

clear
PortA = 0
PortC = 0

Start:

goto start

disable
int:
TMR0 = 0
toggle red
intcon.2 = 0 ' reset interupt flag
resume
enable

Darrel Taylor
- 6th November 2007, 22:50
Hi George,

Try this ...
Start:
PAUSE 1
goto start

Or, this ...
Start:
@ CLRWDT
goto start

Or, maybe ...
@ DEVICE PIC16F676, XT_OSC, WDT_OFF, MCLR_OFF, PROTECT_OFF, BOD_ON, CPD_OFF

<br>

George
- 6th November 2007, 22:57
Thanks DT - yr a genius, the first thing i did worked so didn't try the others. Why did it need that pause for it to work - i would have thought it would have just cycled around in the loop

Darrel Taylor
- 7th November 2007, 00:10
..., the first thing i did worked so didn't try the others. ...
Well that's unfortunate.
Trying the other 2, may have answered your question.


Why did it need that pause for it to work - i would have thought it would have just cycled around in the loop

It does "just cycled around in the loop".
But, there's nothing in there to clear the WatchDogTimer. And without it, the processor will reset every ~18ms.
Timer0 was set up with 1:256 prescaler, so it would interrupt after 65.536 ms had passed. But it never made it that far.

PAUSE, automatically clears the WDT every so often, so that caused it to work.

The second example just clears the WDT by using the ASM statement CLRWDT.

And the third example turns the WDT OFF so that it doesn't need to be cleared.

Any one of the three examples should have made it work.
<br>

RodSTAR
- 7th November 2007, 01:18
Hi George,

Try this ...
Start:
PAUSE 1
goto start

Or, this ...
Start:
@ CLRWDT
goto start

Or, maybe ...
@ DEVICE PIC16F676, XT_OSC, WDT_OFF, MCLR_OFF, PROTECT_OFF, BOD_ON, CPD_OFF

<br>


Thanks DT - yr a genius, the first thing i did worked so didn't try the others. Why did it need that pause for it to work - i would have thought it would have just cycled around in the loop

Yes i have the same question:
Why was that "pause 1" needed for it to work??

George
- 7th November 2007, 01:48
Just after I turned the wdt off and got rid of the pause 1 and it worked also, detailed knowlegde certainly helps with these things doesn't it

Cheers for your help