LED闪烁顺序

时间:2018-11-30 13:51:00

标签: c multithreading microcontroller

我有一个易失的无符号字符数组LedState [9]变量,该变量在线程之间共享。数组中的每个索引表示一个状态。根据每个状态,LED将以不同的顺序闪烁。一个线程设置阵列中的状态,而另一个基于阵列索引的线程将使LED闪烁。每个状态维护一组数组的ontimer和offtimer。

无符号长TimersForBlueLedOn [] = {100,200,500,1,0,0,100,200,500};

无符号长TimersForBlueLedOff [] = {100,200,500,0,0,0,100,200,500};

在主线程中,遍历数组中的每个状态,并检查该状态是否打开。 如果状态为开,我将使LED闪烁以获取与状态相对应的计时器值。

例如:状态2必须在500毫秒内处于开启状态,而在毫秒内处于关闭状态。我们继续处于状态2,直到设置了状态3。状态3的ON计时器为1,没有OFF计时器,这意味着LED应该一直保持点亮状态。

状态3是基本状态,即状态3之后的任何状态,应根据计时器闪烁并返回状态3。
例如,在状态3之后,LED蓝灯会亮起,在设置状态6时,LED灯应闪烁100毫秒,关闭100毫秒。指示灯应闪烁,直到状态6关闭,然后返回状态3。因此,基本上,这是基于优先级的。如果状态7也为ON,则在完成状态6之后,它应该闪烁状态7,直到状态7为OFF并返回状态3。

我的问题是,闪烁始终像闪烁一样,因为状态3始终处于设置状态。我需要进行无状态转换。我无法根据下一个状态关闭状态3。

activator clean cleanFiles compile

1 个答案:

答案 0 :(得分:0)

目前,仍然缺少完整分析所需的信息,但现在可以提出这些改进建议。

1)通过将0的值分配给LEDState变量,您正在写入volatile

void TurnOffLed(ModemState state) {
    LEDState[state] = 0;
}

您不应这样做。 These should be read only 。无论如何,您描述的方法中没有任何内容指示需要volatile。 (除非您的硬件或应用程序外部的其他进程正在访问LEDState[i],否则)。
此变量数组需要由程序中的所有 线程进行更新的事实并不需要将其设置为volatile。您的数组在每个线程中都有一个专用元素这一事实就足够了,只要您严格限制对每个元素对其各自线程的访问,使用此方法更新状态就可以了。但是此方法不支持使用volatile

More about volatile HERE

2)您声明数组中的每个索引表示一个状态。 易失性阵列仅可容纳5个状态,但是您在描述中最多提及7个状态。 (稍后,在注释中,您说有9个状态。)明确定义有多少个状态,然后更改数组以支持所有状态:(请注意,数组未创建为volatile,不需要成为。)

#define MAX_STATES 9
unsigned char array LedState[MAX_STATES];

3)考虑为您的switch()使用state machine语句。

... 
switch(i)  {
    case LastBlueState:
    case LastGreenState:        
        // do something
        break;
    case <some other state>
        // do something
        break;
        ...