View previous topic :: View next topic |
Author |
Message |
nikin78
Joined: 20 Sep 2007 Posts: 11
|
EX_CCPMP.C Example |
Posted: Tue Oct 02, 2007 3:25 pm |
|
|
I am using the EX_CCPMP.C example to get the delay of a 60Hz square wave from falling edge to rising edge. I have the following setup in my code.
#include <18F4550.h>
#device ICD = TRUE
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
My problem is figuring out what my clock is running at so I can get the 60Hz delay time in seconds. I really don't understand what I need to do or understand to get the proper answer. I do know that my final delay time should be around 8ms. What is the first thing I should be looking at in the code to get this? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Oct 02, 2007 5:02 pm |
|
|
Timer1 is clocked at 1/4 of the oscillator frequency. With a 48 MHz
oscillator, Timer will run at 12 MHz. That's too fast to capture a pulse
with a duration of 8.333 ms.
12 MHz * .008333 = 99996 counts
The CCP (and Timer1) can only hold 65535. The count of 99996 is
too high, because the Timer1 clock speed is too high for the expected
pulse duration of 8.333 ms.
The solution is to slow down the Timer1 clock, by using a prescaler
when you setup the timer. Look in the 18F4550.H file to see the
available prescaler constants. |
|
|
Guest
|
|
Posted: Wed Oct 03, 2007 10:09 am |
|
|
So does this mean I have to change my #fuse PLL5 or CPUDIV? From the data sheet it looks like the prescalar is PLLDIV. Looking at the control register for Timer1 it looks like CPUDIV needs to change. |
|
|
Ttelmah Guest
|
|
Posted: Wed Oct 03, 2007 10:15 am |
|
|
No.
It means you change the divider for the clock feeding the Timer.
If you change the fuses, you alter the speed the whole processor is running at.
Look in the .h file for the processor, at the entries for 'setup_timer_1'.
Best Wishes |
|
|
nikin78
Joined: 20 Sep 2007 Posts: 11
|
|
Posted: Wed Oct 03, 2007 4:19 pm |
|
|
So this is what my code looks like now
#include <18F4550.h>
#device ICD = TRUE
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
long rise,fall,pulse_width;
#int_ccp2
void isr()
{
rise = CCP_1;
fall = CCP_2;
pulse_width = fall - rise; // CCP_1 is the time the pulse went high
} // CCP_2 is the time the pulse went low
// pulse_width/(clock/4) is the time
// In order for this to work the ISR
// overhead must be less than the
// low time. For this program the
// overhead is 45 instructions. The
// low time must then be at least
// 9 us.
void main()
{
printf("\n\rHigh time (sampled every second):\n\r");
setup_ccp1(CCP_CAPTURE_RE); // Configure CCP1 to capture rise
setup_ccp2(CCP_CAPTURE_FE); // Configure CCP2 to capture fall
setup_timer_1(T1_INTERNAL|T1_DIV_BY_4); // Start timer 1
enable_interrupts(INT_CCP2); // Setup interrupt on falling edge
enable_interrupts(GLOBAL);
while(TRUE) {
delay_ms(1000);
printf("\r%lu us ", pulse_width/4 );
}
}
So I changed setup of timer1 to
setup_timer_1(T1_INTERNAL|T1_DIV_BY_4);
and change CPUDIV4 back to CPUDIV1.
I think this is a stretch so correct me if im wrong.
using a 20MHz crystal I have setup my device to run at 48MHz because of my #fuses settings.
the 48MHz is divided by 4 because of the Fosc/4 leaving me with 12Mhz which is to fast for a 60Hz signal that i want to use. using the prescalar for Timer1 I can divide the clock speed by 4 using T1_DIV_BY_4. This gives me 3Mhz. when running my program pulse_width is 24560. If I divide by 3Mhz I get .0081867s which would be 8.1867ms.
Is this correct because I feel like im stretching and not truelly understanding this? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Oct 03, 2007 5:38 pm |
|
|
The timer is counting at 3 million counts per second. You got 24560
counts between edges of the signal. The math is:
Code: |
24560 clocks
----------------------- = .0081867 seconds = 8.1867 ms
3000000 clocks/second
|
|
|
|
|