CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Help on Capture Module

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ritchie



Joined: 13 Sep 2003
Posts: 87

View user's profile Send private message

Help on Capture Module
PostPosted: Sat Jun 25, 2005 12:25 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jun 25, 2005 12:41 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jun 25, 2005 3:23 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jun 25, 2005 12:32 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jun 25, 2005 8:04 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jun 26, 2005 1:21 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jun 26, 2005 5:38 am     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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