|
|
View previous topic :: View next topic |
Author |
Message |
mka879
Joined: 30 Oct 2015 Posts: 34
|
Code Hang Problem |
Posted: Sun May 01, 2016 11:26 pm |
|
|
I am using SIM900 with Portb interrupt on change in a project. The system sends SMS every minute. Also an SMS is sent at each interrupt on change. The system runs fine only if there are less than three IOC between 1 minute interval SMS otherwise the code hangs. The code is given below:
Code: | #include <16F877A.h>
#device ADC=10;
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or (PIC18) used for I/O
#use delay(crystal=20000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7,PARITY=N,BITS=8,STOP=1,ERRORS)
char flag[80];
char check;
int counter = 0;
int16 overflow = 0;
int16 fuel_level,vol_batt;
int16 temp = 0;
int16 temp1 = 0;
int16 tmpr = 0;
int1 flag_else = 0;
int mod_test();
void init_CS5463();
int send_sms1(int32,int32,int32,int16,int16,int1,int1,int32);
int send_sms2(int32,int32,int32,int32,int16,int16,int1,int1,int32);
void init_pic1();
void init_pic2();
void init_gsm_mod();
int1 w,y,z;
int1 flag_b4,flag_b6;
int8 flag_sel;
int1 flag_blink,flag_sec;
#include<math.h>
#define i_thresh 419430
#define v_thresh 1471686
#define CS PIN_D1
#define RESET PIN_B5
#define LED_Blink PIN_D6
#define CS5463_CONFIG_REG 0
#define AC_I_Gain_Reg 2
#define AC_V_Gain_Reg 4
#define CS5463_TEMP_REG 19
#define CS5463_CYCLE_COUNT_REG 5
#define CS5463_EPILSON_REG 13
#define AC_I_Offset_Reg 16
#define AC_V_Offset_Reg 17
#define OPERATION_REG 18
#define PF_Reg 25
#define PActive_Reg 10
#define Vrms_Reg 12
#define Irms_Reg 11
#define sync 0xFF
#define ovr_sec 2304
#define ovr_min 4578
#bit sspbuf0 = 0x13.0
#byte sspbuf = 0x13
#int_rb
void rb_isr(void)
{
int1 state_b7,state_b4;
output_bit(pin_b5,!input_state(pin_b5));
delay_ms(10);
output_high(pin_b6);
if (input_state(pin_b7) != w)
{
if (input_state(pin_b7))
{
flag_b4 = 1;
w = 1;
}
else
w = 0;
}
if (input_state(pin_b4) != y)
{
if (!input_state(pin_b4))
{
flag_b6 = 1;
y = 0;
}
else
y = 1;
}
state_b7 = input(pin_b7);
state_b4 = input(pin_b4);
output_low(pin_b6);
}
#use delay(crystal=20000000)
#int_rda
void isr_rda(void)
{
output_high(pin_b6);
flag[counter] = getchar();
counter++;
output_low(pin_b6);
}
#int_timer0
void isr_timer0(void)
{
static int temp = 0;
overflow++;
temp++;
if (temp == 78)
{
flag_blink = 1;
temp = 0;
}
clear_interrupt(int_timer0);
}
//---------------------------------
int32 CS5463_read_reg(int8 reg)
{
int8 msb, mid, lsb,temp;
int32 retval;
output_low(CS); //slave select
temp = spi_read(reg << 1); //send read command
msb = spi_read(sync); //read msb mid and lsb by sending sync commands
mid = spi_read(sync);
lsb = spi_read(sync);
output_high(CS);
retval = make32(0, msb, mid, lsb);
return(retval);
}
//---------------------------------
void CS5463_write_reg(int8 reg, int8 msb, int8 mid, int8 lsb)
{
output_low(CS);
spi_write((reg << 1) | 0x40); // OR with Write bit
spi_write(msb);
spi_write(mid);
spi_write(lsb);
output_high(CS);
}
//---------------------------------
void sync_port(void)
{
output_low(CS);
spi_write(0xFF);
spi_write(0xFF);
spi_write(0xFF);
spi_write(0xFE);
output_high(CS);
}
//---------------------------------
void start_conv(void)
{
output_low(CS);
spi_write(0xE8);
output_high(CS);
}
//---------------------------------
void ac_offset_calibration(void)
{
CS5463_write_reg(AC_V_Offset_Reg,0,0,0);
CS5463_write_reg(AC_I_Offset_Reg,0,0,0);
output_low(CS);
spi_write(0xDD); //voltage and current ac offset command
output_high(CS);
}
//---------------------------------
void ac_gain_calibration(void)
{
CS5463_write_reg(AC_V_Gain_Reg,64,0,0);
CS5463_write_reg(AC_I_Gain_Reg,64,0,0);
output_low(CS);
spi_write(0xDE); //AC V and I Gain Calibration command
output_high(CS);
}
//---------------------------------
//===============================
void main()
{
int32 v,i,ccr;
int32 pf;
int1 pressure_sw,temp_sw;
int16 overflow_dig1 = 0;
int16 overflow_dig2 = 0;
v = 0; i = 0; ccr =0; pf = 0;
fuel_level = 0;vol_batt = 0; pressure_sw = 0; temp_sw = 0;temp = 0;
flag_b4 = 0;flag_b6 = 0;
float pf_sqr= 0.00 ;
init_pic1();
flag_sel = 0;
init_pic1();
init_gsm_mod();
flag_blink = 0;
flag_sec = 0;
int16 overflow1 = 0;
while (!mod_test())
{
}
init_CS5463();
w = input(pin_b7);
y = input(pin_b4);
z = input(pin_d4);
init_pic2();
while(TRUE)
{
v = CS5463_read_reg(Vrms_Reg);
if (flag_b4 == 1)
{
flag_b4 = 0;
output_high(pin_b1);
output_high(pin_b2);
while (!send_sms1(v,i,pf,fuel_level,vol_batt,pressure_sw,temp_sw,ccr))
{
}
output_low(pin_b1);
output_low(pin_b2);
}
if (flag_b6 == 1)
{
flag_b6 = 0;
output_high(pin_b3);
output_high(pin_b2);
while (!send_sms1(v,i,pf,fuel_level,vol_batt,pressure_sw,temp_sw,ccr))
{
}
output_low(pin_b2);
output_low(pin_b3);
}
if (flag_blink == 1)
{
output_bit(LED_Blink,!input_state(LED_Blink));
flag_blink = 0;
}
if (v > v_thresh)
{
flag_sec = 1;
overflow1 = ovr_sec;
}
else
{
flag_sec = 0;
overflow1 = ovr_min;
}
if (overflow > overflow1)
{
output_high(pin_b2);
while (!send_sms1(v,i,pf,fuel_level,vol_batt,pressure_sw,temp_sw,ccr))
{
}
output_low(pin_b2);
overflow = 0;
}
}
}
int mod_test()
{
int index = 0;
counter = 0;
int overflow_mod = overflow;
strcpy(flag,"no");
printf("AT+CMGF=1");
putchar(0x0D);
output_bit(pin_b5,1);
delay_ms(500);
while ((counter <= 7) && (overflow < (overflow_mod + 10)))
{
}
output_bit(pin_b5,0);
for (index = 0; index <= 12; index++)
{
if (flag[index] == 'O' && flag[index + 1] == 'K')
{
delay_ms(500);
return 1;
}
}
delay_ms(500);
return 0;
}
int send_sms1(int32 v, int32 i, int32 pf, int16 fuel_level, int16 vol_batt, int1 pressure_sw, int1 temp_sw,int32 ccr)
{
int index = 0;
counter = 0;
strcpy(flag,"no");
printf("AT+CMGS=\"03332097014\"");
putchar(0x0D);
delay_ms(500);
float vfinal = ((float)v / 16777216)*355.38;
float ifinal = ((float)i / 16777216)*90.6;
while (counter <= 7)
{
}
for (index = 0; index <= 28; index++)
{
if (flag[index] == '>')
{
printf("%fV,%fA,%fkW,%f,%fC,%f%%,%fV,%u,%u,%lu\r\n",vfinal,ifinal,vfinal*ifinal*pf/1000,(float)pf / 8388608,(float)vol_batt*2.5/1023,(((float)fuel_level*5/1023)*187.41)-7.38,((float)tmpr*14.5/1023),temp_sw,pressure_sw,ccr);
delay_ms(500);
putchar(0x1A);
return 1;
}
}
delay_ms(500);
return 0;
}
void init_gsm_mod()
{
output_bit(pin_b5,1);
delay_ms(11000);
output_bit(pin_b5,0);
strcpy(flag,"no");
counter = 0;
}
void init_CS5463()
{
setup_spi(SPI_MASTER|SPI_SCK_IDLE_LOW|SPI_CLK_DIV_64|SPI_XMIT_L_TO_H); //set up spi module
sync_port();
CS5463_write_reg(CS5463_EPILSON_REG,1,163,111);
CS5463_write_reg(OPERATION_REG,0,0,96); // turn high pass filter on
delay_ms(500);
CS5463_write_reg(CS5463_CONFIG_REG,1,0,1);
delay_ms(1000);
CS5463_write_reg(AC_I_Gain_Reg,70,134,146);
CS5463_write_reg(AC_V_Gain_Reg,63,25,194);
start_conv();
delay_ms(500);
output_low(CS); // turn high pass filter on
CS5463_write_reg(OPERATION_REG,0,0,97);
}
void init_pic1()
{
setup_adc_ports(AN0_AN1_AN2_AN3_AN4);
setup_adc(ADC_CLOCK_DIV_32);
output_high(RESET);
output_high(CS);
enable_interrupts(global);
enable_interrupts(int_rda);
setup_timer_0(T0_DIV_256);
enable_interrupts(INT_TIMER0);
}
void init_pic2()
{
enable_interrupts(int_rb);
}
|
There may be a few variables which are not used so far but may be used in future. Please help. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Mon May 02, 2016 12:39 am |
|
|
Nobody is going to wade through and solve your programming problems for you.
However one glaring place to look. delay_ms(10) inside an interrupt. Search here for 'why' this is almost certainly the cause (given in particular that there are several 500mSec delays in the external code....). |
|
|
mka879
Joined: 30 Oct 2015 Posts: 34
|
|
Posted: Mon May 02, 2016 1:25 am |
|
|
Ttelmah wrote: | Nobody is going to wade through and solve your programming problems for you.
However one glaring place to look. delay_ms(10) inside an interrupt. Search here for 'why' this is almost certainly the cause (given in particular that there are several 500mSec delays in the external code....). |
Thank you Ttelmah for giving the hint. I will look into this problem. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon May 02, 2016 10:18 am |
|
|
The usual problem of "interrupts disabled to prevent re-entrancy" is not
the case in your program, because you have two #use delay(20M)
statements. This causes the #int_rb routine to have its own separate
delay_ms() library routines.
You need to find the line of code that's causing the lockup.
If you can't find it by inspection, then try this method:
You can put markers in your main while() loop, such as
putc('1');
putc('2');
putc('3');
etc.
Put a marker at the start of the while() loop, and inside each if() or else
block. Also put a marker inside each while() loop that is inside an if().
In other words, track the program flow. Start your program and let
it run. Give it the external input that causes it to fail. Look at the markers
on your terminal window (eg., TeraTerm). Notice the last marker printed.
That's the block of code where it entered and did not leave.
If a function was called in that block of code, enter more markers inside
that function. Track down the exact line that's causing the problem.
The reason for using markers is to test the code in Release mode.
You are using the hardware UART for SMS messages, so the markers
would have to use a software UART. These means you would have to
use streams in the #use rs232() statements and in your code.
To reduce the time spent sending these marker bytes, you could increase
the baud rate for the soft UART to 115200, or maybe higher if it works.
Since you're running interrupts in your program, you will also have to
add DISABLE_INTS to your #use rs232() statement for the soft UART.
Hence the reason for the higher baud rate. |
|
|
mka879
Joined: 30 Oct 2015 Posts: 34
|
|
Posted: Mon May 02, 2016 10:52 pm |
|
|
PCM programmer wrote: | The usual problem of "interrupts disabled to prevent re-entrancy" is not
the case in your program, because you have two #use delay(20M)
statements. This causes the #int_rb routine to have its own separate
delay_ms() library routines.
You need to find the line of code that's causing the lockup.
If you can't find it by inspection, then try this method:
You can put markers in your main while() loop, such as
putc('1');
putc('2');
putc('3');
etc.
Put a marker at the start of the while() loop, and inside each if() or else
block. Also put a marker inside each while() loop that is inside an if().
In other words, track the program flow. Start your program and let
it run. Give it the external input that causes it to fail. Look at the markers
on your terminal window (eg., TeraTerm). Notice the last marker printed.
That's the block of code where it entered and did not leave.
If a function was called in that block of code, enter more markers inside
that function. Track down the exact line that's causing the problem.
The reason for using markers is to test the code in Release mode.
You are using the hardware UART for SMS messages, so the markers
would have to use a software UART. These means you would have to
use streams in the #use rs232() statements and in your code.
To reduce the time spent sending these marker bytes, you could increase
the baud rate for the soft UART to 115200, or maybe higher if it works.
Since you're running interrupts in your program, you will also have to
add DISABLE_INTS to your #use rs232() statement for the soft UART.
Hence the reason for the higher baud rate. |
Thank you so much. I will revert to you once I have implemented your suggestion. |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Tue May 03, 2016 11:03 am |
|
|
yes your delays are a BAD idea - but
i am betting flag[] is being overrun inside the int handler.
nothing limits 'counter' to values less than 80 .........
then trashing check var that follows.
you might well not be getting the data you expect and that makes it worse yet....
also the handling of counter is scary since in your mod_test routine RDA_ISR is still active.
the time domain performance of the whole thing is sketchy IMHO.
it takes some run time to fail since it depends on what comes in data wise.
a gaping code fault |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Wed May 04, 2016 12:32 am |
|
|
Asmboy is right.
The delay though probably causes the actual problem!....
Think about it. Data at 9600bps, means basically one character per mSec. 10mSec delay inside the int_rb handler is 10mSec, when serial is not being handled. Result up to 8 serial characters lost (2 characters in the hardware).
Then according to what is lost you can then get counter overflowing. Result garbage in memory.....
So:
1) Do the delay by programming an interrupt, exiting immediately, and when this interrupt triggers do your tests. Result no serial data lost, so quite probably the problem vanishes.
2) Add a test to limit counter anyway. Much safer if anything else triggers the same problem. |
|
|
mka879
Joined: 30 Oct 2015 Posts: 34
|
|
Posted: Wed May 04, 2016 11:56 pm |
|
|
asmboy wrote: | yes your delays are a BAD idea - but
i am betting flag[] is being overrun inside the int handler.
nothing limits 'counter' to values less than 80 .........
then trashing check var that follows.
you might well not be getting the data you expect and that makes it worse yet....
also the handling of counter is scary since in your mod_test routine RDA_ISR is still active.
the time domain performance of the whole thing is sketchy IMHO.
it takes some run time to fail since it depends on what comes in data wise.
a gaping code fault |
Thank you so much all of you. Fundamentally it was a hardware issue and also the issue pointed out by asmboy. I modified the isr_rda in the following manner
Code: |
if (counter >= 79)
counter = 0;
flag[counter] = getchar();
counter++; |
This modification fixed the bug. Again thank you so much to all of you.
If you can suggest how to improve program flow, that will be of great help. You can notice a number of if structures in my while loop which is polling the flags set by interrupt service routines. How may I avoid these if structures and make my program more efficient. Also I modified my previous code which is given below
Code: |
#include <16F877A.h>
#device ADC=10;
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or (PIC18) used for I/O
#use delay(crystal=20000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7,PARITY=N,BITS=8,STOP=1,ERRORS)
typedef struct
{
int32 v;
int32 i;
int32 pf;
int32 ccr;
int16 fuel_level;
int16 vol_batt;
int16 tmpr;
int1 pressure_sw;
int1 temp_sw;
}Gen_Params;
char flag[80];
char check;
int counter,state;
int16 overflow,overflow1;
int16 temp;
int16 sensor_read;
int mod_test();
void read_sensor(Gen_Params*);
void init_CS5463();
int send_sms1(Gen_Params*);
int send_sms2(int32,int32,int32,int32,int16,int16,int1,int1,int32);
void calculate_CS5463(Gen_Params*);
void init_pic1();
void init_pic2();
void init_gsm_mod();
int1 w,y,z,flag_sensor;
int1 flag_b4,flag_b6;
int1 flag_blink;
#include<math.h>
#define i_thresh 419430
#define v_thresh 1471686
#define CS PIN_D1
#define RESET PIN_B5
#define LED_Blink PIN_d6
#define CS5463_CONFIG_REG 0
#define AC_I_Gain_Reg 2
#define AC_V_Gain_Reg 4
#define CS5463_TEMP_REG 19
#define Cycle_Count_Reg 5
#define CS5463_EPILSON_REG 13
#define AC_I_Offset_Reg 16
#define AC_V_Offset_Reg 17
#define OPERATION_REG 18
#define PF_Reg 25
#define PActive_Reg 10
#define Vrms_Reg 12
#define Irms_Reg 11
#define sync 0xFF
#define ovr_sec 6866
#define ovr_min 4578
#define half_sec 2289
#bit sspbuf0 = 0x13.0
#byte sspbuf = 0x13
#int_rb
void rb_isr(void)
{
int1 state_b7,state_b4;
output_bit(pin_b5,!input_state(pin_b5));
delay_ms(10);
if (input_state(pin_b7) != w)
{
if (input_state(pin_b7))
{
flag_b4 = 1;
w = 1;
}
else
w = 0;
}
if (input_state(pin_b4) != y)
{
if (!input_state(pin_b4))
{
flag_b6 = 1;
y = 0;
}
else
y = 1;
}
state_b7 = input(pin_b7);
state_b4 = input(pin_b4);
}
#use delay(crystal=20000000)
#int_rda
void isr_rda(void)
{
if (counter >= 79)
counter = 0;
flag[counter] = getchar();
counter++;
}
#int_timer0
void isr_timer0(void)
{
output_high(pin_d7);
overflow++;
temp++;
if (temp == 78)
{
flag_blink = 1;
temp = 0;
}
if (overflow == sensor_read - half_sec)
{
flag_sensor = 1;
}
clear_interrupt(int_timer0);
output_low(pin_d7);
}
//---------------------------------
int32 CS5463_read_reg(int8 reg)
{
int8 msb, mid, lsb,temp;
int32 retval;
output_low(CS); //slave select
temp = spi_read(reg << 1); //send read command
msb = spi_read(sync); //read msb mid and lsb by sending sync commands
mid = spi_read(sync);
lsb = spi_read(sync);
output_high(CS);
retval = make32(0, msb, mid, lsb);
return(retval);
}
//---------------------------------
void CS5463_write_reg(int8 reg, int8 msb, int8 mid, int8 lsb)
{
output_low(CS);
spi_write((reg << 1) | 0x40); // OR with Write bit
spi_write(msb);
spi_write(mid);
spi_write(lsb);
output_high(CS);
}
//---------------------------------
void sync_port(void)
{
output_low(CS);
spi_write(0xFF);
spi_write(0xFF);
spi_write(0xFF);
spi_write(0xFE);
output_high(CS);
}
//---------------------------------
void start_conv(void)
{
output_low(CS);
spi_write(0xE8);
output_high(CS);
}
//---------------------------------
void ac_offset_calibration(void)
{
CS5463_write_reg(AC_V_Offset_Reg,0,0,0);
CS5463_write_reg(AC_I_Offset_Reg,0,0,0);
output_low(CS);
spi_write(0xDD); //voltage and current ac offset command
output_high(CS);
}
//---------------------------------
void ac_gain_calibration(void)
{
CS5463_write_reg(AC_V_Gain_Reg,64,0,0);
CS5463_write_reg(AC_I_Gain_Reg,64,0,0);
output_low(CS);
spi_write(0xDE); //AC V and I Gain Calibration command
output_high(CS);
}
//---------------------------------
//===============================
void main()
{
Gen_Params params1;
Gen_Params *params1_ptr;
params1_ptr = ¶ms1;
//varaibles initialization
params1.v = 0; params1.i = 0; params1.ccr =0; params1.pf = 0;
params1.fuel_level = 0; params1.vol_batt = 0; params1.pressure_sw = 0; params1.temp_sw = 0; params1.tmpr = 0;
flag_b4 = 0;flag_b6 = 0;
counter = 0; overflow = 0;overflow1 = 0; sensor_read = 0; state = 0;temp = 0;
output_high(pin_b6);
delay_ms(1000);
output_low(pin_b6);
delay_ms(1000);
init_CS5463();
params1.v = CS5463_read_reg(Vrms_Reg);
if (params1.v > v_thresh)
{
overflow1 = ovr_sec;
}
else
{
overflow1 = ovr_min;
params1.v = 0;
params1.pf = 0;
}
sensor_read = overflow1;
init_pic1();
init_gsm_mod();
flag_blink = 0;
int16 overflow1 = 0;
while (!mod_test())
{
}
w = input(pin_b7);
y = input(pin_b4);
z = input(pin_d4);
init_pic2();
while(TRUE)
{
output_high(pin_b0);
if (flag_b4 == 1)
{
flag_b4 = 0;
calculate_CS5463(params1_ptr);
output_high(pin_b1);
output_high(pin_b2);
while (!send_sms1(params1_ptr))
{
}
output_low(pin_b1);
output_low(pin_b2);
}
if (flag_b6 == 1)
{
flag_b6 = 0;
calculate_CS5463(params1_ptr);
output_high(pin_b3);
output_high(pin_b2);
while (!send_sms1(params1_ptr))
{
}
output_low(pin_b2);
output_low(pin_b3);
}
output_low(pin_b0);
output_high(pin_d7);
if (flag_blink == 1)
{
output_bit(LED_Blink,!input_state(LED_Blink));
flag_blink = 0;
}
if (flag_sensor == 1)
{
read_sensor(params1_ptr);
}
if (overflow > overflow1)
{
output_high(pin_b2);
calculate_CS5463(params1_ptr);
while (!send_sms1(params1_ptr))
{
}
output_low(pin_b2);
overflow = 0;
}
if (params1.v > v_thresh)
{
overflow1 = ovr_sec;
}
else
{
overflow1 = ovr_min;
}
output_low(pin_d7);
}
}
int mod_test()
{
int index = 0;
counter = 0;
int overflow_mod = overflow;
strcpy(flag,"no");
printf("AT+CMGF=1");
putchar(0x0D);
output_bit(pin_b5,1);
delay_ms(500);
while ((counter <= 7) && (overflow < (overflow_mod + 10)))
{
}
output_bit(pin_b5,0);
for (index = 0; index <= 12; index++)
{
if (flag[index] == 'O' && flag[index + 1] == 'K')
{
delay_ms(500);
return 1;
}
}
delay_ms(500);
return 0;
}
int send_sms1(Gen_Params *ptr)
{
int index = 0;
counter = 0;
strcpy(flag,"no");
//printf("AT+CMGS=\"03012118327\"");//Riaz sahab ufone sim
printf("AT+CMGS=\"03332097014\"");
putchar(0x0D);
delay_ms(500);
float vfinal = ((float)ptr->v / 16777216)*355.38;
float ifinal = ((float)ptr->i / 16777216)*90.6;
while (counter <= 7)
{
}
for (index = 0; index <= 28; index++)
{
if (flag[index] == '>')
{
printf("%fV,%fA,%fkW,%f,%fC,%f%%,%fV,%u,%u,%lu\r\n",vfinal,ifinal,vfinal*ifinal*ptr->pf/1000,(float)ptr->pf / 8388608,(float)ptr->vol_batt*2.5/1023,(((float)ptr->fuel_level*5/1023)*187.41)-7.38,((float)ptr->tmpr*16/1023),ptr->temp_sw,ptr->pressure_sw,ptr->ccr);
// else
// printf("%fV,%fA,%fkW,%f,%f,%fC,%f%%,%fV,%u,%u,%lu\r\n",((float)v / 16777216)*378.3,((float)i / 16777216)*90.6,((float)v / 16777216)*378.3*((float)i / 16777216)*90.6*pf_corr/1000,(float)pf / 8388608,pf_corr,-34 * log((float)vol_batt*5/1023) + 48,(((float)fuel_level*5/1023)*63.83)-5.32,((float)tmpr*16/1023) - 0.6,temp_sw,pressure_sw,ccr);
//printf("%fV,%fA,%fkW,%f,%f,%fC,%f%%,%fV,%u,%u,%lu\r\n",((float)v / 16777216)*378.3,((float)i / 16777216)*90.6,((float)v / 16777216)*378.3*((float)i / 16777216)*90.6*((float)pf_signed / 8388608)/1000,(float)pf_signed / 8388608,pf_corr,-33 * log((float)vol_batt*5/1023) + 81,(((float)fuel_level*5/1023)*63.83)-5.32,(float)tmpr*16/1023,temp_sw,pressure_sw,ccr);
//printf("%fV,%fA,%fkW,%f,%fC,%f%%,%u,%u,%lu\r\n",((float)v / 16777216)*378.3,((float)i / 16777216)*90.6,((float)v / 16777216)*378.3*((float)i / 16777216)*90.6*((float)pf_signed / 8388608)/1000,(float)pf_signed / 8388608,-34 * log((float)vol_batt*5/1023) + 87,(((float)fuel_level*5/1023)*63.83)-5.32,temp_sw,pressure_sw,ccr);
delay_ms(500);
putchar(0x1A);
return 1;
}
}
delay_ms(500);
return 0;
}
void init_gsm_mod()
{
output_bit(pin_b5,1);
delay_ms(11000);
output_bit(pin_b5,0);
strcpy(flag,"no");
counter = 0;
}
void init_CS5463()
{
setup_spi(SPI_MASTER|SPI_SCK_IDLE_LOW|SPI_CLK_DIV_64|SPI_XMIT_L_TO_H); //set up spi module
sync_port();
CS5463_write_reg(CS5463_EPILSON_REG,1,163,111);
CS5463_write_reg(OPERATION_REG,0,0,96); // turn high pass filter on
delay_ms(500);
CS5463_write_reg(CS5463_CONFIG_REG,1,0,1);
delay_ms(1000);
CS5463_write_reg(AC_I_Gain_Reg,70,134,146);
CS5463_write_reg(AC_V_Gain_Reg,63,25,194);
start_conv();
delay_ms(500);
output_low(CS); // turn high pass filter on
CS5463_write_reg(OPERATION_REG,0,0,97);
}
void init_pic1()
{
setup_adc_ports(AN0_AN1_AN2_AN3_AN4);
setup_adc(ADC_CLOCK_DIV_32);
output_high(CS);
enable_interrupts(global);
enable_interrupts(int_rda);
setup_timer_0(T0_DIV_256);
enable_interrupts(INT_TIMER0);
}
void init_pic2()
{
enable_interrupts(int_rb);
}
void read_sensor(Gen_Params *ptr1)
{
switch (state)
{
case 0:
set_adc_channel(0);
flag_sensor = 0;
sensor_read = sensor_read + 35;
state++;
break;
case 1:
flag_sensor = 0;
ptr1->fuel_level = read_adc();
sensor_read = sensor_read + 35;
output_high(pin_d0);
state++;
break;
case 2:
set_adc_channel(1);
flag_sensor = 0;
sensor_read = sensor_read + 35;
state++;
break;
case 3:
flag_sensor = 0;
ptr1->vol_batt = read_adc();
sensor_read = sensor_read + 35;
output_low(pin_d0);
state++;
break;
case 4:
flag_sensor = 0;
set_adc_channel(4);
sensor_read = sensor_read + 35;
state++;
break;
case 5:
flag_sensor = 0;
ptr1->tmpr = read_adc();
state = 0;
sensor_read = overflow1;
break;
}
}
void calculate_CS5463(Gen_Params *ptr2)
{
ptr2->i = CS5463_read_reg(Irms_Reg);
if (ptr2->i < i_thresh)
{
ptr2->i = 0;
ptr2->pf = 0;
}
else
ptr2->pf = CS5463_read_reg(PF_Reg);
ptr2->ccr = CS5463_read_reg(Cycle_Count_Reg);
ptr2->pressure_sw = input_state(pin_b4);
ptr2->temp_sw = input_state(pin_b7);
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Fri May 06, 2016 2:20 am |
|
|
You don't need to clear your timer interrupt at the end of it's call. Minor, but a wasted instruction.
However, a suggestion.
I've not looked at how 'frequent' your timer tick actually is, but you could approach your debounce two different ways:
First one, is to not have int_rb at all....
If your timer tick is reasonably frequent, then just test the inputs in your timer interrupt. If the port changes, record this, then if it is the same in the _next_ interrupt, process the inputs. If your tick is at any reasonable frequency, this is a much better solution than using int_rb and a delay.
As I said, I suspect the core 'reason' behind your data getting out of sync, so the counter overflows, is the characters being lost in the delay....
Second solution is to use another timer. If you are not using timer1 for instance, then when int_rb occurs, just clear this timer's interrupt, program it with a value that will timeout in (say) 10mSec, enable it's interrupt, and exit.
It doesn't matter if the int_rb then triggers again, it'll just reset the same timer.
Move INT_RDA above the INT_RB, then if both happen at the same time, this interrupt will have priority (or you can use #priority to do the same).
Then when this timer interrupts do your tests, and then disable this timer.
Result in either case, is that the processor is not stuck sitting inside an interrupt handler, and blocking anything else from being handled. |
|
|
mka879
Joined: 30 Oct 2015 Posts: 34
|
|
Posted: Fri May 06, 2016 11:33 pm |
|
|
Ttelmah wrote: | You don't need to clear your timer interrupt at the end of it's call. Minor, but a wasted instruction.
However, a suggestion.
I've not looked at how 'frequent' your timer tick actually is, but you could approach your debounce two different ways:
First one, is to not have int_rb at all....
If your timer tick is reasonably frequent, then just test the inputs in your timer interrupt. If the port changes, record this, then if it is the same in the _next_ interrupt, process the inputs. If your tick is at any reasonable frequency, this is a much better solution than using int_rb and a delay.
As I said, I suspect the core 'reason' behind your data getting out of sync, so the counter overflows, is the characters being lost in the delay....
Second solution is to use another timer. If you are not using timer1 for instance, then when int_rb occurs, just clear this timer's interrupt, program it with a value that will timeout in (say) 10mSec, enable it's interrupt, and exit.
It doesn't matter if the int_rb then triggers again, it'll just reset the same timer.
Move INT_RDA above the INT_RB, then if both happen at the same time, this interrupt will have priority (or you can use #priority to do the same).
Then when this timer interrupts do your tests, and then disable this timer.
Result in either case, is that the processor is not stuck sitting inside an interrupt handler, and blocking anything else from being handled. |
Thank you so much. Most of the problems have now vanished and the code has become more predictable and responsive than before. There is just one minor issue which I shall post in a new topic. |
|
|
|
|
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
|