CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Strange math results [Solved]

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



Joined: 06 Apr 2011
Posts: 4

View user's profile Send private message

Strange math results [Solved]
PostPosted: Wed Apr 06, 2011 4:28 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Apr 06, 2011 5:23 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Apr 07, 2011 5:42 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group