C中的LED闪烁模式

时间:2017-09-08 07:49:36

标签: c embedded led

我需要在附图中产生第三轴(Resulting_pattern)中显示的LED闪烁模式

LED blinking pattern

我决定用两个软件振荡器实现这个功能。 第一个振荡器产生周期为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)的事实。

0 个答案:

没有答案