[SOLVED] Using a PIC16F630, want to make use of timers.  - Page 1
Forum section: electronics / general

author: MrT123
author_rank: Contributor
timestamp: August 22, 2017, 12:20:19 pm
content: 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.

author: Ian.M
author_rank: Super Contributor
timestamp: August 22, 2017, 01:00:22 pm
content: 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 theGooligum 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.

author: Bruce Abbott
author_rank: Frequent Contributor
timestamp: August 22, 2017, 05:10:01 pm
content: How accurate do you need it to be? What else do you need the PIC to do during the delays?

author: MrT123
author_rank: Contributor
timestamp: August 22, 2017, 08:43:41 pm
content: 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

author: Ian.M
author_rank: Super Contributor
timestamp: August 22, 2017, 09:18:50 pm
content: 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:while(!INTCONbits.T0IF); //Wait for rolloverINTCONbits.T0IF=0; //Clear rollover flagAs 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.

author: MrT123
author_rank: Contributor
timestamp: August 23, 2017, 09:01:07 am
content: 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.

author: Ian.M
author_rank: Super Contributor
timestamp: August 23, 2017, 09:25:09 am
content: 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=4MHzTimer 0 prescaler internal input is Fcy (the instruction clock). Fcy=Fosc/4==>Fcy=1MHzSet the prescaler to /4 and the clock source as internal:Code:OPTION_REGbits.T0CS=0;OPTION_REGbits.PSA=0;OPTION_REGbits.PS=0b001; // /4==>Timer_0_increment_rate=1MHz/4=250KHzTimer 0 is 8 bit so it wraps every 256 increments.==>Timer_0_rollover_rate=250KHz/256rearranging to get the period:Timer_0_period=256/250KHz=1.024ms

author: MrT123
author_rank: Contributor
timestamp: August 23, 2017, 02:21:50 pm
content: Ah, makes a lot of sense. Everything works perfectly