![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
picman62
Joined: 12 Dec 2014 Posts: 77
|
Timer1 in RC0 and RC1 |
Posted: Sat Jan 10, 2015 8:23 am |
|
|
Hello,
Beginner here.
I am using PIC 16F877A/20MHz. I am sending a PWM frequency from CCP1/RC2 pin .
I need to set pin RC0 to act as a counter and once this same frequency is received in this pin, RC1 will be set as comparator and light a LED if the frequency corresponds.
My question is if I can use TIMER1 simultaneously in RC0 and RC1 to perform the mentioned tasks or will I need to use TIMER0 in RC0 and TIMER1 in RC1?
Thanks. |
|
![](templates/subSilver/images/spacer.gif) |
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Sat Jan 10, 2015 9:48 am |
|
|
what you describe seems too vague for a useful answer.
At least by me.
what have you tried to do so far?
can you post the compilable code to show what you have done already
in pursuit of your goal?
that's a better starting point for a discussion that might actually help you . |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9176 Location: Greensville,Ontario
|
|
Posted: Sat Jan 10, 2015 4:08 pm |
|
|
While the details are fuzzy...
I'm thinking he's sending out the PIC a fixed frequency,say 5KHz. With the same PIC he wants to receive it, compute what it is, then turn on an LED to say 'yes !'.
if so , it's a tachometer with setpoint......and a freqgenny in one PIC. Can be broken down into 3 'sub programs'....
jay |
|
![](templates/subSilver/images/spacer.gif) |
picman62
Joined: 12 Dec 2014 Posts: 77
|
|
Posted: Sat Jan 10, 2015 4:39 pm |
|
|
asmboy, I am giving more details but I think temtronic has got the idea.
PIC will send out a frequency say 5Khz PWM. An external receiver will get that frequency and transmit. Then when it reaches RC0, RC1 as comparator will detect that it is the correct frequency and will light a LED.
My doubt is whether I can use TIMER1 at the same time in pins C0 and C1. Or if each pin will need its own timer configured for this function.
I am confused about this because I see that the PIC has two CCP modules and one is already being used for PWM with TIMER2. Since I need a comparator at RC1 and if it's not possible to use TIMER1 also in RC0 as frequency counter, I would need to use TIMER0 at this pin.
What is the best aproach and how to configure the timers?
Here is a code for frequency counter that I found in the internet. I have changed it to fit my purposes.
Code: | #include <16f877a.h>
#fuses hs,nowdt,nocpd,nolvp,noprotect
#use delay(clock=20M)
#include <LCD.c>
unsigned int16 value;
void main()
{
lcd_init();
while(1)
{
set_timer1(0);
setup_timer_1(t1_external | T1_DIV_BY_1);
delay_ms(1000);
setup_timer_1(T1_DISABLED);
value=get_timer1();
lcd_gotoxy(1,2);
printf(lcd_putc,"%LU HZ ",value);
}
}
|
I tested it in proteus simulator and I see that when I connect a signal generator either to RC0 or RC1, the LCD displays the correct frequency.
So, can I keep timer1 in C0 and program RC1 as comparator employing also timer1?
If so, how would I do it?
Thanks. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19375
|
|
Posted: Sun Jan 11, 2015 2:21 am |
|
|
If you look at the CCP modules in the data sheet, there is a nice little table listing 'Interaction of two CCP modules'.
One can capture, and one compare, but then the compare will reset the timer. So if the 'capture' needs to retrieve an unaffected count, how many times the 'compare' how occurred, times the compare value being checked for, will need to be added in to the count. So you have an interrupt on the compare, count how often this is called, and multiply this by the value you are putting into the compare register, then add this to the value retrieved from the 'capture' CCP.
To avoid having to do this, is why chips that have more 16bit timers (a lot of the newer PIC18's etc.), allow you to select timer 3 as well as timer 1, for the CCP modules. |
|
![](templates/subSilver/images/spacer.gif) |
picman62
Joined: 12 Dec 2014 Posts: 77
|
|
Posted: Sun Jan 11, 2015 4:23 am |
|
|
Thanks for your reply Ttelmah.
Let me see if I understood. You are saying that it is possible to use TIMER1 configured as 'capture' in RC0 and also configured as 'compare' in RC1, but this have a limitation of the counter being reset. Is that it?
But I don't know how troublesome this would become in my case.
Suppose RC0 happens to capture the intended frequency. RC1 as a comparator 'will tell' the chip to blink the led in this same pin. The led blinks. Then another signal comes through RC0 and this is not the intended frequency. Led does not blink.
You mention that "if the 'capture' needs to retrieve an unaffected count, how many times the 'compare' has occurred, times the compare value being checked for, will need to be added in to the count".
It's not clear to me if in the case of my example above the 'capture' will need to retrieve an unaffected count or not and if it does what trouble it would cause to sense if a given frequency in RC0 is the intendeded one or not.
Would this become a problem in my case?
Also, regarding the use of TIMER0 as a counter, what seems to be the case is that TIMER0 is 8 bits, thus limited to 256. So, it would be problematic to deal with frequencies above 1000Hz. But I found here in this forum an old post about timers in which is stated that TIMER0 can be set to 16bit mode. Is this true? If it is, and if the timer reset you mentioned is confirmed to cause problems to what I need the PIC to do, wouldn't be the case to use TIMER0 in RC0 as I first suggested?
At this moment the timer will reset and gets ready for another 'reading'? If this is what you mean, then I see no problem |
|
![](templates/subSilver/images/spacer.gif) |
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Sun Jan 11, 2015 7:23 am |
|
|
Quote: |
chips that have more 16bit timers (a lot of the newer PIC18's |
The 18F4525 is an example of an excellent PIC with
individual timers available for PWM1 and PWM2 as Ttelmah suggests.
Use Timer1 and Timer3 respectively.
the 18f4525 is pin for pin compatible with the 16f877.
It is the better way to proceed for your project.
It is also a lower priced part these days too, owing to the near obsolescent status of the '877. |
|
![](templates/subSilver/images/spacer.gif) |
picman62
Joined: 12 Dec 2014 Posts: 77
|
|
Posted: Sun Jan 11, 2015 3:22 pm |
|
|
Thanks for the suggestion asmboy, I will sure take a look at the 4525. But I remember I once knew of somebody who programmed the 16f877a for a similar purpose. He had C0 as counter and C1 as comparator. I don't know if he was using TMR0 and TMR1 or only TMR1. But his program worked. I completely lost contact with him.
I found an example of a counter in CCS. I am playing with the code to see if I can adapt it to my purposes. I will see what happens if I set TMR1 as comparator too to light that LED.
In the mean time if you or anybody have suggestions on how this could be accomplished I would appreciate.
Regards. |
|
![](templates/subSilver/images/spacer.gif) |
Eugeneo
Joined: 30 Aug 2005 Posts: 155 Location: Calgary, AB
|
|
Posted: Mon Jan 12, 2015 1:23 am |
|
|
Another way that comes to mind is to generate the 5khz signal.
Then read it back along with the questioned signal using an interrupt.
Take the count of both values over a certain time.
Calculate the difference between the two values with respect to the overall time.
If it fits within a tolerance it is good.
This method also acts as a filter / output stabilizer based on the time / tolerance. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19375
|
|
Posted: Mon Jan 12, 2015 2:27 am |
|
|
He almost certainly 'time multiplexed'.
Program CCP1 to do the sampling. Leave CCP2 disabled. Read your 'frequency' as you currently do. Then disable CCP1, and program CCP2 to do the measurement you want with this. Perform this measurement. Then disable CCP2, and go back to measuring the frequency. You do one job, then the other. This way there is no interference between the tasks.
He may also have done the frequency measurement the 'other way'. There are two fundamentally different ways of measuring frequency. The first is to count over time (as you currently do). The second is to measure the 'period' of just one or more pulse(s) of the incoming signal. If (for instance) your signal is 5KHz, and your CPU clock it 4MHz, then if you set CCP1 to 'capture' with an /16 prescaler, you will time (in FOSC/4 counts) how long just 16 pulses of the incoming signal take. Frequency is then (16*1000000)/count. The great advantage of this is that it is fast. Takes just 1/312.5 second to measure the frequency, and the accuracy is basically as good as for the count approach (resolution is 1:3200, against 1:5000).
You then switch to the second CCP, and measure the other signal. You can probably do both measurements quicker than your current approach.... |
|
![](templates/subSilver/images/spacer.gif) |
Eugeneo
Joined: 30 Aug 2005 Posts: 155 Location: Calgary, AB
|
|
Posted: Mon Jan 12, 2015 3:09 am |
|
|
I absolutely agree with you Ttelmah.
From the perspective of lighting a LED means to me, (and I am assuming here) that he is looking for an output that is visually noticeable. Just another option without too much math. |
|
![](templates/subSilver/images/spacer.gif) |
picman62
Joined: 12 Dec 2014 Posts: 77
|
|
Posted: Mon Jan 12, 2015 6:22 am |
|
|
I have found a way to send PWM without using the TMR2 module.
This is the code I employed:
Code: |
#include<16f877a.h>
#fuses nowdt
#use delay(clock=20M)
long value;
void main(void)
{
set_tris_c(0x00);
value=96;
while(true)
{
for (value=96; value<96; value+=96);
{
output_high(pin_c2);
delay_us (value);
output_low(pin_c2);
delay_us(value);
}
}
}
|
As a complete newbie in PIC programming, I do not know how correct or valid this is. But this gives me a stable 5005 Hz signal, according to the Proteus frequency counter I hooked in pin C2.
The number '96' was got from trial and error until the closest value to 5KHz was achieved. In this case 5005Hz.
Assuming the method I used to generate PWM is valid, what would be the aproach to get the exact 5KHz signal?
Also assuming this as valid, would it be ok now to use TMR1 as 'capture' in pin C0 and TMR2 as 'compare' in pin C1 and finally use two independent timers? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19375
|
|
Posted: Mon Jan 12, 2015 8:33 am |
|
|
You can't use timer2 for compare.
It's not really valid, since the frequency will get disturbed whenever you do anything else (measurements etc..).
Your PIC only has _one_ 16bit timer.
Timer1.
Timer2, is only 8bits, but gives 10bits for PWM.
Timer0, is only 8bit.
The CCP for capture or compare, uses a 16bit timer. Hence has to use Timer1.
So go back to your original use of the PWM, and time multiplex as already outlined. |
|
![](templates/subSilver/images/spacer.gif) |
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Mon Jan 12, 2015 8:57 am |
|
|
picman62 wrote: | I have found a way to send PWM without using the TMR2 module.
....
....
As a complete newbie in PIC programming, I do not know how correct or valid this is. But this gives me a stable 5005 Hz signal, according to the Proteus frequency counter I hooked in pin C2.
The number '96' was got from trial and error until the closest value to 5KHz was achieved. In this case 5005Hz.
Assuming the method I used to generate PWM is valid, what would be the aproach to get the exact 5KHz signal?
Also assuming this as valid, would it be ok now to use TMR1 as 'capture' in pin C0 and TMR2 as 'compare' in pin C1 and finally use two independent timers? |
Using either delay_us(xx) or delay_ms(xx) is NOT the way to generate accurate PWM signals.
Apart from any other consideration, the PIC is tied up totally to the task and can do nothing else.
Use the hardware PWM.
Don't fall into the trap of believing ISIS/Proteus.
I tested your code with MPLAB and got a slightly different frequency.
My experience with MPLAB is that it's quite good but can give minor timing discrepencies.
Test on real hardware for the truth.
You've already been pointed in a better direction.
Mike |
|
![](templates/subSilver/images/spacer.gif) |
picman62
Joined: 12 Dec 2014 Posts: 77
|
|
Posted: Mon Jan 12, 2015 9:43 am |
|
|
Hi all, thanks for all the answers. So as Ttelmah stated, this is not the correct way to do it. OK.
But I have just remembered one fact that might be relevant or not for this puzzle.
I am outputting PWM pulses that turns on and turns off in a loop. Is it possible to employ TMR2 IN RC0 for 'capturing' the external signal when PWM is off and finally get TMR1 in RC1 to make the 'compare'? |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|