|
|
View previous topic :: View next topic |
Author |
Message |
kmp65
Joined: 06 Apr 2011 Posts: 4
|
Strange math results [Solved] |
Posted: Wed Apr 06, 2011 4:28 am |
|
|
I am trying to calculate time it takes a square wave to complete, problem i am facing is compiler seems to fail doing simple arithmetic, hope someone can tall what i am doing wrong here;
compiler 4.114
PIC 18F6722/18F67J10
(6722 for debugging in proteus)
Code: |
#define DProt // Debug in Proteus
#IF DEFINED(DProt)
#include <18F6722.h>
#ELSE
#include <18F67j10.h>
#ENDIF
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES WDT2048 //Watch Dog Timer uses 1:128 Postscale
#FUSES NOWDT //Watch Dog Timer off
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES DEBUG //Debug mode for use with ICD
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NOPROTECT //Code protected from reads
#FUSES NOFCMEN //Fail-safe clock monitor enabled
#FUSES NOIESO //Internal External Switch Over mode enabled
#IFNDEF DProt
#use delay(clock=20000000, RESTART_WDT)
#ELSE
#use delay(clock=20000000)
#ENDIF
#use fixed_io ( a_outputs= )
#use fixed_io ( b_outputs= )
#use fixed_io ( c_outputs=PIN_C6 )
//#use fixed_io ( d_outputs=PIN_D0, PIN_D1 )
#use fixed_io ( e_outputs=PIN_E0, PIN_E1, PIN_E2, PIN_E3, PIN_E4, PIN_E5, PIN_E6, PIN_E7 )
#use fixed_io ( f_outputs= )
#use fixed_io ( g_outputs=PIN_G1 )
#use rs232(baud=9600, xmit=PIN_G1, rcv=PIN_G2, STREAM=COM_PC)
#define high_start 76 //38 //Timer count for 1 sec
byte high_count;
int seconds;
#define RXPin PIN_B0 // RF Remote Data
struct rx_event {
int eventflag;
int16 hi_start;
int16 hi_stop;
int16 lo_start;
int16 lo_stop;
int16 hp_width;
int16 lp_width;
} rxevent;
void rsrx()
{
rxevent.eventflag = 0;
rxevent.hi_start = 0;
rxevent.hi_stop = 0;
rxevent.lo_start = 0;
rxevent.lo_stop = 0;
rxevent.hp_width = 0;
rxevent.lp_width = 0;
}
/******************************************************************************\
* E X T E R N A L I N T E R U P T *
\******************************************************************************/
#INT_EXT
void EXT_ISR()
{
//! disable_interrupts ( INT_EXT ); // enable Timer0 interrupt
disable_interrupts ( GLOBAL ); // enable all interrupts
rxevent.hi_start = get_timer1();
while (input(RXPin));
rxevent.hi_stop = get_timer1();
rxevent.lo_start = get_timer1();
while (!input(RXPin));
rxevent.lo_stop = get_timer1();
rxevent.eventflag = 1;
}
/******************************************************************************\
* T I M E R I N T E R U P T *
\******************************************************************************/
#INT_RTCC //Interrupt procedure
void clock_isr() //called every time RTCC flips from 255 to 0
{
--high_count;
if(high_count==0)
{
++seconds;
high_count=high_start; //Inc SECONDS counter every //38 times to keep time
}
}
/******************************************************************************\
* I N I T I A L I Z E I N T E R R U P T S E T C *
\******************************************************************************/
void startints()
{
set_tris_d(0b00000000);
high_count = high_start;
setup_timer_0( T0_INTERNAL | T0_DIV_256 | T0_8_BIT);
set_timer0(0);
setup_timer_1( T1_INTERNAL | T1_DIV_BY_1 );
set_timer1(0);
ext_int_edge( 0, L_TO_H );
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
//setup_spi2(SPI_SS_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_timer_4(T4_DISABLED,0,1);
setup_ccp1(CCP_OFF);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
//! enable_interrupts ( INT_RTCC ); // enable Timer0 interrupt
enable_interrupts ( INT_EXT ); // enable all interrupts
enable_interrupts ( GLOBAL ); // enable all interrupts
}
void get_pwidth()
{
if (rxevent.hi_stop >= rxevent.hi_start)
rxevent.hp_width = rxevent.hi_stop - rxevent.hi_start;
else
rxevent.hp_width = rxevent.hi_start - rxevent.hi_stop;
if (rxevent.lo_stop >= rxevent.lo_start)
rxevent.lp_width = rxevent.lo_stop - rxevent.lo_start;
else
rxevent.lp_width = rxevent.lo_start - rxevent.lo_stop;
}
// ************************************************************************** //
// ************************** MAIN LOOP ************************* //
// ************************************************************************** //
void main_loop()
{
int sec_now, sec_then;
int16 t1val;
sec_now = seconds + 1;
sec_then = sec_now;
do
{
if ( rxevent.eventflag )
{
get_pwidth();
fprintf(COM_PC, "\r\nHigh Start = %09Lu, Low Start = %09Lu",rxevent.hi_start, rxevent.lo_start);
fprintf(COM_PC, "\r\nHigh Stop = %09Lu, Low Stop = %09Lu\r\n",rxevent.hi_stop, rxevent.lo_stop);
fprintf(COM_PC, "High Pulse = %09Lu, Low Pulse = %09Lu\r\n",rxevent.hp_width, rxevent.lp_width);
rsrx();
set_timer1(0);
enable_interrupts ( INT_EXT ); // enable external interrupt
enable_interrupts ( GLOBAL ); // enable all interrupts
}
} while (TRUE);
}
/******************************************************************************\
* M A I N R O U T I N E *
\******************************************************************************/
void main()
{
seconds = 0;
startints();
rsrx();
main_loop();
}
/* EOF */
output in proteus;
High Start = 000026986, Low Start = 000018361
High Stop = 000007285, Low Stop = 000064251
High Pulse = 000002443, Low Pulse = 000002498
High Start = 000025084, Low Start = 000016459
High Stop = 000015383, Low Stop = 000006813
High Pulse = 000002443, Low Pulse = 000002498
High Start = 000029442, Low Start = 000020817
High Stop = 000009741, Low Stop = 000001171
High Pulse = 000002443, Low Pulse = 000002498
High Start = 000025024, Low Start = 000016399
High Stop = 000015323, Low Stop = 000006753
High Pulse = 000002443, Low Pulse = 000002498
High Start = 000029442, Low Start = 000020817
High Stop = 000009741, Low Stop = 000001171
High Pulse = 000002443, Low Pulse = 000002498
|
Thanks for any help
Last edited by kmp65 on Thu Apr 07, 2011 5:39 am; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Wed Apr 06, 2011 5:23 am |
|
|
There are a number of issues here, including one that is probably causing the problem...
First, when you re-enable the interrupts after having printed the times, the interrupt may well _already_ have triggered. As such the time you then get _will_ be garbage. You need to clear the timer, then clear the interrupt, and only then re-enable it.
The big problem though is disabling global interrupts inside an interrupt. This won't work. When an interrupt is called, the global interrupt flag, is disabled by the _hardware_. So when you arrive in the EXT_ISR handler, the global interrupts are already disabled. There is a special 'return' instruction used at the end of the interrupt handler, which _automatically_ re-enables the global interrupt flag after it executes. This is part of the PIC hardware handling for interrupts. As such, interrupts _will_ be enabled when you exit the routine, and the numbers you see will be changing as you print them, with 'garbage' results....
Separately, how long is the pulse?. Given your interrupt handler is going to be running for the entire duration of a 'high', and 'low' pulse, will this cause timing problems for the RTCC interrupt?.
Why waste time printing 9 digits for a number that can never be more than five digits?.
Best Wishes |
|
|
kmp65
Joined: 06 Apr 2011 Posts: 4
|
|
Posted: Thu Apr 07, 2011 5:42 am |
|
|
Thanks for your help it helped me solve this problem.
This is code which works fine now;
Code: |
#define DProt // Debug in Proteus
#IF DEFINED(DProt)
#include <18F6722.h>
#ELSE
#include <18F67j10.h>
#ENDIF
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES NOWDT //Watch Dog Timer off
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES DEBUG //Debug mode for use with ICD
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NOPROTECT //Code not protected from reads
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOIESO //Internal External Switch Over mode disabled
#IFNDEF DProt
#use delay(clock=20000000) //, RESTART_WDT)
#ELSE
#use delay(clock=20000000)
#ENDIF
#use fixed_io ( a_outputs= )
#use fixed_io ( b_outputs= )
#use fixed_io ( c_outputs=PIN_C6 )
//#use fixed_io ( d_outputs=PIN_D0, PIN_D1 )
#use fixed_io ( e_outputs=PIN_E0, PIN_E1, PIN_E2, PIN_E3, PIN_E4, PIN_E5, PIN_E6, PIN_E7 )
#use fixed_io ( f_outputs= )
#use fixed_io ( g_outputs=PIN_G1 )
#use rs232(baud=9600, xmit=PIN_G1, rcv=PIN_G2, STREAM=COM_PC)
#define high_start 76 //38 //Timer count for 1 sec
byte high_count;
int seconds;
#define RXPin PIN_B0 // RF Remote Data
struct rx_event {
int eventflag;
int16 hi_start;
int16 hi_stop;
int16 lo_start;
int16 lo_stop;
int16 hp_width;
int16 lp_width;
} rxevent[b], trxevent[/b];
void rsrx()
{
[b] trxevent.eventflag = 0;
trxevent.hi_start = 0;
trxevent.hi_stop = 0;
trxevent.lo_start = 0;
trxevent.lo_stop = 0;
trxevent.hp_width = 0;
trxevent.lp_width = 0;[/b]
}
/******************************************************************************\
* E X T E R N A L I N T E R U P T *
\******************************************************************************/
#INT_EXT
void EXT_ISR()
{
[b]if (!rxevent.eventflag) {[/b]
rxevent.hi_start = get_timer1();
while (input(RXPin));
rxevent.hi_stop = get_timer1();
rxevent.lo_start = get_timer1();
while (!input(RXPin));
rxevent.lo_stop = get_timer1();
rxevent.eventflag = 1;
}
}
/******************************************************************************\
* T I M E R I N T E R U P T *
\******************************************************************************/
#INT_RTCC //Interrupt procedure
void clock_isr() //called every time RTCC flips from 255 to 0
{
--high_count;
if(high_count==0)
{
++seconds;
high_count=high_start; //Inc SECONDS counter every //38 times to keep time
}
}
/******************************************************************************\
* I N I T I A L I Z E I N T E R R U P T S E T C *
\******************************************************************************/
void startints()
{
set_tris_d(0b00000000);
high_count = high_start;
setup_timer_0( T0_INTERNAL | T0_DIV_256 | T0_8_BIT);
set_timer0(0);
setup_timer_1( T1_INTERNAL | T1_DIV_BY_1 );
set_timer1(0);
ext_int_edge( 0, L_TO_H );
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
//setup_spi2(SPI_SS_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_timer_4(T4_DISABLED,0,1);
setup_ccp1(CCP_OFF);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
//! enable_interrupts ( INT_RTCC ); // enable Timer0 interrupt
enable_interrupts ( INT_EXT ); // enable all interrupts
enable_interrupts ( GLOBAL ); // enable all interrupts
}
void get_pwidth()
{
[b] trxevent.hi_start = rxevent.hi_start;
trxevent.hi_stop = rxevent.hi_stop;
trxevent.lo_start = rxevent.lo_start;
trxevent.lo_stop = rxevent.lo_stop;
if (trxevent.hi_stop >= trxevent.hi_start)
trxevent.hp_width = trxevent.hi_stop - trxevent.hi_start;
else
trxevent.hp_width = trxevent.hi_start - trxevent.hi_stop;
if (trxevent.lo_stop >= trxevent.lo_start)
trxevent.lp_width = trxevent.lo_stop - trxevent.lo_start;
else
trxevent.lp_width = trxevent.lo_start - trxevent.lo_stop;
[/b]}
// ************************************************************************** //
// ************************** MAIN LOOP ************************* //
// ************************************************************************** //
void main_loop()
{
int sec_now, sec_then;
int16 t1val;
sec_now = seconds + 1;
sec_then = sec_now;
do
{
if ( rxevent.eventflag )
{
[b] disable_interrupts ( GLOBAL ); // enable all interrupts
[/b] get_pwidth();
fprintf(COM_PC, "\r\nHigh Start = %05Lu, Low Start = %05Lu",trxevent.hi_start, trxevent.lo_start);
fprintf(COM_PC, "\r\nHigh Stop = %05Lu, Low Stop = %05Lu\r\n",trxevent.hi_stop, trxevent.lo_stop);
fprintf(COM_PC, "High Pulse = %05Lu, Low Pulse = %05Lu\r\n",trxevent.hp_width/5, trxevent.lp_width/5);
rsrx();
[b] clear_interrupt ( INT_EXT );
[/b] set_timer1(0);
enable_interrupts ( INT_EXT ); // enable external interrupt
enable_interrupts ( GLOBAL ); // enable all interrupts
}
} while (TRUE);
}
/******************************************************************************\
* M A I N R O U T I N E *
\******************************************************************************/
void main()
{
seconds = 0;
startints();
rsrx();
main_loop();
}
/* EOF */
|
Changes made are in bold |
|
|
|
|
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
|