PDA

View Full Version : PIC16F688 Timer1



jmbanales21485
- 13th July 2007, 07:05
Hello All,

I need i little help with timer1 in 16F688. I am trying to set the interrupt to flag at about 60us. I have the pic running on the internal oscillator at 8Mhz but for some odd reason it interrupts at far greater than 100ms. I was able to get TMR0 to interrupt as low as 250us but could not get it lower than that. since TMR1 is 16 bits i figured that i will be able to get it lower. Yes i used the PICmulticalc, and according to that I sould get it to interrupt at 65us at 8Mhz. Here is some code to what i am trying to do.

basically i have another pic that is sending a constant pulse which i can vary. th16f688 has an onchange interrupt and every OCI it reinitializes the timer. basically i want the pic to time out when a pulse is larger than 65us(approx)

appearantly the timer times out but i have to put a pulse of something greater than 100ms. any help is appreciated thank you. jose

DEFINE OSC 8
TRISA = %111111 'PORTA as input
TRISC = %000000 'PORTC as output
ANSEL = 0
CMCON0 = 7

'Set to 8 Mhz
OSCCON.4 = 1 'Int Osc = 8MHZ
OSCCON.5 = 1 'Int Osc = 8MHZ
OSCCON.6 = 1 'Int Osc = 8MHZ

'Enable Interrupt Register
INTCON.3 = 1 'PORTA change interupt enabled
INTCON.6 = 1 'Enables Peripheral interrupt
INTCON.7 = 1 'Global interrupt enabled

PIE1.0 = 1 ' Enables the Timer1 Overflow interrupt

'Enable Timer1 Register
T1CON.0 = 1 'Enables Timer1
T1CON.1 = 0 'Internal Clock
T1CON.3 = 0 'LP oscillator is off
T1CON.4 = 0 '1:1 prescaler
T1CON.5 = 0 '1:1 prescaler
T1CON.6 = 0 'TMR1 is on

IOCA.0 = 1 'PORTA.0 is an OCI

OPTION_REG.7 = 0 'Enable Pullup Resistors

'=======Flag Bits======
'PIR1.0 = 1 ' TMR1F Flag Enabled
'PIR1.0 = 0 ' TMR1F Flag Disabled
'INTCON.0 = 1 ' IOC Interrupt Flag enabled
'INTCON.0 = 0 ' Interrupt Flag disabled

on interrupt GOTO myInterrupt

LED VAR PORTC.0
LED1 VAR PORTC.1
dummy VAR PORTC.2



LOW LED
LOW LED1

main:
HIGH dummy
LOW dummy
goto main

disable
myInterrupt:
if PIR1.0 = 1 then timerInt
if INTCON.0 = 1 then onchangeInt
resume

timerInt:
HIGH LED1
pause 500
LOW LED1
pause 500
TMR1H = 0
TMR1L = 0
PIR1.0 = 0 'remove interrupt flag
resume

onchangeINT:
TMR1H = 0
TMR1L = 0
INTCON.0 = 0
resume

Darrel Taylor
- 13th July 2007, 08:24
Hi jose,

At 8Mhz, with a 1:1 prescaler on Timer1, and the count starting from 0, it will take over 32mS for the timer to overflow.

If you want it to take less time, you need to load a value in the TMR1H:L registers, so that it takes fewer "ticks" to make it overflow.

For 65uS, use 65406 ($FF7E).
That way it only takes 130 clock cycles to overflow.

@ 8Mhz, 1 clock cycle = 0.5uS [1/(8,000,000/4)]
and 130 * 0.5 = 65uS

But frankly, trying to get that kind of resolution using ON INTERRUPT is a gamble at best. ASM interrupts would be much better. Or, at least more predictable.

HTH,

Bruce
- 13th July 2007, 13:31
Also, with interrupt on-change, you'll want to read the port in your interrupt
handler, then clear the int-on-change flag bit before exiting the int handler.

jmbanales21485
- 14th July 2007, 00:06
Darryl,

Thank you for that info. I will try it out as soon as i have a chance.

I only wish i knew how to program in assembly. i see that code and all i see is gibberish. basic and C make sense to me but not the high level languages like assembly.

regards

Darrel Taylor
- 14th July 2007, 04:50
Darryl,

Thank you for that info. I will try it out as soon as i have a chance.

Don't forget about Bruce's suggestion. You'll need that too.


I only wish i knew how to program in assembly. i see that code and all i see is gibberish.

And that's the way it'll stay, until you break down and try it.
The hardest part about Assembly Language, is getting past the fear of something you don't already know.

See how the changes work for you, and if there are timing problems, we can set you up with Instant Interrupts, and a couple very small ASM routines.

Once you see how easy it is, you'll slap yourself for not trying it sooner.
<br>

jmbanales21485
- 18th July 2007, 00:56
thank you both. i got my timers working fine. i am able to use tmr0 and tmr1 in my project. even though i could not get a resultion of 65us i was able to get a good reading at 100us which i think should be good enough for what i need.

as for the ASM, your right. i do need to sit there for a day or 2 to figure out ASM and all it is is my lazyness. maybe when i really need to learn it i'll sit there and learn it. but for now im good.

thank you all for your help.

jose