View previous topic :: View next topic |
Author |
Message |
hemnath
Joined: 03 Oct 2012 Posts: 242 Location: chennai
|
Strange problem with CCP2 pin |
Posted: Sat Mar 01, 2014 2:30 am |
|
|
Hi, I'm using PIC18F2520. CCS: 4.114, Clock: 12 Mhz.
I'm measuring the frequency on pin CCP2 and displaying the value on LCD.
Problem faced: it doesn't display the frequency value on LCD.
Now i have measured the frequency using CCP1. frequency value is displayed on LCD. But i want to read the frequency using CCP2. How to do that? Below is the sample code. Please help. Anything missing?
Code: | #include "18F2520.h"
#fuses HS
#use delay(clock=12000000)
#define RS PIN_B4
#define EN PIN_A5
void lcd_init();
void lcd_cmd(unsigned char);
void lcd_data(unsigned char);
void disp_cmd(unsigned char);
void disp_data(unsigned char);
#define MAX_SAMPLE 100 // Sets No of period samples
unsigned int8 sample = 0; // Current sample
unsigned int32 total_period; // Total period count in machine cycles
unsigned int16 new_ccp_value; //
unsigned int16 old_ccp_value; //
unsigned int16 new_period_value; // latest period value = difference between ccp values
unsigned int16 frequency;
#int_ccp2
void ccp2_isr(void)
{
new_ccp_value = CCP_1;
if ((sample > 0)&&(sample<MAX_SAMPLE+1)) // Ignores sample zero!
{
new_period_value = new_ccp_value - old_ccp_value; //
total_period+=new_period_value; //
}
old_ccp_value = new_ccp_value; // ready for next sample
if (sample < (MAX_SAMPLE+1)) // stops overflow when done
{
sample++; // Increment the variable
}
}
void main()
{
unsigned int16 value;
set_tris_c(0b00000010); // C1 - input
lcd_init();
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); // Timer1 internal & 1:1 Prescaler
setup_ccp2(CCP_CAPTURE_RE); // Looks for Rising edge
//clear_interrupt(INT_CCP1); // disables the CCP1 interrupt
enable_interrupts(INT_CCP2); // enables the CCP1 Interupt
enable_interrupts(GLOBAL); // Enables global interrupt
while(1)
{
value = 112;
disp_cmd(0x80);
printf(disp_data, "%lu", value);
delay_ms(1000);
total_period = 0; // Ensure variables are reset
sample = 0; //
while (sample<(MAX_SAMPLE+1)){} // waits here 'til done sampling
frequency = (int32)((3000000*MAX_SAMPLE)/(total_period));
disp_cmd(0x80);
printf(disp_data, "%lu", frequency);
delay_ms(1000);
}
}
void lcd_init()
{
disp_cmd(0x02); // To initialize LCD in 4-bit mode.
disp_cmd(0x20); // To initialize LCD in 1 lines, 5x7 dots and 4bit mode.
disp_cmd(0x0C);
disp_cmd(0x01);
disp_cmd(0x06);
disp_cmd(0x80);
}
void lcd_cmd(unsigned char c)
{
output_b(c);
output_low(RS);
output_high(EN);
delay_ms(15);
output_low(EN);
}
void lcd_data(unsigned char z)
{
output_b(z);
output_high(RS);
output_high(EN);
delay_ms(15);
output_low(EN);
}
void disp_cmd(unsigned char cmd_value)
{
unsigned char cmd_value1;
cmd_value1 = ((cmd_value>>4) & 0x0F); // Shift 4-bit and mask
lcd_cmd(cmd_value1); // Send to LCD
cmd_value1=(cmd_value & 0x0F);
lcd_cmd(cmd_value1); // Send to LCD
}
void disp_data(unsigned char data_value)
{
unsigned char data_value1;
data_value1 = ((data_value>>4) & 0x0F);
lcd_data(data_value1);
data_value1=(data_value & 0x0F);
lcd_data(data_value1);
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19516
|
|
Posted: Sat Mar 01, 2014 2:36 am |
|
|
You are reading the value from CCP1, in the CCP2 ISR..... |
|
|
hemnath
Joined: 03 Oct 2012 Posts: 242 Location: chennai
|
|
Posted: Sat Mar 01, 2014 2:44 am |
|
|
Im measuring the period for every rising edge. That's why i'm reading the CCP_1 value.
new_ccp_value = CCP_1;
in the CCS example, it is given like this,
rise = CCP_1; //CCP_1 is the time the pulse went high
fall = CCP_2; //CCP_2 is the time the pulse went low |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19516
|
|
Posted: Sat Mar 01, 2014 4:16 am |
|
|
In the example you refer to, they use both CCP's (same signal connected to both), with one programmed to record the rising edge, and one programmed to record the falling edge. Then on the second edge, both times are available, to give the pulse width.
You are using CCP2, so you need to be reading CCP2. You can't do pulse width with one CCP, but you can do period (which is what you need for frequency). Since it is the CCP2 pin you are using, it is the CCP2 counter you need to read.
Without a signal connected to the CCP1 input, and CCP1 programmed, the value read from CCP1, is 'meaningless' (garbage at boot up), hence the reading does nothing..... |
|
|
hemnath
Joined: 03 Oct 2012 Posts: 242 Location: chennai
|
|
Posted: Sat Mar 01, 2014 4:48 am |
|
|
Thanks for the reply.
I'm not reading the pulse width of the signal. I just mentioned that CCP_1 will read the time period for the pulse went high.
I'm reading the period of the pulse.
In my CCP2 isr,
i have done something like
new_ccp_value = CCP_1;
is this right? or else how to capture the period value for CCP2?
Please help. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19516
|
|
Posted: Sat Mar 01, 2014 4:53 am |
|
|
new_ccp_value = CCP_2;
Note the 2.... |
|
|
hemnath
Joined: 03 Oct 2012 Posts: 242 Location: chennai
|
|
Posted: Sat Mar 01, 2014 4:58 am |
|
|
Great help. Thanks it is working. |
|
|
|