|
|
View previous topic :: View next topic |
Author |
Message |
POPE19
Joined: 27 Jun 2017 Posts: 71
|
PIC LOWER FREQ. READING PROBLEM |
Posted: Mon Nov 27, 2017 7:22 am |
|
|
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: 9243 Location: Greensville,Ontario
|
|
Posted: Mon Nov 27, 2017 10:39 am |
|
|
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
|
|
Posted: Mon Nov 27, 2017 11:54 am |
|
|
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: 19539
|
|
Posted: Mon Nov 27, 2017 11:55 am |
|
|
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. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Nov 27, 2017 12:33 pm |
|
|
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
|
|
Posted: Mon Nov 27, 2017 12:54 pm |
|
|
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.
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: 19539
|
|
Posted: Mon Nov 27, 2017 1:00 pm |
|
|
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
|
|
Posted: Mon Nov 27, 2017 1:19 pm |
|
|
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: 9243 Location: Greensville,Ontario
|
|
Posted: Mon Nov 27, 2017 1:50 pm |
|
|
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
|
|
Posted: Mon Nov 27, 2017 2:05 pm |
|
|
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: 19539
|
|
Posted: Mon Nov 27, 2017 2:15 pm |
|
|
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
|
|
Posted: Mon Nov 27, 2017 3:09 pm |
|
|
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
|
|
Posted: Tue Nov 28, 2017 2:18 pm |
|
|
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: 19539
|
|
Posted: Tue Nov 28, 2017 3:03 pm |
|
|
and, does your old code still work OK, if compiled with the current compiler?. |
|
|
POPE19
Joined: 27 Jun 2017 Posts: 71
|
|
Posted: Tue Nov 28, 2017 4:38 pm |
|
|
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 |
|
|
|
|
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
|