|
|
View previous topic :: View next topic |
Author |
Message |
Zloi
Joined: 26 Oct 2012 Posts: 11 Location: Croatia
|
I need advice, multitasking goes out of synchronization |
Posted: Fri Oct 26, 2012 12:05 pm |
|
|
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: 19537
|
|
Posted: Fri Oct 26, 2012 1:18 pm |
|
|
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
|
|
Posted: Fri Oct 26, 2012 4:10 pm |
|
|
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 |
|
|
|
|
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
|