View previous topic :: View next topic |
Author |
Message |
Guest
|
Using 1 timer for several purposes...... |
Posted: Sat Oct 11, 2008 7:48 pm |
|
|
Hi,
I want to use a 10F206 in a new project. The PIC will read the pulse width of an R/C receiver output (1.0 to 2.0 mS), and switch one output depending on the received pulse width. Concurrently, the PIC will blink an LED connected to another output. There is only one timer (TMR0) on this PIC, so I'm not sure how I can do both functions simultaneously?
Dave |
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Sat Oct 11, 2008 8:10 pm |
|
|
Let the timer run freely and toggle the led when it overflows.
If this pic has an interrupt on change pin, use it to sample the timer every time the pin changes it state. Keep the current and last timer readings and calculate the delta time between the events. |
|
|
Rohit de Sa
Joined: 09 Nov 2007 Posts: 282 Location: India
|
|
Posted: Sun Oct 12, 2008 5:04 am |
|
|
If the blinking of the Led is not time critical, you could simply put it into an endless while(true) loop. Since the '206 doesn't have an external interrupt pin you would need to constantly poll for the status of the input pin. Algorithmically:
Code: |
Check if pin is high, else skip this.
{
Start timer0.
Keep polling the pin for the negative going edge.Stop the timer when this edge is received.
Check the value of timer0 and accordingly turn on other Leds.
} |
This will introduce a delay in your 'status' Led flashing, but only about a 2ms delay. This won't really, matter much to the 'status' Led. Do note that this is very simple code, and if your servo pulse stays high it will put the PIC into a stall.
Rohit |
|
|
John P
Joined: 17 Sep 2003 Posts: 331
|
|
Posted: Sun Oct 12, 2008 6:58 am |
|
|
An alternative might be to set the timer running, but don't allow an interrupt. Instead, just check the interrupt flag in the main loop; you could use interrupts, but there's a time penalty for doing it, and you don't really need to do it that way. Say the timer is running so it wraps at a 10KHz rate.
Code: |
Check to see if clock has ticked, else loop.
{
Clear clock INT flag.
Check input pin.
If pin is high,
increment counter.
If pin is low, and counter is nonzero,
If counter exceeds threshold,
Set output high.
Else
Set output low.
Set counter to zero.
Increment second counter for blinking and set output accordingly, but that's an easy job.
}
|
|
|
|
Rohit de Sa
Joined: 09 Nov 2007 Posts: 282 Location: India
|
|
Posted: Sun Oct 12, 2008 7:57 am |
|
|
Just to inform everyone on this thread: the 10F206 does NOT have interrupt capability. No PIR or PIE registers, heck, no interrupt vector! It is a very low cost device.
Rohit |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Oct 12, 2008 8:31 am |
|
|
Quote: |
I'm not sure how I can do both functions simultaneously?
------
The 10F206 does NOT have interrupt capability. No PIR or PIE registers, heck, no interrupt vector.
|
This thread has sample code that may help:
http://www.ccsinfo.com/forum/viewtopic.php?p=101541 |
|
|
John P
Joined: 17 Sep 2003 Posts: 331
|
|
Posted: Sun Oct 12, 2008 9:48 pm |
|
|
I didn't realize that the processor is that minimalist!
As PCMP said in that linked thread, you'd have to use the top bit of the timer register to determine whether it has "ticked". And there would need to be an additional flag to record the previous state of the highest bit. So if the previous state was 0 and the present state is 1, you register a timer event. Still pretty straightforward.
Oops, I just checked and the counter would only wrap about 4000 times a second. That doesn't give much flexibility in checking an incoming pulse width that varies 1msec total. Better use bit 5 or bit 4 of the counter, which doubles or quadruples the rate.
Untested code, worth what you pay for it:
Code: |
while(1)
{
if (!bit_test(tmr0, 5))
{ // Bit is high?
last_hibit = 0; // No
continue;
}
if (last_hibit) // Bit newly went high?
continue; // No
last_hibit = 1; // We come here 1000000/64 times/second = 15625
if (bit_test(input_pin))
pwm_count++; // This mustn't reach 256!
else if (pwm_count)
{
if (pwm_count > threshold)
bit_set(output_pin);
else
bit_clear(output_pin);
pwm_count = 0;
}
// Blinking light omitted
}
|
|
|
|
|