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

I need advice, multitasking goes out of synchronization

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



Joined: 26 Oct 2012
Posts: 11
Location: Croatia

View user's profile Send private message

I need advice, multitasking goes out of synchronization
PostPosted: Fri Oct 26, 2012 12:05 pm     Reply with quote

I try to blink two led's in multitasking manner, but things are getting out of control, after n first cycle LED's are no longer synchronized. I'm using unsigned arithmetic and timer overflow should not be a problem. my guess is that the source of the error is IF conndition and > operator.
Can someone give me advice?

Here is code snippet,

Code:

#include <18F4620.h>
#device *=16
#fuses HS,NOWDT,NOPROTECT,NOLVP,BROWNOUT
#use delay(crystal=10Mhz, clock=40Mhz)
#use rs232(baud=57600, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8, ERRORS)
#USE FAST_IO (ALL)
#include <string.h>

#define RedTimeToggle 500


#INT_TIMER0
void One_mS_Timer(void){                                 
   set_timer0(Timer0IntCnt);
   Int0Cnt++;                                 
   if(Int0Cnt>19){
      Int0Cnt=0;                              
      Mills++;
   }


struct {                     
.
.
.
unsigned int16 Old_Red_Mills;
.
.   
} Left,Right;





unsigned int16 CalcElapsedTime(unsigned int16 MillsC,unsigned int16 OldMills){      
unsigned int16 calc;
   calc=MillsC - OldMills;
return (calc);
}


void LeftStartCondErr(){
   if (CalcElapsedTime(Mills,Left.Old_Red_Mills) > (unsigned int16)(RedTimeToggle)){
   printf("Left=%lu\r\n",Mills-Left.Old_Red_Mills);
   printf("Mils=%lu\r\n"Mills);
      Left.Old_Red_Mills=Mills;
      if (input_state(LR)){            
         output_low(LR);
         }
      else{
         output_high(LR);
      }

   
}


void RightStartCondErr(void){
   if (CalcElapsedTime(Mills,Right.Old_Red_Mills) > RedTimeToggle){
   Right.Old_Red_Mills=Mills;
      if (input_state(RR)){               
         output_low(RR);

         }
      else{
         output_high(RR);
         
      }
   
}





void main(void){
   main:
   disable_interrupts(GLOBAL);
   SystemInit();
   OutputInit();
   SystemVariableInit();
   FlushBuffers();
   set_pwm1_duty(514);      
   enable_interrupts(INT_TIMER0);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   set_timer0(Timer0IntCnt);          
   printf("\r\n Running....\r\n");
   output_low(PIN_A1);
        Mills=0;   
        LoopTime=Mills;
        Right.Old_Red_Mills=Left.Old_Red_Mills=Mills;
 
      while (true){
           LeftStartCondErr();
           RightStartCondErr();
        }





Here is the Printout:.
Mils=56135
Left=501
Mils=56638
Left=193 -> passed to the comparison condition
Mils=56833
Left=501
Mils=57336
Left=501
Mils=57839
Left=501
Ttelmah



Joined: 11 Mar 2010
Posts: 19448

View user's profile Send private message

PostPosted: Fri Oct 26, 2012 1:18 pm     Reply with quote

Unfortunately,what you post, is a messy bit of tatty code, missing vital parts, and too large for debugging. But some comments:

Remember your printf's,will take about 4mSec.
Remember anything reading or writing an int16, which is updated in an interrupt, needs to _disable_ the interrupt, read/write the value, and then re-enable the interrupt. Otherwise if the value updates between one byte being used and the other, the results _will_ be wrong. Then is is even worse with something slow like a printf.....
Zloi



Joined: 26 Oct 2012
Posts: 11
Location: Croatia

View user's profile Send private message

PostPosted: Fri Oct 26, 2012 4:10 pm     Reply with quote

Ttelmah wrote:
Unfortunately,what you post, is a messy bit of tatty code, missing vital parts, and too large for debugging.

I agree with the comment, program has about 800 lines of code and counting, for purposes of readability I did not want to post everything.
problem with LEDs haunted me for days.

Ttelmah wrote:

But some comments:

Remember your printf's,will take about 4mSec.
Remember anything reading or writing an int16, which is updated in an interrupt, needs to _disable_ the interrupt, read/write the value, and then re-enable the interrupt. Otherwise if the value updates between one byte being used and the other, the results _will_ be wrong. Then is is even worse with something slow like a printf.....


printf were there just for "debugging"...
I tried with disabling interrupts, but without positive result.
btw this is good advice with guarding int6,32 by disabling interrupts.

In the end I set up a free timer3 in main,

Code:

void GetTime(void){
if(get_timer3()>1249){
   set_timer3(0);      
   Mills++;
   }
}


So far everything working as expected.

Best regards
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