我需要在附图中产生第三轴(Resulting_pattern)中显示的LED闪烁模式
我决定用两个软件振荡器实现这个功能。 第一个振荡器产生周期为500 ms的脉冲信号。第二个 产生周期为5000 ms的脉冲信号。两个振荡器的输出都是 由逻辑AND处理以产生信号。
软件振荡器以下列方式实现。有一个功能 在我的源代码中称为OSC,各个实例由C struct建模。
typedef struct{
float period; // period of the oscillations (ms)
BOOL start; // oscillator start signal (start==TRUE, stop==FALSE)
BOOL init; // init==TRUE, initialize timer
float delta; // timeout for negation the output
uint16_t start_time; // captured state of the appropriate system timer
uint16_t cycle_cnt; // current cycle count
TIMER tmr; // used system timer
}Osc_t;
void OSC(uint32_t output, Osc_t *p){
uint16_t act_time;
uint16_t elap_time;
// oscillator start required?
if(p->start){
// reading value of system timer
taskENTER_CRITICAL();
switch(p->tmr){
case T1MS:
act_time = Tmr_1ms;
break;
case T10MS:
act_time = Tmr_10ms;
break;
case T100MS:
act_time = Tmr_100ms;
break;
}
taskEXIT_CRITICAL();
// capture current state of appropriate system timer
if(p->init){
p->start_time = act_time;
p->init = FALSE;
}
// half period based on desired period and system timer used
switch(p->tmr){
case T1MS:
p->delta = ((p->period)/2);
break;
case T10MS:
p->delta = ((p->period)/(2*10));
break;
case T100MS:
p->delta = ((p->period)/(2*100));
break;
}
// current elapsed time
elap_time = (act_time - (p->start_time));
// half period elapsed?
if(elap_time >= (p->delta)){
// one cycle
if(TestIfLogicSignalSet(output)){
p->cycle_cnt++;
}
NegLogicSignal(output);
p->start_time = act_time;
}
}else{
ClearLogicSignal(output);
p->cycle_cnt = 0;
p->init = TRUE;
}
}
我定义了几个名为Tmr_1ms的全局变量(“软件定时器”), Tmr_10ms和Tmr_100ms用于计时目的。这些变量递增 每1 ms调用一次ISR
// 1 ms counter
Tmr_1ms++; // 0 ms - 65535 ms
// 10 ms counter
if(++cnt_01 == 10){
Tmr_10ms++; // 0 ms - 655350 ms
cnt_01 = 0;
}
// 100 ms counter
if(++cnt_02 == 100){
Tmr_100ms++; // 0 ms - 6553500 ms
cnt_02 = 0;
}
振荡器实例使用的软件定时器由TIMER tmr项决定 在Osc_t struct。
// system timers
typedef enum{
T100MS,
T10MS,
T1MS
}TIMER;
完整的实施如下
// main oscillator init
Main_Oscillator_state.period = 500; // 500 ms
Main_Oscillator_state.tmr = T1MS;
Main_Oscillator_state.init = TRUE;
// mask oscillator init
Mask_Oscillator_state.period = 5000; // 5000 ms
Mask_Oscillator_state.tmr = T1MS;
Mask_Oscillator_state.init = TRUE;
Main_Oscillator_state.start = TRUE;
Mask_Oscillator_state.start = TRUE;
// main oscillator
OSC(LMainOsc, &Main_Oscillator_state);
// mask oscillator
OSC(LMaskOsc, &Mask_Oscillator_state);
// resulting alarm blinking pattern
AND_02(LBlinkPat, LMainOsc,DIR, LMaskOsc,DIR);
问题是这个实现只在我放置的情况下才有用 OSC和AND_02函数进入ISR,每1 ms调用一次。如果我放置 这些函数进入ISR,每20 ms调用一次就会出现错误 闪烁模式(所得模式中的第一个和第五个脉冲具有 有时候持续时间较短)有没有人知道可能是什么原因?我需要将OSC和AND_02函数调用放入20 ms的ISR中。 我的想法是,这种不准确性是由在20 ms ISR中读取Tmr_1ms引起的 以及振荡半周期为250 ms(= 12.5 * 20 ms,即20 ms不是整数倍)和2500 ms(= 125 * 20 ms)的事实。