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

capture mode in pic18F13K22

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



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

capture mode in pic18F13K22
PostPosted: Mon Jul 10, 2017 2:41 am     Reply with quote

Earlier I used capture mode with pic18F2520. It was working good. For some reasons, I have to change the controller to 18F13K22.

Using Internal oscillator.

I tried to debug the code using Pickit3. Though i don't apply any frequency, the tm3_variable is not zero. Any help please.

Code:
 
#include "18f13k22.h"
#FUSES INTRC_IO, PLLEN
#use delay(clock = 64000000)

#BYTE INTCON       = 0xFF2
#BYTE TMR0H       = 0xFD7
#BYTE TMR0L       = 0xFD6
#BYTE TRISB        = 0xF93
#BYTE PORTA        = 0xF80
#BYTE PORTB       = 0xF81
#BYTE PORTC      = 0xF82
#BYTE T3CON        = 0xFB1
#BYTE TMR3H        = 0xFB3
#BYTE TMR3L        = 0xFB2
#BYTE T0CON       = 0xFD5

#BIT    TMR0IF       = INTCON.2
#BIT    TMR0IE       = INTCON.5
#BIT    TMR0ON     =  T0CON.7
#BIT   TMR3ON  = T3CON.0

#define CAL_LED1   PIN_C7      // Material Present Status

#define LED1   PIN_C0         // Relay LED status

#define MAX_SAMPLE    100                // Sets No of period samples

// Variable Declaration
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;
float capacitance, disp_value;

unsigned int16 delay_ms_flag = 0;
unsigned int16 seconds;
unsigned int seconds1 = 0;

int1 flag_500ms = 0, flag1_500ms = 0;

unsigned int16 flag = 0;
unsigned int16 tm3_Variable;

float read_capacitance();
void timer0_init();

#int_ccp1
void ccp1_isr()
{
   new_ccp_value = CCP_1;      // captures the timer value
   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
   }
}

#INT_TIMER0
void timer0_isr()
{
   if(TMR0IF == 1)
   {
      delay_ms_flag++;   // increment variable
      seconds++;
      flag++;            // increment variable
      
      if(flag >= 500)      // for 500 ms
      {
         flag_500ms = 0;     
      }
      
      if(flag >= 1000)   // for 1second
      {
         flag = 0;      // reset variable to 0
         flag_500ms = 1;
      }
      
      if(seconds >= 1000)      // every 1 second
      {
         seconds = 0;
         SECONDS1++;         // Variables are incremented
      }
      
      TMR0IF = 0;         // clear flag
      TMR0IE = 1;         // enable interrupt
      
      TMR0H = 0xC1;      // 1ms for 64Mhz
      TMR0L = 0x7F;
      
   }
}


void main()
{
   
   TRISB = 0b01110000;
   
   PORTA = 0;      // configure PORTA as low
   PORTB = 0;      // configure PORTB as low
   PORTC = 0;
   
   setup_adc_ports(NO_ANALOGS|VSS_VDD);   
   setup_adc(ADC_OFF|ADC_TAD_MUL_0);
   
   setup_comparator (NC_NC_NC_NC);                 //   Disable comparator 
   
   setup_ccp1(CCP_CAPTURE_RE);                     //   Looks for Rising edge
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);       //   Timer1 internal & 1:1 Prescaler
   
   timer0_init();                                  //   Timer0 Initialization
   
   enable_interrupts(INT_CCP1);                   //   enables the CCP2 Interupt
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);                     //   Enables global interrupt
   
   T3CON = 0b10000110;                        //   16 bit, external clock input, TMR3 OFF
   
   while(1)
   {   
      TMR3H = 0;         // Values are reset to 0
      TMR3L = 0;
      TMR3ON = 1;         // Timer 3 ON
      delay_ms(10);      // 10 ms delay
      TMR3ON = 0;         // Timer 3 OFF
      tm3_Variable = TMR3H << 8 | TMR3L;      // Get the values
      
      if(tm3_Variable == 0)      // if the values are 0
      {        
         output_low(CAL_LED1);
         delay_ms(50);
         
         output_high(CAL_LED1);
         delay_ms(50);
         
         TMR3H = 0;         // Values are reset to 0
         TMR3L = 0;
         
         output_low(LED1);
      }
      
      else
      {
         read_capacitance();         //   Read the capacitance.
         disp_value = capacitance;

         if(flag_500ms == 0)
            output_high(CAL_LED1);

         else if(flag_500ms == 1)
            output_low(CAL_LED1);
      }
   }
}

float read_capacitance()
{
   total_period = 0;                        // Ensure variables are reset
   sample = 0;                              //   
   
   while (sample<(MAX_SAMPLE+1)){}                // waits here 'til done sampling
   
   frequency = (int32)((16000000*MAX_SAMPLE)/(total_period));      // calculates the frequency which is non-linear ,
   
   capacitance = 2467917.077/frequency;      // frequency converted to capacitance. to make it linear
   
   return capacitance;
}

void timer0_init()
{   
   T0CON = 0b00001000;      // 16 bit, prescaler not assigned
   
   TMR0H = 0xC1;      // 1ms for 64Mhz
   TMR0L = 0x7F;
   
   TMR0ON = 1;               // Timer1 ON
   TMR0IF = 0;               // set Timer1 Interrupt Flag as zero
   TMR0IE = 1;               // Set Timer1 Interrupt Enable = 1   
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jul 10, 2017 10:35 am     Reply with quote

Run a 1 Hz LED blink test. I suspect that your PIC is not really running
at 64 MHz. There may be other problems, but that one should be
checked first.
hemnath



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

PostPosted: Mon Jul 10, 2017 9:31 pm     Reply with quote

Thank you. I used the same code to test the LED blinking. By applying the frequency input, the main code goes into else statement where it has a blinking of LED for 500 ms. It is working.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jul 10, 2017 9:57 pm     Reply with quote

So is your whole program now working correctly, or is just the LED part
working ? Do you still have a problem ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Tue Jul 11, 2017 6:52 am     Reply with quote

Some comments on just one routine:
Code:

#INT_TIMER0
void timer0_isr()
{
   if(TMR0IF == 1)
   //Pointless. Wasted instructions. The interrupt handler is only
   //called if the interrupt flag _is_ set....

   {
      delay_ms_flag++;   // increment variable
      seconds++;
      flag++;            // increment variable
     
      if(flag >= 500)      // for 500 ms
      {
         flag_500ms = 0;     
      }
     
      if(flag >= 1000)   // for 1second
      {
         flag = 0;      // reset variable to 0
         flag_500ms = 1;
      }
     
      if(seconds >= 1000)      // every 1 second
      {
         seconds = 0;
         SECONDS1++;         // Variables are incremented
      }
     
      TMR0IF = 0;         // clear flag
      //Pointless. The compiler will always clear the flag for you
      //unless you specify for it not to...
      TMR0IE = 1;         // enable interrupt
      //Pointless. How can the code get here unless the interrupt
      //is already enabled....
     
      TMR0H = 0xC1;      // 1ms for 64Mhz
      TMR0L = 0x7F;
      //These values should be loaded ASAP in the routine.     
   }
}

//So lets do the same routine using the compiler...
#define TIMER0_PRELOAD 0xC17F

#INT_TIMER0
void timer0_isr(void)
{
    set_timer0(TIMER0_PRELOAD); //set the timer
    delay_ms_flag++;   // increment variable
    seconds++;
    flag++;            // increment variable
     
    if(flag >= 500)      // for 500 ms
    {
        flag_500ms = 0;     
    }
     
    if(flag >= 1000)   // for 1second
    {
       flag = 0;      // reset variable to 0
       flag_500ms = 1;
    }
     
    if(seconds >= 1000)      // every 1 second
    {
       seconds = 0;
       SECONDS1++;         // Variables are incremented
    }
}

However 'think again'. Why not use timer2?.

Set this to use the /16 prescaler. Count to 250 (249 in PR2), and to interrupt every fourth time. Result, an accurate 1mSec interrupt.

setup_timer_2(T2_DIV_BY_16,249,4); //16MHz/(16*250*4) = 1000Hz

No need to load timer values etc..

Now another comment. The 32bit value being reset in the read routine "total_period=0". What happens if an interrupt occurs during this load?...

For any variable larger than 8bit, that is externally and is changed inside an interrupt, you need to disable interrupts during the load.

Now, like PCM_programmer, I'm surprised if your chip really is clocking correctly at 64MHz. A bit of a fluke. Use this syntax:

Code:

#use delay(INTERNAL = 64MHz)
#FUSES INTRC_IO


The 'internal' setting ensures the compiler sets up the PLL, and selects the 16MHz clock branch and PLL. Having the INTRC_IO fuse _after_ this, then ensures the IO pin is set correctly as well.
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