PDA

View Full Version : Serin2 and Timer1



retepsnikrep
- 22nd August 2010, 18:57
I am using a 12F683 with a Serin2 routine and timeout which works fine.

I am now introducing a timer into my code to count 250ms. The code is base on Melanie's olympic timer stuff and other bits cribbed from here.

Since introducing the timer code the program just does not work and seems to crash at the serin2 routine.

Does serin2 use timer1?

Kamikaze47
- 23rd August 2010, 05:24
are you using interrupts for that timer?

Because an interrupt will interrupt serin2 in the middle of whatever it is doing at the time and you will lose data.

mackrackit
- 23rd August 2010, 05:45
Try
DISABLE
before the SERIN2 command
and
ENABLE
after the SERIN2 command

retepsnikrep
- 23rd August 2010, 06:14
I'm not using an interrupt as such I'm polling the Timer1 flag.

Some code extracts here below



Initialise: 'Initialise 250ms Timer 8mhz clock

PreLoad = 3035 'Preload Constant Loads Timer with 3035 to get 250ms ticks
PIE1.0 = 1 'Enable TMR1 Interrupts (Not sure about this)
TMR1L = PreLoad.LowByte 'Load the Timer with preload value
TMR1H = PreLoad.HighByte 'Load the Timer with preload value
TMR1IF = 0 'Clear TMR1 int flag



My Serin2 command is here in the code.



IF TMR1IF = 0 THEN TimerJump 'If 250ms has not elapsed then jump over below section

T1CON.0=0 'Stop the Clock

TMR1RunOn.Highbyte = TMR1H 'Load the Run-On (Over-Run) value (if any)
TMR1RunOn.Lowbyte = TMR1L 'Load the Run-On (Over-Run) value (if any)
TMR1RunOn = PreLoad + TMR1RunOn 'Calculate new Preload setting to include any timer overrun
TMR1H = TMR1RunOn.HighByte 'Load the timer with new value
TMR1L = TMR1RunOn.LowByte 'Load the timer with new value

T1CON.0=1 'Restart the Clock

TMR1IF = 0 'Clear TMR1 int flag
'PIR1.0=0 'Reset TMR1's Interupt Flag (Not sure about this)


So you can see i intialise the timer for 250ms ticks. Then poll the flag. If it is set then I execute some code and then reinitialise the timer adding any overrun to the preload value.

retepsnikrep
- 15th July 2011, 08:51
I'm working on this and a bit confused by the 12F683 data sheet.

I don't want an interrupt (i.e. jump to some assembly level routine) I'm just polling the TMR1 overflow flag.


if PIR1.0 = 1 then T1Handler 'If Timer1 has overflowed then

So do i need to do the stuff below?




The Timer1 register pair (TMR1H:TMR1L) increments
to FFFFh and rolls over to 0000h. When Timer1 rolls
over, the Timer1 interrupt flag bit of the PIR1 register is
set. To enable the interrupt on rollover, you must set
these bits:
• Timer1 interrupt enable bit of the PIE1 register
• PEIE bit of the INTCON register
• GIE bit of the INTCON register
The interrupt is cleared by clearing the TMR1IF bit in
the Interrupt Service Routine.


I just want to clear the TMR1 overflow flag every time it overflows, load my 250ms preload value etc and carry on.

HenrikOlsson
- 15th July 2011, 09:34
> I just want to clear the TMR1 overflow flag every time it overflows, load my 250ms preload value etc and carry on.
Then that's all you need to do. The roll-over event will set the interrupt flag even if the actual interrupt enable bit and/or GIE bit isn't set. Just clear it, reload and you're good to go.

retepsnikrep
- 16th July 2011, 05:30
Thanks got the timer working now but have one more question.



T1CON.0 = 0 'Stops Timer

TMR1RunOn.Highbyte = TMR1H 'Load the Run-On (Over-Run) value (if any)
TMR1RunOn.Lowbyte = TMR1L 'Load the Run-On (Over-Run) value (if any)
TMR1RunOn = PreLoad + TMR1RunOn 'Calculate new Preload setting to include any timer overrun
TMR1H = TMR1RunOn.HighByte 'Load the timer with new value
TMR1L = TMR1RunOn.LowByte 'Load the timer with new value

PIR1.0 = 0 'Clear TMR1 int flag
T1CON.0 = 1 'Starts Timer


In the above code i stop the timer then work out any TMR1 overun and add it to my timer reload value.
But how do i compensate for the instructions above which clearly take some time to execute?
I must need to add a few more timer ticks to my reload value, but how many? My clock is running at 8mhz.

HenrikOlsson
- 16th July 2011, 07:44
You could just do it by trial and error, let it run for a while and see if and how much it drifts. Otherwise you need to dig into the generated .lst file and count the actual instructions. I'm guessing somewhere around 16 cycles.

Or, why not use a second timer (TMR0 etc) to actually time it. Stop TMR1, start TMR0, do the reload, stop TMR0, start TMR1. TMR0 will now give you your answer.

If you tick the timer with the main oscillator it matter if you run at 8kHz or 8MHz, a cycle is a cycle.

/Henrik.

retepsnikrep
- 17th July 2011, 08:36
I'm confused now by the relationship between the crystal/int osc at 8mhz and the various clocks :?

So at 8mhz with Fosc/4 & 1/8 prescaler timer1 is ticking at 250,000hz? OK I get that.

But the sytem instruction clock is operating at? 8mhz instruction cycles a second or Fosc/4 = 2mhz? or something else?

retepsnikrep
- 17th July 2011, 09:25
The asm listing shows these instructions.



MOVE?CT 000h, _T1CON??0
MOVE?BB TMR1H, _TMR1RunOn??HIGHBYTE
MOVE?BB TMR1L, _TMR1RunOn??LOWBYTE
ADD?WWW _PreLoad, _TMR1RunOn, _TMR1RunOn
MOVE?BB _TMR1RunOn??HIGHBYTE, TMR1H
MOVE?BB _TMR1RunOn??LOWBYTE, TMR1L
MOVE?CT 000h, _PIR1??0
MOVE?CT 001h, _T1CON??0


So how much to add to timer1 reload to compensate I wonder?
Looking at the data sheet these instructions all seem to need 1 cycle each? So I make that 8 cycles how much is that in TMR1 ticks?

HenrikOlsson
- 17th July 2011, 09:44
Hi,
You are correct, when using any other prescaler than 1:1 one instructioncycle is not equal to one timer tick.

If you're using 1:8 prescaler then the timer is incremented every 8th instructioncycle but it still doesn't matter if the Fosc is 8kHz or 8Mhz, the relationship between instructioncylce and timertick/count is still the same and that relationship is the prescaler ratio.

The problem with the ASM-listing that is generated is that it's not "true" ASM, those commands you have in your listing are macros which you then need to "expand" into the "real" ASM instructions. (Did you really find those instruction in the datasheet?) But if it does work out to 8 instructions and your prescaler is 1:8 then it equals exactly 1 timer tick.

/Henrik.