Author Topic: [SOLVED] Using a PIC16F630, want to make use of timers.  (Read 2093 times)

0 Members and 1 Guest are viewing this topic.

Offline MrT123Topic starter

  • Contributor
  • Posts: 12
  • Country: gb
[SOLVED] Using a PIC16F630, want to make use of timers.
« on: August 22, 2017, 12:20:19 pm »
Ok, Im using a PIC16F630 with little experience in it. I need to incorporate some kind of delay into my code but have used actual delays till this point.
However, Ive come to understand that this will be quite inaccurate over long delays (a  pulse of 120ms followed by 10s of nothing is needed).
How would I go about using the timer? (Never used one before)

Thanks for any advice.
« Last Edit: August 23, 2017, 02:22:34 pm by MrT123 »
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 12852
Re: Using a PIC16F630, want to make use of timers.
« Reply #1 on: August 22, 2017, 01:00:22 pm »
Whatever you do wont be accurate unless you use an external crystal as the internal 4MHz oscillator only holds +/-1% accuracy  at 3.5V Vdd 25 deg C.  Over the normal Vdd range and temperatures above 0 deg C it will hold +/-2% degrading to +/-5% below 0 deg C or for the extended temperature range part, above 85 deg C.

Given an accurate oscillator, software delays cam be just as accurate as a hardware timer. The difficulty is keeping track of the small proportion of the CPU time used by other code in between calls to the delay routine.  This is only an issue when you require background long-period timekeeping to quartz crystal accuracy, for which a hardware timer is vastly preferable because it can be configured to increment autonomously.

A further complication is lost time when writing to a running timer.  When you write to a PIC timer, the prescaler is cleared so if you try to preload the timer in an ISR to get a 'nice' rate for your application timing (e.g a power of 10 fraction of a second) it will invariably loose time slightly.  That wont matter with a +/-2% oscillator, but if you need crystal accuracy, and you want to use a timer with a prescaler you need to let the timer free-run and cope with the fact the resulting rollover interrupt rate is a binary fraction of the clock speed. 

Your best bet is  to study the Gooligum Mid-Range PIC tutorials (free sample) (registration required for free download).  Its for a different PIC, and uses XC8 undrer MPLAB X, but the code to actually handle Timer 0 and its interrupt is pretty much the same for your PIC and the old version of HiTech C you are using.   The MPLAB 8 Simulator does a great job of simulating your PIC and the PIC12F629 used in the tutorials, including their hardware timers so you can check the code works as expected before porting it to your hardware.
 
The following users thanked this post: MrT123

Offline Bruce Abbott

  • Frequent Contributor
  • **
  • Posts: 627
  • Country: nz
    • Bruce Abbott's R/C Models and Electronics
Re: Using a PIC16F630, want to make use of timers.
« Reply #2 on: August 22, 2017, 05:10:01 pm »
How accurate do you need it to be? What else do you need the PIC to do during the delays?
 
The following users thanked this post: MrT123

Offline MrT123Topic starter

  • Contributor
  • Posts: 12
  • Country: gb
Re: Using a PIC16F630, want to make use of timers.
« Reply #3 on: August 22, 2017, 08:43:41 pm »
Thanks for your replies again guys. Glad to see you both again.

For further clarification,
I am using this PIC to time two different pulses of length 120ms and 500ms. Following a pulse, the system is to not allow any more pulses for a 10s period.

I am currently using delays with arbitrary values to get the rest of the system running. The next step before moving any further really is to get these timings done.
I do not need this PIC to do anything else during the delays which was in part the reason I just used delay functions to begin with. Would use of the internal timer be a lot more accurate? Is there a way to specify a time a delay function run for. I understand that the length of code itself will have an influence on the delay as well.

I do not have access to an external crystal so would prefer a method using the internal 4MHz oscillator would be preferable (if a delay would not be ideal).
This system will be used at room temperature so as I understand it according to Ian, the internal oscillator will have a +/- 1% accuracy.
This will be accurate enough for the purpose I am trying to achieve.

I'll also be looking at the Gooligum tutorials as suggests by Ian.

thanks again
« Last Edit: August 22, 2017, 08:48:35 pm by MrT123 »
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 12852
Re: Using a PIC16F630, want to make use of timers.
« Reply #4 on: August 22, 2017, 09:18:50 pm »
One approach would be to set up a timer to provide a regular 'tick' interrupt at approximately 1ms intervals.   The input to Timer 0 prescaler is Fosc/4, so if you set the prescaler to /4 and allow Timer 0 to free-run it will divide by (4*4*256), giving a period of 1.024 ms.

Then its just a matter of waiting for 117 'ticks' for the 120ms pulse, or 488 'ticks' for the 500ms pulse or 9766 'ticks' for the 10s gap.

You don't even need to write an ISR - The PIC sets its hardware interrupt flags even if that hardware interrupt is disabled so you can run a state machine in a superloop to sequence your outputs, respond to inputs etc. and at the bottom of the loop, poll the interrupt flag to wait for a timer rollover with:
Code: [Select]
while(!INTCONbits.T0IF); //Wait for rollover
INTCONbits.T0IF=0; //Clear rollover flag
As long as the execution time of the rest of the loop is under 1ms, it will always wait for the rest of the 1.024ms, and if it occasionally does go over 1ms it will catch up without slippage as long as the execution time for two consecutive passes of the loop never exceeds 2ms.

N.B if you want cycle accurate pulse generation, use a PIC with a CCP module.  That lets you sequence the edges from a CCP pin in hardware with resolution up to one instruction cycle. The sequencing can run in the background in an ISR.  You can sequence as many signals as you have CCP modules from the same free-running 16 bit timer. You do however need enough instruction cycles to prepare the next edge so edges closer than 50 instruction cycles on the same CCP module are problematic.  Unfortunately the PIC16F630 doesn't have a CCP module.
« Last Edit: August 22, 2017, 09:25:06 pm by Ian.M »
 
The following users thanked this post: MrT123

Offline MrT123Topic starter

  • Contributor
  • Posts: 12
  • Country: gb
Re: Using a PIC16F630, want to make use of timers.
« Reply #5 on: August 23, 2017, 09:01:07 am »
I've been trying to get my head around how you came at a period of 1.024ms.
This might be a tad tedious but could you explain it in a bit more detail.
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 12852
Re: Using a PIC16F630, want to make use of timers.
« Reply #6 on: August 23, 2017, 09:25:09 am »
The PIC16F1630 has a 4MHz INTOSC, lets suppose its spot on as the +/-1% makes a mockery of precise period calculations, or you could be using an external 4MHz crystal.

Fosc=4MHz

Timer 0 prescaler internal input is Fcy (the instruction clock). Fcy=Fosc/4

==> Fcy=1MHz

Set the prescaler to /4 and the clock source as internal:
Code: [Select]
OPTION_REGbits.T0CS=0;
OPTION_REGbits.PSA=0;
OPTION_REGbits.PS=0b001; // /4
==> Timer_0_increment_rate=1MHz/4=250KHz

Timer 0 is 8 bit so it wraps every 256 increments.
==> Timer_0_rollover_rate=250KHz/256
rearranging to get the period:

Timer_0_period=256/250KHz=1.024ms

« Last Edit: August 23, 2017, 09:26:48 am by Ian.M »
 
The following users thanked this post: MrT123

Offline MrT123Topic starter

  • Contributor
  • Posts: 12
  • Country: gb
Re: Using a PIC16F630, want to make use of timers.
« Reply #7 on: August 23, 2017, 02:21:50 pm »
Ah, makes a lot of sense. Everything works perfectly
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf