|
|
View previous topic :: View next topic |
Author |
Message |
ritchie
Joined: 13 Sep 2003 Posts: 87
|
Help on Capture Module |
Posted: Sat Jun 25, 2005 12:25 am |
|
|
Hi,
I made a test program for my capture interrupt module using 18F452 at 20MHz clock.
To test it I simulated a waveform with 61 falling edge and 61 rising edge. I use CCP1 only and inputted to PortC2 of the MCU.
I encountered a problem maybe a latency issue or whatever.
What I need is your comment, maybe I miss something with my code.
The intention of the test program is to determine I really get the whole waveform with 61 falling and rising edge.
Below is my code:
Code: |
#int_timer1
void timer1_isr()
{
if (capstart == 1)
{
capstart = 0;
capend = 1;
fallcnt = BarCnt;
risecnt = SpaceCnt;
BarCnt = 0;
SpaceCnt = 0;
capmode = 0;
}
clear_interrupt(int_timer1);
}
#int_ccp1
void ccp1_isr()
{
if (capmode == 0)
{
capmode = 1;
BarCnt++;
}
else
{
capmode = 0;
SpaceCnt++;
}
if (barstart == 0)
{
barstart = 1;
}
// toggle edges
#asm
movlw 0x01
xorwf 0xFBD, F
#endasm
set_timer1(0);
clear_interrupt(int_ccp1);
}
void init_mcu(void)
{
lcd_init();
output_float(PIN_C2);
clear_interrupt(int_timer1);
clear_interrupt(int_ccp1);
setup_adc_ports(NO_ANALOGS); // setup PortA to digital I/O
setup_ccp1(CCP_CAPTURE_FE); // set CCP1 to falling edge capture
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
set_timer1(0);
enable_interrupts(int_timer1);
enable_interrupts(INT_CCP1);
enable_interrupts(global);
output_low(PIN_A0);
}
|
This is my main loop which capture the whole waveform with 61 falling and rising edges.
Code: |
main()
{
init_mcu();
lcd_gotoxy(1,1);
printf(lcd_putc,"Fall=%02U Rise=%02U",fallcnt,risecnt);
while (TRUE)
{
lcd_gotoxy(1,1);
printf(lcd_putc,"Fall=%02U Rise=%02U",fallcnt,risecnt);
}
}
|
And below is the modified main loop which does not capture the whole waveform... mean it does not get the 61 falling and rising edges.
Code: |
main()
{
init_mcu();
lcd_gotoxy(1,1);
printf(lcd_putc,"Fall=%02U Rise=%02U",fallcnt,risecnt);
while (TRUE)
{
if (barend == 1)
{
barend = 0;
lcd_gotoxy(1,1);
printf(lcd_putc,"Fall=%02U Rise=%02U",fallcnt,risecnt);
}
}
}
|
I need your help.
Thank you.
. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Jun 25, 2005 12:41 am |
|
|
What is the frequency of the waveform ?
Is the frequency constant, or does it change ?
What is the duration of the positive and the negative
portion of each cycle ? |
|
|
ritchie
Joined: 13 Sep 2003 Posts: 87
|
|
Posted: Sat Jun 25, 2005 3:23 am |
|
|
Hi PCM Programmer,
PCM programmer wrote: | What is the frequency of the waveform ? |
The frequency varies from 10Hz to 1KHz or from 1mSec. to 10mSec.
PCM programmer wrote: | Is the frequency constant, or does it change ? |
No, the frequency varies.
PCM programmer wrote: | What is the duration of the positive and the negative
portion of each cycle ? |
The input waveform is varying positive and negative pulse width. It ranges from 1mSec. to 10mSec.
How can I re-code my test code such that I can capture this pulse width ranges I mention above.
I'll appreciate any help.
Thank you and I appreciate your reply. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Jun 25, 2005 12:32 pm |
|
|
Have you looked at the CCS example file, EX_CCPMP.C ?
To solve your problem, I would use a program similar to that,
and I would save the pulse durations in an array. This would
be done inside the INT_CCP isr.
I would not display the pulse widths as they are captured. I would
wait until all the captures are done, and then display the contents of
the array. |
|
|
ritchie
Joined: 13 Sep 2003 Posts: 87
|
|
Posted: Sat Jun 25, 2005 8:04 pm |
|
|
Hi PCM programmer,
PCM programmer wrote: | Have you looked at the CCS example file, EX_CCPMP.C ?
To solve your problem, I would use a program similar to that,
and I would save the pulse durations in an array. This would
be done inside the INT_CCP isr.
I would not display the pulse widths as they are captured. I would
wait until all the captures are done, and then display the contents of
the array. |
I pattern my code from the CCS example file (EX_CCPMP.C).
I modified the code as per your suggestion and listed below:
Code: |
#int_timer1
void timer1_isr() // timer overflows at 104mSec.
{
if (capstart == 1)
{
capstart = 0;
capend = 1;
HighCnt = 0;
LowCnt = 0;
capmode = 0;
}
clear_interrupt(int_timer1);
}
#int_ccp1
void ccp1_isr()
{
if (capmode == 0)
{
//HighTable[HighCnt++] = get_timer1();
HighTable[HighCnt++] = CCP_1;
capmode = 1;
}
else
{
//LowTable[LowCnt++] = get_timer1();
LowTable[LowCnt++] = CCP_1;
capmode = 0;
}
if (capstart == 0)
{
capstart = 1;
}
#asm
movlw 0x01
xorwf 0xFBD, F
#endasm
set_timer1(0);
clear_interrupt(int_ccp1);
}
void init_mcu(void)
{
lcd_init(); // LCD should be initialized first
output_float(PIN_C2); // make CCP1 as input
clear_interrupt(int_timer1);
clear_interrupt(int_ccp1);
setup_adc_ports(NO_ANALOGS); // setup PortA to digital I/O
setup_ccp1(CCP_CAPTURE_FE); // set CCP1 to falling edge capture
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8); // 20M/(4*8*65536)
set_timer1(0);
enable_interrupts(int_timer1);
enable_interrupts(INT_CCP1); // enable CCP1 interrupt on falling edge
enable_interrupts(global); // enable global interrupt
output_low(PIN_A0);
}
void print_data(void)
{
int Idx;
printf("\r\n\r\n");
for (Idx=0; Idx<MAXIMUM_HIGH_LOW; Idx++)
{
if (Idx == 10)
printf("\r\n");
printf("%04X ",HighTable[Idx]);
}
printf("\r\n\r\n");
for (Idx=0; Idx<MAXIMUM_HIGH_LOW; Idx++)
{
if (Idx == 10)
printf("\r\n");
printf("%04X ",LowTable[Idx]);
}
}
|
And my main loop
Code: |
main()
{
capstart = 0;
capend = 0;
capmode = 0;
HighCnt = 0;
LowCnt = 0;
init_mcu();
clear_HighLow_buffers();
while (TRUE)
{
if (capend == 1)
{
capend = 0;
print_data();
}
}
}
|
My PIC configuration
Code: |
#include <18F452.H> // Target MCU Chip
#device *=16 // 16-Bit Pointer
#fuses HS,NOPROTECT,NOWDT,NOLVP,NOPUT // PIC MCU Configuration
#use delay(clock=20000000) // 20MHz Crystal clock speed
#use rs232(baud=115200, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8, errors)
|
When the captured data is printed thru RS232 I get zero values which in correlation to the count of the number of high and low pulses as provided in the previous listed code.. it does not get the whole waveform and the count for fall and rise is not 61 edges.
I need your suggestion and help.
Thanks.
Last edited by ritchie on Sun Jun 26, 2005 5:43 am; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jun 26, 2005 1:21 am |
|
|
I have no idea what you're doing or what your overall purpose is,
but here's some code I just did, that makes a little mini-logic analyzer.
I did all this on a PicDem2-Plus board. I connected pins C1 and C2
together, and also connected them to pin B1. Pins C1 and C2 are
CCP2 and CCP1. I created a test waveform on pin B1 by using
for() loops with delay_ms() statements in them.
The output of the program is shown below. The first few cycles of the
input waveform have a nominal 2 ms period. The program shows it
as 2.157 ms. The program is probably accurate.
So hopefully this will help. If not, then you need to design it
yourself. I don't want to do your project for you.
Code: |
Cycle Positive
Period Half-cycle
# (us) Width (us)
1 2157 1026
2 2157 1026
3 2157 1026
4 2157 1026
5 2157 1026
6 2157 1026
7 2157 1026
8 2157 1026
9 2157 1026
10 2163 1032
11 5185 2539
12 5185 2539
13 5185 2539
14 5185 2539
15 5185 2539
16 5185 2539
17 5185 2539
18 5185 2539
19 5185 2539
20 5191 2545
21 10157 5026
22 10157 5026
23 10157 5026
24 10157 5026
25 10157 5026
26 10157 5026
27 10157 5026
28 10157 5026
29 10157 5026 |
Code: | #include <16F877.H>
#device *=16
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#byte PIR1 = 0x0C
#bit CCP1IF_BIT = PIR1.2 // CCP1 interrupt flag bit
int16 rise;
int16 fall;
int16 old_rise;
int16 period;
int16 rise_data[30];
int16 fall_data[30];
int16 period_data[30];
int8 index = 0;
#INT_CCP1
void ccp1_isr(void)
{
rise = CCP_1;
fall = CCP_2;
period = rise - old_rise;
// Collect data until the data buffers are full.
// The buffers only have room for 30 samples.
if(index < 30)
{
rise_data[index] = rise;
fall_data[index] = fall;
period_data[index] = period;
index++;
}
old_rise = rise;
}
//========================
void main()
{
int8 i;
output_low(PIN_B1);
setup_ccp1(CCP_CAPTURE_RE);
setup_ccp2(CCP_CAPTURE_FE);
set_timer1(0);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
CCP1IF_BIT = 0;
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);
// Create a waveform for the CCP's to capture.
for(i = 0; i < 10; i++)
{
output_high(PIN_B1);
delay_ms(1);
output_low(PIN_B1);
delay_ms(1);
}
for(i = 0; i < 10; i++)
{
output_high(PIN_B1);
delay_us(2500);
output_low(PIN_B1);
delay_us(2500);
}
for(i = 0; i < 10; i++)
{
output_high(PIN_B1);
delay_ms(5);
output_low(PIN_B1);
delay_ms(5);
}
//------------
// Display the data that we captured.
printf(" Cycle Positive\n\r");
printf(" Period Half-cycle\n\r");
printf(" # (us) Width (us)\n\r");
for(i = 1; i < 30; i++)
{
printf("%2u %5lu %5lu\n\r", i, period_data[i],
rise_data[i] - fall_data[i]);
}
while(1);
} |
Edited on June 26, 2005 to add a test to see if the data buffers
are full, before putting more data in them. Also fixed typos.
Last edited by PCM programmer on Sun Jun 26, 2005 3:48 pm; edited 1 time in total |
|
|
ritchie
Joined: 13 Sep 2003 Posts: 87
|
|
Posted: Sun Jun 26, 2005 5:38 am |
|
|
Hi PCM programmer,
I got the hardware working now... I am using the second post of my code which capture the high/low pulses and store it to an allocated buffers just what you've mention in this thread.
damn cables....
Once I complete the hardware design and the code... I'll share it to this forum.
thank you for your patience. |
|
|
|
|
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
|