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 support@ccsinfo.com

PIC LOWER FREQ. READING PROBLEM
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
POPE19



Joined: 27 Jun 2017
Posts: 71

View user's profile Send private message

PIC LOWER FREQ. READING PROBLEM
PostPosted: Mon Nov 27, 2017 7:22 am     Reply with quote

I am using pic16f914 for the speedo application. I have an older hardware and code working perfectly fine. My application is to determine a speed ranging from 0.5mph - 37hz to 99mph- 7.34khz --> Higher limit is not so important for application point of view.

Calculation for Speed is 1MPH = 74 Hz.

The old Hardware was using a 2digit 7 segment LED Display module (Digikey Part No : - 160-1536-5-ND). the Speedo Signal is feed to OPAMP 6002 (Open Loop Config) & output of the OPAMP is connected to CCP1 Pin -43 of PIC. My newer hardware is all same except the Display module is replaced by custom LCD which is driven by LCD Driver of a PIC.

The problem is with the same chunk of code for speed the PIC doesn't display anything until 208Hz. (2.8 MPH) and after that if i reduce the frequency it will display up to 1.3 miles (99 Hz.) on lower end and then displays 00 on LCD. The Signal I/P Circuit is same but why i am having trouble with this hardware ?

I am using 5v Peak to Peak Square wave signal from BK Precision 4084 as a signal source at Speed Input. I am using CCS PCWH Compiler 5.074.

My Code for Old Hardware is

Code:

#include <16F914.h>
#device ADC=10
#fuses HS, MCLR, NOWDT, PUT, NOIESO, BROWNOUT, NOFCMEN
#use delay(clock=20000000)


#define INTS_PER_QUARTER_SECOND     19      // (20000000/4*(4*256*256))

int int_count=INTS_PER_QUARTER_SECOND;

int count0 = 0;
int count1 = 0;

long speed = 0;
long newspeed = 0;

long time_delay = 0;

int capture_interrupt = 0;
int capture_ready = 0;
short capture_stable = false;
float Frequency = 0;

long MPH_KmPH_mode;
short MPH_KmPH_status;

#int_rtcc               //This function is called

//============================================================================//
void clock_isr()
{                         //every time the RTCC (timer0)
                          //overflows (255->0)
                          //For this program this is apx
                          //31 times per second.

   if(--int_count==0)
   {
     time_delay ++;
     int_count=INTS_PER_QUARTER_SECOND;
   }
}
//============================================================================//
// Timer 1 extend to 32 bit timer

#priority CCP1, TIMER1
#priority CCP2, TIMER1

//============================================================================//
// note:                                                                      //
// * = changed because of compiler update have made changes to work           //
// with pointers to solve ANSI issue.                                         //
//============================================================================//
//#define BytePtr(var, offset) (char *)(&(char *)var + offset)
#define BytePtr(var, offset) (char *)((char *)&var + offset)  // * refer NOTE

#byte PIR1 = 0xF9E
#bit TMR1IF = PIR1.0

int gc_timer1_extension = 0;       
int32 g32_ccp_delta;

//============================================================================//

#int_timer1
void timer1_isr()
{
   gc_timer1_extension++;
}
//============================================================================//
int32 current_ccp = 0;

int32 current_ccp_delta = 0;

//============================================================================//
#int_ccp1
void ccp1_isr()
{
   capture_interrupt = 0;
   MPH_KmPH_status = True;      // MPH mode
 
   char timer_ext_copy;
   
   static int32 old_ccp = 0;
   
   current_ccp = (int32)CCP_1;
   
   timer_ext_copy = gc_timer1_extension;
   
   if (TMR1IF)
   {
      if (make8 (current_ccp, 1) < 2)  // * refer NOTE
         timer_ext_copy++;
      gc_timer1_extension++;
      TMR1IF = 0;
   }
   
   make8 (current_ccp, 2) = timer_ext_copy;  // * refer NOTE
   
   g32_ccp_delta = (current_ccp > old_ccp) ? current_ccp - old_ccp : current_ccp
                     + (0x1000000 - old_ccp);               
   
   old_ccp = current_ccp;
   
}       

//============================================================================//
#int_ccp2
void ccp2_isr()
{
   capture_interrupt = 0;
   MPH_KmPH_status = False;      // KmPH mode
   
   char timer_ext_copy;
   
   static int32 old_ccp = 0;
   
   current_ccp = (int32)CCP_2;
   
   timer_ext_copy = gc_timer1_extension;
   
   if (TMR1IF)
   {
      if (make8 (current_ccp, 1) < 2)  // * refer NOTE
         timer_ext_copy++;
      gc_timer1_extension++;
      TMR1IF = 0;
   }
   
   make8 (current_ccp, 2) = timer_ext_copy;  // * refer NOTE
   
   g32_ccp_delta = (current_ccp > old_ccp) ? current_ccp - old_ccp : current_ccp
                     + (0x1000000 - old_ccp);               
   
   old_ccp = current_ccp;
   
}       
//============================================================================//

void Speed_Cal ()
{
   if (capture_interrupt == 0)
         capture_ready ++;
         
   if (capture_ready >= 10)
   {
      capture_stable = true;
      capture_ready = 10;
   }
   
   if (capture_interrupt >= 10)
   {
      capture_stable = false;
      capture_interrupt = 10;
      capture_ready = 0;
   }
   
   capture_interrupt ++;
   
   if (capture_stable == true)
   {
      current_ccp_delta = g32_ccp_delta;
   }
   else
      current_ccp_delta = 0;
     
   //current_ccp_delta = g32_ccp_delta;
   //=========================================================================//
   // Frequency = (Fosc/4)/(Timer1_Prescale * time interval)                  //
   //=========================================================================//
   
   Frequency = (1250000 + (current_ccp_delta >> 3))*100 / current_ccp_delta;
                                                   // x100 to get 2 decimal
                                                   
   // 1MPH = 74Hz or 0.1MPH = 7.4Hz   application requirement
   if (MPH_KmPH_status == True)  // MPH mode
   {
      newspeed = Frequency/740;  // newspeed = 0.1 MPH,
                                 // /100 to get back 2 decimal
     
      if (newspeed < 5)
         newspeed = 0;
   }
   if (MPH_KmPH_status == False) // KmPH mode
   {
      newspeed = Frequency/740;  // newspeed = 0.1 MPH,
                                 // /100 to get back 2 decimal
      newspeed = newspeed*1.6093; // MPH to KMPH
     
      if (newspeed < 8)
         newspeed = 0;
   }
}

//============================================================================//

void digit1(int temp_count)
 {
   switch (temp_count)
    {
      case 0:
          //output_d (0xc0);          // Zero
          output_high (PIN_D0);
          output_high (PIN_D1);
          output_high (PIN_C6);
          output_high (PIN_D3);
         
          output_high (PIN_D4);
          output_high (PIN_D5);
          output_low  (PIN_D6);
          output_low  (PIN_D7);
          break;
      case 1:
          //output_d (0xf9);          // One
          output_low  (PIN_D0);
          output_high (PIN_D1);
          output_high (PIN_C6);
          output_low  (PIN_D3);
         
          output_low (PIN_D4);
          output_low (PIN_D5);
          output_low (PIN_D6);
          output_low (PIN_D7);
          break;
      case 2:
          //output_d (0xa4);          // Two
          output_high (PIN_D0);
          output_high (PIN_D1);
          output_low  (PIN_C6);
          output_high (PIN_D3);
         
          output_high (PIN_D4);
          output_low  (PIN_D5);
          output_high (PIN_D6);
          output_low  (PIN_D7);
          break;
      case 3:
          //output_d (0xb0);          // Three
          output_high (PIN_D0);
          output_high (PIN_D1);
          output_high (PIN_C6);
          output_high (PIN_D3);
         
          output_low  (PIN_D4);
          output_low  (PIN_D5);
          output_high (PIN_D6);
          output_low  (PIN_D7);
          break;
      case 4:
          //output_d (0x99);          // Four
          output_low  (PIN_D0);
          output_high (PIN_D1);
          output_high (PIN_C6);
          output_low  (PIN_D3);
         
          output_low  (PIN_D4);
          output_high (PIN_D5);
          output_high (PIN_D6);
          output_low  (PIN_D7);
          break;
      case 5:
          //output_d (0x92);          // Five
          output_high (PIN_D0);
          output_low  (PIN_D1);
          output_high (PIN_C6);
          output_high (PIN_D3);
         
          output_low  (PIN_D4);
          output_high (PIN_D5);
          output_high (PIN_D6);
          output_low  (PIN_D7);
          break;
      case 6:
          //output_d (0x82);          // Six
          output_high (PIN_D0);
          output_low  (PIN_D1);
          output_high (PIN_C6);
          output_high (PIN_D3);
         
          output_high (PIN_D4);
          output_high (PIN_D5);
          output_high (PIN_D6);
          output_low  (PIN_D7);
          break;
      case 7:
          //output_d (0xf8);          // Seven
          output_high (PIN_D0);
          output_high (PIN_D1);
          output_high (PIN_C6);
          output_low  (PIN_D3);
         
          output_low (PIN_D4);
          output_low (PIN_D5);
          output_low (PIN_D6);
          output_low (PIN_D7);
          break;
      case 8:
          //output_d (0x80);          // Eight
          output_high (PIN_D0);
          output_high (PIN_D1);
          output_high (PIN_C6);
          output_high (PIN_D3);
         
          output_high (PIN_D4);
          output_high (PIN_D5);
          output_high (PIN_D6);
          output_low  (PIN_D7);
          break;
      case 9:
          //output_d (0x90);          // Nine
          output_high (PIN_D0);
          output_high (PIN_D1);
          output_high (PIN_C6);
          output_high (PIN_D3);
         
          output_low  (PIN_D4);
          output_high (PIN_D5);
          output_high (PIN_D6);
          output_low  (PIN_D7);
          break;
    }
 }

//============================================================================//

void digit2()
 {
   switch (count1)
    {
      // same as digit 1 ( case 0 to case 9)
    }
 }

//============================================================================//

void display_number ()
 {

   digit1(count0);

   output_high (PIN_B1);

   if ((count0==1) || (count0==7))
      delay_us (750);
   else
      delay_us (1500);

   output_low (PIN_B1);
   //======================//

   if (speed < 100)
      digit2();
   else
      digit1(count1);

   output_high (PIN_B2);

   if ((count1==1) || (count1==7))
      delay_us (750);
   else
      delay_us (1500);

   output_low (PIN_B2);

}
//============================================================================//

//============================================================================//
void Speed_Mode()
{
   Speed_Cal ();
   
   if (time_delay >= 2)
   {
      speed = newspeed;
      time_delay = 0;
   }
   
   if (speed >= 100)
   {
      count0 = speed%100/10;
      count1 = speed/100;
   }
   else
   {
      count0 = speed%10;
      count1 = speed%100/10;
   }

   display_number();
 
}

//============================================================================//
void main()
{
   
   set_rtcc(0);
   setup_counters (RTCC_INTERNAL, RTCC_DIV_256);

   setup_ccp1 (CCP_CAPTURE_RE);               // Configure CCP1 to capture rise
   setup_ccp2 (CCP_CAPTURE_RE);               // Configure CCP1 to capture rise
   
   set_timer1 (0);
   setup_timer_1 (T1_INTERNAL|T1_DIV_BY_4);   // Start timer 1
   
   clear_interrupt (INT_CCP1);
   enable_interrupts (INT_CCP1);              // Setup interrupt on raising edge
   
   clear_interrupt (INT_CCP2);
   enable_interrupts (INT_CCP2);              // Setup interrupt on raising edge
   
   clear_interrupt (INT_TIMER1);
   enable_interrupts (INT_TIMER1);            // Enable interrupt timer 1
   
   enable_interrupts (INT_RTCC);              // Enable interrupt timer 0
   
   enable_interrupts (GLOBAL);                // Enable interrup Global

 
      count0 = 8;
      count1 = 8;
      display_number ();
     
   
       
   MPH_KmPH_mode = read_eeprom (0);
   
   if (MPH_KmPH_mode > 1)
   {
      MPH_KmPH_mode = 0;
      write_eeprom (0,MPH_KmPH_mode = 0);  // clear eeprom   
   }
   
   MPH_KmPH_mode = read_eeprom (0);
   
   if (MPH_KmPH_mode == 1)
      MPH_KmPH_status = True;
   if (MPH_KmPH_mode == 0)
      MPH_KmPH_status = False;
     
   
   while(TRUE)     
      {
       
         if (MPH_KmPH_status == True)   // MPH mode
         {
            if (MPH_KmPH_mode == 0)
            {
               MPH_KmpH_mode = 1;
               write_eeprom (0, MPH_KmPH_mode = 1);
            }
         }
         else                           // KmPH mode
         {
            if (MPH_KmPH_mode == 1)
            {
               MPH_KmpH_mode = 0;
               write_eeprom (0, MPH_KmPH_mode = 0);
            }
         }
         
         Speed_Mode();
       
      }
}



my code for new Hardware is
Code:


#include <16F914.h>
#device ADC=10
#fuses HS, MCLR, NOWDT, PUT, NOIESO, BROWNOUT, NOFCMEN
#use delay(clock=20000000)


#define INTS_PER_QUARTER_SECOND     19      // (20000000/4*(4*256*256))

int int_count=INTS_PER_QUARTER_SECOND;

long speed = 0;
long newspeed = 0;

long time_delay = 0;

int capture_interrupt = 0;
int capture_ready = 0;
short capture_stable = false;
float Frequency = 0;

long MPH_KmPH_mode;
short MPH_KmPH_status;

short digit2_dec = True;
int count1 = 11;   // 1st digit
int count2 = 11;   // 2nd digit
int count3 = 11;   // 3rd digit

int Unit = 0;   
//========================================================================================//
//                                 LCD Configuration                                      //
//========================================================================================//
// Digit segments  A        B         C          D         E         F         G        DP
//                 b7       b6        b5         b4        b3        b2        b1       b0
#define DIGIT1  COM0+11,  COM1+11,  COM2+11,  COM3+11,  COM2+3,   COM0+3,   COM1+3,   COM3+3
#define DIGIT2  COM0+6,   COM1+6,   COM2+6,   COM3+6,   COM2+16,  COM0+16,  COM1+16,  COM3+16
#define DIGIT3  COM0+17,  COM1+17,  COM2+17,  COM3+17,  COM2+18,  COM0+18,  COM1+18,  COM3+18
#define UNIT1    COM0+19,  COM1+19,  COM2+19,  COM3+19,  COM2+20,  COM0+20,  COM1+20,  COM3+20
//#define DIGIT5  COM0+2,   COM1+2,   COM2+2,   COM3+2,   COM2+3,   COM0+3,   COM1+3,   COM3+3
//    COM0+0,   COM1+0,   COM2+0,   COM3+0,   COM2+1,   COM0+1,   COM1+1,   COM3+1
//       ComX+Y is combination of Backplan0-3 and Segment0-SegmentXX
//========================================================================================//
//           character         0    1    2    3    4    5    6    7    8    9    0   Null
//Decimal
byte const Digit_Map[12]   = {0xFD,0x61,0xDB,0xF3,0x67,0xB7,0xBF,0xE1,0xFF,0xF7,0xFD,0x01};
//No Decimal
byte const Digit_Map_1[12] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0xFC,0x00};
//========================================================================================//
//           Bars               MPH KMPH MPH&KMPH
byte const Unit_Map[3]      = {0x04,0x02,0x06};
//=======================================================================================//
//                          Segments Initilization                                       //
// Seg23 Seg22  ...  Seg12 Seg11 Seg10 Seg9 Seg8 Seg7 Seg6 Seg5 Seg4 Seg3 Seg2 Seg1 Seg0 //
//  0/1   0/1   0/1   0/1   0/1   0/1  0/1  0/1   0/1  0/1 0/1   0/1 0/1  0/1  0/1   0/1 //
//  if bit_SegX is 1, SegX is set as Segment Output. Otherwise                           //
//=======================================================================================//

#define Segments 0x170848    // Initilize LCD SegmentX
//============================================================================//
#int_rtcc               //This function is called
void clock_isr()
{                         //every time the RTCC (timer0)
                          //overflows (255->0)
                          //For this program this is apx
                          //31 times per second.

   if(--int_count==0)
   {
      time_delay ++;
      int_count=INTS_PER_QUARTER_SECOND;
   }
}
//============================================================================//
// Timer 1 extend to 32 bit timer

#priority CCP1, TIMER1
#priority CCP2, TIMER1
#define BytePtr(var, offset) (char *)((char *)&var + offset) 

#byte PIR1 = 0xF9E
#bit TMR1IF = PIR1.0

int gc_timer1_extension = 0;       
int32 g32_ccp_delta;

//============================================================================//

#int_timer1
void timer1_isr()
{
   gc_timer1_extension++;
}
//============================================================================//
int32 current_ccp = 0;

int32 current_ccp_delta = 0;

//============================================================================//
#int_ccp1
void ccp1_isr()
{
   capture_interrupt = 0;
   MPH_KmPH_status = True;      // MPH mode
 
   char timer_ext_copy;
   
   static int32 old_ccp = 0;
   
   current_ccp = (int32)CCP_1;
   
   timer_ext_copy = gc_timer1_extension;
   
   if (TMR1IF)
   {
      if (make8 (current_ccp, 1) < 2) 
         timer_ext_copy++;
      gc_timer1_extension++;
      TMR1IF = 0;
   }
   
   make8 (current_ccp, 2) = timer_ext_copy; 
   
   g32_ccp_delta = (current_ccp > old_ccp) ? current_ccp - old_ccp : current_ccp
                     + (0x1000000 - old_ccp);               
   
   old_ccp = current_ccp;
   
}       

//============================================================================//
#int_ccp2
void ccp2_isr()
{
   capture_interrupt = 0;
   MPH_KmPH_status = False;      // KmPH mode
   
   char timer_ext_copy;
   
   static int32 old_ccp = 0;
   
   current_ccp = (int32)CCP_2;
   
   timer_ext_copy = gc_timer1_extension;
   
   if (TMR1IF)
   {
      if (make8 (current_ccp, 1) < 2)
         timer_ext_copy++;
      gc_timer1_extension++;
      TMR1IF = 0;
   }
   
   make8 (current_ccp, 2) = timer_ext_copy;
   
   g32_ccp_delta = (current_ccp > old_ccp) ? current_ccp - old_ccp : current_ccp
                     + (0x1000000 - old_ccp);               
   
   old_ccp = current_ccp;
   
}       
//============================================================================//

void Speed_Cal ()
{
   if (capture_interrupt == 0)
         capture_ready ++;
         
   if (capture_ready >= 10)
   {
      capture_stable = true;
      capture_ready = 10;
   }
   
   if (capture_interrupt >= 10)
   {
      capture_stable = false;
      capture_interrupt = 10;
      capture_ready = 0;
   }
   
   capture_interrupt ++;
   
   if (capture_stable == true)
   {
      current_ccp_delta = g32_ccp_delta;
   }
   else
      current_ccp_delta = 0;
     
   //current_ccp_delta = g32_ccp_delta;
   //=========================================================================//
   // Frequency = (Fosc/4)/(Timer1_Prescale * time interval)                  //
   //=========================================================================//
   
   Frequency = (1250000 + (current_ccp_delta >> 3))*100 / current_ccp_delta;
                                                   // x100 to get 2 decimal
                                                   
   // 1MPH = 74Hz or 0.1MPH = 7.4Hz   application requirement
   if (MPH_KmPH_status == True)  // MPH mode
   {
      newspeed = Frequency/740;  // newspeed = 0.1 MPH,
                                 // /100 to get back 2 decimal
      if (newspeed < 5)
         newspeed = 0;
   }
   if (MPH_KmPH_status == False) // KmPH mode
   {
      newspeed = Frequency/740;  // newspeed = 0.1 MPH,
                                 // /100 to get back 2 decimal
      newspeed = newspeed*1.6093; // MPH to KMPH
     
      if (newspeed < 8)
         newspeed = 0;
   }
}

//============================================================================//
void Display()
{
   lcd_symbol (Digit_Map_1[count1], DIGIT1);  // from left to right
     
   if (Digit2_Dec == False) 
      lcd_symbol (Digit_Map_1[count2], DIGIT2);  // from left to right
   else                 
      lcd_symbol (Digit_Map[count2], DIGIT2);    // from left to right
     
   lcd_symbol (Digit_Map[count3], DIGIT3);       // from left to right
 
   lcd_symbol (Unit_Map[Unit], UNIT1);              // from left to right
}
//============================================================================//

//============================================================================//
void Speed_Mode()
{
   Speed_Cal ();
   count1 = 11;
   if (time_delay >= 2)
   {
      speed = newspeed;
      time_delay = 0;
   }
   
   if (speed >= 100)
   {
      digit2_dec = False;
      count3 = speed%100/10;
      count2 = speed/100;
   }
   else
   {
      digit2_dec = True;
      count3 = speed%10;
      count2 = speed%100/10;
   }

   Display();
     
}

//============================================================================//
void main()
{
   setup_lcd(LCD_MUX14|LCD_STOP_ON_SLEEP,2, Segments);
   set_rtcc(0);
   setup_counters (RTCC_INTERNAL, RTCC_DIV_256);

   setup_ccp1 (CCP_CAPTURE_RE);               // Configure CCP1 to capture rise
   setup_ccp2 (CCP_CAPTURE_RE);               // Configure CCP1 to capture rise
   
   set_timer1 (0);
   setup_timer_1 (T1_INTERNAL|T1_DIV_BY_4);   // Start timer 1
   
   clear_interrupt (INT_CCP1);
   enable_interrupts (INT_CCP1);              // Setup interrupt on raising edge
   
   clear_interrupt (INT_CCP2);
   enable_interrupts (INT_CCP2);              // Setup interrupt on raising edge
   
   clear_interrupt (INT_TIMER1);
   enable_interrupts (INT_TIMER1);            // Enable interrupt timer 1
   
   enable_interrupts (INT_RTCC);              // Enable interrupt timer 0
   
   enable_interrupts (GLOBAL);                // Enable interrup Global

      digit2_dec = True;
      count3 = 8;
      count2 = 8;
      Display();
     
   MPH_KmPH_mode = read_eeprom (0);
   
   if (MPH_KmPH_mode > 1)
   {
      MPH_KmPH_mode = 0;
      write_eeprom (0,MPH_KmPH_mode = 0);  // clear eeprom   
   }
   
   MPH_KmPH_mode = read_eeprom (0);
   
   if (MPH_KmPH_mode == 1)
      MPH_KmPH_status = True;
   if (MPH_KmPH_mode == 0)
      MPH_KmPH_status = False;
     
   
   while(TRUE)     
      {
       
         if (MPH_KmPH_status == True)   // MPH mode
         {
            if (MPH_KmPH_mode == 0)
            {
               MPH_KmpH_mode = 1;
               write_eeprom (0, MPH_KmPH_mode = 1);
            }
         }
         else                           // KmPH mode
         {
            if (MPH_KmPH_mode == 1)
            {
               MPH_KmpH_mode = 0;
               write_eeprom (0, MPH_KmPH_mode = 0);
            }
         }
         
         Speed_Mode();
       
      }
}
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Nov 27, 2017 10:39 am     Reply with quote

OK since ONLY the display has changed....

I'd cut a test program to 'increment and display' the numbers from 00 to 99, say at 1/2 second interval. Just a simple loop, nothing fancy, NO speed input.

Get that to work, then say reduce the interval to say 1/4 second, then 1/10th of a second. Anything faster than that will be a blur and LCDs need some time to function.

ONCE this program runs correctly THEN try your speedo program. Providing he 'LCD display' section of code is the same as the 'increment and display', then 'speedo' should work.

Jay
POPE19



Joined: 27 Jun 2017
Posts: 71

View user's profile Send private message

PostPosted: Mon Nov 27, 2017 11:54 am     Reply with quote

temtronic,

I tried the LCD is working fine with the code. I have tried the counter and the display is updated at 1/25 second interval. But i did not understand your suggestion completely.
Quote:
Providing he 'LCD display' section of code is the same as the 'increment and display', then 'speedo' should work.


Below is my code

Code:

#include <16F914.h>
#device ADC=10
#fuses HS, MCLR, NOWDT, PUT, NOIESO, BROWNOUT, NOFCMEN
#use delay(clock=20000000)
#define INTS_PER_QUARTER_SECOND     3      // (20000000/4*(4*256*256))

int int_count=INTS_PER_QUARTER_SECOND;
int seconds;
int dig1 = 11;   // 1st digit
int dig2 = 11;   // 2nd digit
int dig3 = 11;   // 3rd digit
int count=0;
//short digit2 = false;


//========================================================================================//
//                                 LCD Configuration                                      //
//========================================================================================//
// Digit segments  A        B         C          D         E         F         G        DP
//                 b7       b6        b5         b4        b3        b2        b1       b0
#define DIGIT1  COM0+11,  COM1+11,  COM2+11,  COM3+11,  COM2+3,   COM0+3,   COM1+3,   COM3+3
#define DIGIT2  COM0+6,   COM1+6,   COM2+6,   COM3+6,   COM2+16,  COM0+16,  COM1+16,  COM3+16
#define DIGIT3  COM0+17,  COM1+17,  COM2+17,  COM3+17,  COM2+18,  COM0+18,  COM1+18,  COM3+18
#define UNIT1    COM0+19,  COM1+19,  COM2+19,  COM3+19,  COM2+20,  COM0+20,  COM1+20,  COM3+20
//#define DIGIT5  COM0+2,   COM1+2,   COM2+2,   COM3+2,   COM2+3,   COM0+3,   COM1+3,   COM3+3
//    COM0+0,   COM1+0,   COM2+0,   COM3+0,   COM2+1,   COM0+1,   COM1+1,   COM3+1
//       ComX+Y is combination of Backplan0-3 and Segment0-SegmentXX
//========================================================================================//
//           character         0    1    2    3    4    5    6    7    8    9    0   Null
//Decimal
byte const Digit_Map[12]   = {0xFD,0x61,0xDB,0xF3,0x67,0xB7,0xBF,0xE1,0xFF,0xF7,0xFD,0x01};
//No Decimal
byte const Digit_Map_1[12] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0xFC,0x00};
//========================================================================================//
//           Bars               MPH KMPH MPH&KMPH
byte const Unit_Map[3]      = {0x04,0x02,0x06};
//=======================================================================================//
//                          Segments Initilization                                       //
// Seg23 Seg22  ...  Seg12 Seg11 Seg10 Seg9 Seg8 Seg7 Seg6 Seg5 Seg4 Seg3 Seg2 Seg1 Seg0 //
//  0/1   0/1   0/1   0/1   0/1   0/1  0/1  0/1   0/1  0/1 0/1   0/1 0/1  0/1  0/1   0/1 //
//  if bit_SegX is 1, SegX is set as Segment Output. Otherwise                           //
//=======================================================================================//
#define Segments 0x170848    // Initilize LCD SegmentX
#int_rtcc               //This function is called
void clock_isr()
{                         //every time the RTCC (timer0)
                          //overflows (255->0)
                          //For this program this is apx
                          //31 times per second.

   if(--int_count==0)
   {
      seconds++;
      int_count=INTS_PER_QUARTER_SECOND;
   }
}

void counter()
{
   if(seconds >=1)
   {
     count++;
     seconds = 0;
   }
   
   if(count <= 9)
   {
      dig3 = count;
      dig2 = 11;
      dig1 = 11;
   }
   
   if(count <=99)
   {
      dig3 = Count%10;
      dig2 = Count%100/10;
      dig1 = 11;
   }
   
   if(count >99)
   {
      count = 0;
      dig3 = 0;
      dig2 = 11;
      dig1 = 11;
   }
}
void Display()
{
   lcd_symbol (Digit_Map_1[dig1], DIGIT1);  // from left to right
     
   //if (Digit2_Dec == False) 
      lcd_symbol (Digit_Map_1[dig2], DIGIT2);  // from left to right
  // else                 
     // lcd_symbol (Digit_Map[dig2], DIGIT2);    // from left to right
     
   lcd_symbol (Digit_Map[dig3], DIGIT3);       // from left to right
   
}
//============================================================================//

void main()
{
   
   setup_lcd(LCD_MUX14|LCD_STOP_ON_SLEEP,2, Segments);
   set_rtcc(0);
   setup_counters (RTCC_INTERNAL, RTCC_DIV_256);
   set_timer1 (0);
   setup_timer_1 (T1_INTERNAL|T1_DIV_BY_4);   // Start timer 1
   enable_interrupts (INT_RTCC);              // Enable interrupt timer 0
   
   enable_interrupts (GLOBAL);                // Enable interrup Global
   
    dig1 = 11;
      dig2 = 8;
      dig3 = 8;
      display ();
     
   while(TRUE)      // Modify on 3/09/12
   {
       Display();
       counter();
   }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Nov 27, 2017 11:55 am     Reply with quote

There are several things in the code that either don't do what the poster thinks, or are just wrong.
For instance #priority, is meant to have a list of all the interrupts whose polling priority you want to set, in the order you want them to be serviced.
Only the last one will actually be setting priority.

Then at several places in the code:
Code:

      MPH_KmPH_mode = 0;
      write_eeprom (0,MPH_KmPH_mode = 0);  // clear eeprom 

The second allocation in each of these is pointless. the variable is set to a value, then set again...

Then:
Code:

   make8 (current_ccp, 2) = timer_ext_copy;

Ugh....
Make8, can't be allocated a value. This is not how to write to the third byte of a four byte value.

There are lots of places where data is moved unnecessarily, or incorrectly...

My guess would be that a variable that was actually overflowing or overwriting another variable, has been moved to a different location in the new code, and hence the change. Sad
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 27, 2017 12:33 pm     Reply with quote

I noticed something about this code. It has two isr routines for CCP1
and CCP2. Is the input signal connected to the CCP inputs ?
Both of these interrupt routines use the same global variables.
That's not going to work well.

I don't see the need for separately clocked CCP inputs, just because one
is labeled "Kilometers per hour" and the other is "Miles per hour".
You only need one CCP. The conversion to Kph or Mph can be done with
math later.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 27, 2017 12:54 pm     Reply with quote

Ttelmah, make8() can be an lvalue in later versions of the compiler.
Here is the output of the test program shown below. It has successfully
inserted a byte of 0x55 into the 32-bit value. This was tested with v5.075.
Quote:
01550304

Test program:
Code:
#include <18F46K22.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)

//================================
void main(void)
{
int8 timer_ext_copy = 0x55;
int32 current_ccp = 0x01020304;

make8(current_ccp, 2) = timer_ext_copy;

printf("%lx \r", current_ccp);

while(TRUE);
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Nov 27, 2017 1:00 pm     Reply with quote

That's not documented.
Fair enough, but there are some really silly bits in the code in general that worry me. Lots of things that 'might' work, rather than sensible code.
I wasn't checking for anything that might apply only to recent compilers, since he talks about it having been written a long time ago, and then 'updated'...
It is also the sort of feature that is likely to differ from compiler version to version, so could be very likely to be causing problems. Since his code is failing when the times are large (just when timer wraps have to be handled), I'm very suspicious of problems in this area.
POPE19



Joined: 27 Jun 2017
Posts: 71

View user's profile Send private message

PostPosted: Mon Nov 27, 2017 1:19 pm     Reply with quote

PCM Programmer


There are two inputs one for MPH & 1 for KPH. Only one operates at a time, but this is application requirement so it is kept that way. However the same code works fine with the old hardware. That is bothering me. I am really new to this field so trying to figure out.

I have checked the Freq input on scope for both the hardware and both of them are identical which points out that something is wrong with the code.

However for new hardware with same code the Pic Detects the Freq from 208HZ. It cannot detect freq. below 99Hz. It wakes up at 208 hz and then detects the lower freq up to 99 Hz.
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Nov 27, 2017 1:50 pm     Reply with quote

Brings me back to my point, perhaps not worded well though.
The poster says the original code WORKS with a 2 digit LED display. If the ONLY change was to use an LCD, then nothing as far as pulse capturing and 'math' conversion' has been changed, so the 'numbers' should be the same.
As pointed out ther's a lot of code 'issues' but he does say it WORKS.
Changing the display from LED to LCD shouldn't affect the 'acquistion' and 'math' portions of the program.

My request to have an 'increment and display' program is to verify that the hardware can properly display the numbers from 00 to 99, same as the LED does..however.. re reading the LCD code, he now has 3 digits not just 2, so really the LCD test should be from 000 to 999. I'm not convinced the LCD display is correct.

For 'test purposes' it would be nice to have a pin send the data to a PC, via 'RS232'. Hopefully there's one available output pin. This would show WHERE the problem is, either 'data acquistion', 'math conversion' or 'display'.

It will be interesting to see what solves this !
POPE19



Joined: 27 Jun 2017
Posts: 71

View user's profile Send private message

PostPosted: Mon Nov 27, 2017 2:05 pm     Reply with quote

Temtronic i have RB0, RB1 I/O pins available. What exactly you want me to test ? I need little more explanation.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Nov 27, 2017 2:15 pm     Reply with quote

The best thing to start is to just have the LCD code, and a single timer. Count from 0 to 999, and make sure this displays OK.
POPE19



Joined: 27 Jun 2017
Posts: 71

View user's profile Send private message

PostPosted: Mon Nov 27, 2017 3:09 pm     Reply with quote

Ttelmah it is working fine. It counts from 0 to 999. Without missing any digit. Works 100%

Here is a piece of my modified code !!
Code:

void counter()
{
   if(seconds >=1)
   {
     count++;
     seconds = 0;
   }
   
   if(count <= 9)
   {
      dig3 = count;
      dig2 = 11;
      dig1 = 11;
   }
   
   if(count <= 99 && count > 9)
   {
      dig3 = count%10;
      dig2 = count%100/10;
      dig1 = 11;
   }
   
   if(count <= 999 && count > 99)
   {
      dig3 = count%10;
      dig2 = count%100/10;
      dig1 = count%1000/100;
   }
   
   if(count > 999)
   {
      count = 0;
      dig3 = 0;
      dig2 = 11;
      dig1 = 11;
   }
}
POPE19



Joined: 27 Jun 2017
Posts: 71

View user's profile Send private message

PostPosted: Tue Nov 28, 2017 2:18 pm     Reply with quote

I have wrote a simple code. it is working now but there is a problem. I am giving 37 Hz Input and getting 0.5 Mph on LCD. But as the freq input to CCP (turning off output of function generator) the display displays 0.6 Mph, sometimes 0.7 Mph. Why is it so ?

Also I want the LCD to Display 0.0 when output of function generator is OFF. How would i do that ? Any suggestion ?

Code:

#include <16F914.h>
#device ADC=10
#fuses HS, MCLR, NOWDT, PUT, NOIESO, BROWNOUT, NOFCMEN
#use delay(clock=20000000)
#define INTS_PER_QUARTER_SECOND     19      // (20000000/4*(4*256*256))

int int_count=INTS_PER_QUARTER_SECOND;
int time_delay =0;
int count0 = 0;   //3rd digit
int count1 = 0;   //2nd digit
int count2 = 0;   //1st digit

int capture_interrupt = 0;  //Trig for Delay to have stable freq reading.
int capture_ready = 0;

short Digit2_Dec = true;
float Frequency = 0;
long newspeed = 0;
long speed = 0;
short MPH_KmPH_status;



//========================================================================================//
//                                 LCD Configuration                                      //
//========================================================================================//
// Digit segments  A        B         C          D         E         F         G        DP
//                 b7       b6        b5         b4        b3        b2        b1       b0
#define DIGIT1  COM0+11,  COM1+11,  COM2+11,  COM3+11,  COM2+3,   COM0+3,   COM1+3,   COM3+3
#define DIGIT2  COM0+6,   COM1+6,   COM2+6,   COM3+6,   COM2+16,  COM0+16,  COM1+16,  COM3+16
#define DIGIT3  COM0+17,  COM1+17,  COM2+17,  COM3+17,  COM2+18,  COM0+18,  COM1+18,  COM3+18
#define UNIT1    COM0+19,  COM1+19,  COM2+19,  COM3+19,  COM2+20,  COM0+20,  COM1+20,  COM3+20
//#define DIGIT5  COM0+2,   COM1+2,   COM2+2,   COM3+2,   COM2+3,   COM0+3,   COM1+3,   COM3+3
//    COM0+0,   COM1+0,   COM2+0,   COM3+0,   COM2+1,   COM0+1,   COM1+1,   COM3+1
//       ComX+Y is combination of Backplan0-3 and Segment0-SegmentXX
//========================================================================================//
//           character         0    1    2    3    4    5    6    7    8    9    0   Null
//Decimal
byte const Digit_Map[12]   = {0xFD,0x61,0xDB,0xF3,0x67,0xB7,0xBF,0xE1,0xFF,0xF7,0xFD,0x01};
//No Decimal
byte const Digit_Map_1[12] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0xFC,0x00};
//========================================================================================//
//           Bars               MPH KMPH MPH&KMPH
byte const Unit_Map[3]      = {0x04,0x02,0x06};
//=======================================================================================//
//                          Segments Initilization                                       //
// Seg23 Seg22  ...  Seg12 Seg11 Seg10 Seg9 Seg8 Seg7 Seg6 Seg5 Seg4 Seg3 Seg2 Seg1 Seg0 //
//  0/1   0/1   0/1   0/1   0/1   0/1  0/1  0/1   0/1  0/1 0/1   0/1 0/1  0/1  0/1   0/1 //
//  if bit_SegX is 1, SegX is set as Segment Output. Otherwise                           //
//=======================================================================================//
#define Segments 0x170848    // Initilize LCD SegmentX

//=================================================================================//
#int_rtcc               //This function is called
void clock_isr()
{                         //every time the RTCC (timer0)
                          //overflows (255->0)
                          //For this program this is apx
                          //31 times per second.

   if(--int_count==0)
   {
      time_delay ++;  // To update Display every 0.5 Sec
      int_count=INTS_PER_QUARTER_SECOND;
   }
}
//================================================================================//

#priority CCP1, TIMER1

#define BytePtr(var, offset) (char *)((char*)&var + offset)

#byte PIR1 = 0xF9E      // to locate PIR1 at address 0xF9E.
#bit  TMR1IF = PIR1.0   // creates TMR1IF Variable & bit 0 of a byte (PIR1 Registor) is stored inside

//========================variables===============//
int8  gc_timer1_extension = 0;   
int32 current_ccp_delta = 0;
short capture_stable = false;
int32 g32_ccp_delta;   //Global Variable which stores Timer intervals between two rising edge of input signal
//===============================================//

//=====routine=========
#int_timer1        //everytime Timer-1 Interrupts the below Subroutine is Executed immediately after interrupt.
void timer1_isr(void)
{
  gc_timer1_extension++;    // increment real timer extension
}

#int_ccp1
void ccp1_isr(void)
{
   
   char timer_ext_copy;
   int32 current_ccp = 0;
   static int32 old_ccp = 0;
   
   capture_interrupt= 0;
   MPH_KmPH_status = True;      // MPH mode
 
 
   current_ccp = (int32)CCP_1; // Read the current CCP
   
   timer_ext_copy = gc_timer1_extension; // get a local copy of timer ext

   if(TMR1IF)
   {
      if (make8 (current_ccp, 1) < 2)  // was CCP captured after Timer-1 Wrapped?
      timer_ext_copy++;                // if yes, Increment the copy of timer ext.

      gc_timer1_extension++;           // Increment the real timer extension
      TMR1IF = 0;                      // Then clear the Timer1 interrupt
   }
    // Insert the timer extension into the proper place in the 32-bit
    // CCP value.
   // ie.,  Insert it into location "EE" as follows: 0x00EEnnnn
   // (nnnn = the CCP).
   make8 (current_ccp, 2) = timer_ext_copy;

   g32_ccp_delta = (current_ccp > old_ccp) ? current_ccp - old_ccp : current_ccp + (0x1000000 - old_ccp);

   old_ccp = current_ccp; // Save the current CCP value for next time.
     
}
//=================================================================================//
void Display()
{
   lcd_symbol (Digit_Map_1[count2], DIGIT1);  // from left to right
     
   if (Digit2_Dec == False) 
      lcd_symbol (Digit_Map_1[count1], DIGIT2);  // from left to right
   else                 
      lcd_symbol (Digit_Map[count1], DIGIT2);    // from left to right
     
   lcd_symbol (Digit_Map[count0], DIGIT3);       // from left to right
   
}
//============================================================================//

void Speed_Cal ()
{
   if (capture_interrupt == 0)
         capture_ready ++;
         
   if (capture_ready >= 10)
   {
      capture_stable = true;
      capture_ready = 10;
   }
   if (capture_stable == true)
   {
     current_ccp_delta = g32_ccp_delta;;
   }
   else
   
      current_ccp_delta = 0;
           
   //current_ccp_delta = g32_ccp_delta;
   //=========================================================================//
   // Frequency = (Fosc/4)/(Timer1_Prescale * time interval)                  //
   //=========================================================================//
   
    Frequency = (1250000 + (current_ccp_delta >> 3))*100 / current_ccp_delta;
                                                   // x100 to get 2 decimal
                                                 
   // 1MPH = 74Hz or 0.1MPH = 7.4Hz   application requirement
    // MPH mode
   if (MPH_KmPH_status == True)  // MPH mode
   {
      newspeed = Frequency/740;  // newspeed = 0.1 MPH,
                                // /100 to get back 2 decimal
      if (newspeed < 5)
        newspeed = 0;
   }
   
   
 }
//============================================================================//
void Speed_Mode()
{
   Speed_Cal ();
   
   if (time_delay >= 2)
   {
      speed = newspeed;
      time_delay  = 0;
   }
   
   if (speed >= 100)
   {
      count2 = speed%100/10;
      count1 = speed/100;
      count0 = speed%10;
   }
   else
   {
      Digit2_Dec = true;
      count2 = 11;
      count1 = speed%100/10;
      count0 = speed%10;
   }

   display();
 
}

//============================================================================//
   
   

void main()
{
   setup_lcd(LCD_MUX14|LCD_STOP_ON_SLEEP,2, Segments);
   set_rtcc(0);
   setup_counters (RTCC_INTERNAL, RTCC_DIV_256);

   setup_ccp1 (CCP_CAPTURE_RE);               // Configure CCP1 to capture rise
   setup_ccp2 (CCP_CAPTURE_RE);               // Configure CCP1 to capture rise
   
   set_timer1 (0);
   setup_timer_1 (T1_INTERNAL|T1_DIV_BY_4);   // Start timer 1
   
   clear_interrupt (INT_CCP1);
   enable_interrupts (INT_CCP1);              // Setup interrupt on raising edge
   
   clear_interrupt (INT_CCP2);
   enable_interrupts (INT_CCP2);              // Setup interrupt on raising edge
   
   clear_interrupt (INT_TIMER1);
   enable_interrupts (INT_TIMER1);            // Enable interrupt timer 1
   
   enable_interrupts (INT_RTCC);              // Enable interrupt timer 0
   
   enable_interrupts (GLOBAL);                // Enable interrup Global

      Digit2_Dec = true;
      count2 = 11;
      count1= 8;
      count0 = 8;
      display ();
     
         
   while(TRUE)      // Modify on 3/09/12
   {
      Speed_Mode();
     
   }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue Nov 28, 2017 3:03 pm     Reply with quote

and, does your old code still work OK, if compiled with the current compiler?.
POPE19



Joined: 27 Jun 2017
Posts: 71

View user's profile Send private message

PostPosted: Tue Nov 28, 2017 4:38 pm     Reply with quote

YES old code works fine in old hardware compiled in same compiler (version 5.074) but it doesnot work in new hardware . any ways the problem is solve but i need some idea how to make an LCD Display 0.0 when my output of function Generator is OFF.

Currently it stick on to the last reading before i turn off the output of my function generator
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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