《星星点灯(一)-LED点灯初阶》
《星星点灯(二)-LED点灯中阶》
《星星点灯(三)-LED点灯高阶》
《在嵌入式系统高效实现软定时器-STOpen软件定时器》
《一个用于嵌入式开发的简单可靠的消息系统-STOpen消息系统》
前面几篇文章讲述了我们常用的LED驱动的设计逐渐提高的方法,然后提出了一种消息系统加软件定时器的全新思路来设计如何简单的驱动两颗LED,把一个全新的软件设计架构展现在了你的面前。
有了这个消息系统框架,现在我们就能比较容易的,用非常简单的代码来实现我们的各种流水灯的动作了,你仔细品品,是不是和你知道的流水灯的设计方法完全不一样,而且是那么的简单,优雅,易于扩展。你掌握了这种设计方法和程序设计思路,是不是再也不用没日没夜的加班熬夜了呢?
程序设计并不是一件多么复杂的事情,关键是掌握好模块化设计能力,同时选择最合适的软件架构,辅以稍微的设计技巧和算法,就非常简单的把复杂问题简单化了。
阅读下面代码,请首先阅读前面五篇文章,才能全面系统的理解其精髓。
要设计一个可以随意动作的流水灯,我们首先定义一个表示流水灯操作动作的结构。
#define LED_ACTION_ON 1
#define LED_ACTION_OFF 2
#define LED_ACTION_DELAY 3
typedef struct __tagLedCtrl {
UINT32 action; //LED的动作,可以是多颗LED同时操作
UINT32 led; //如果是on,off led,表示那些led被操作,
//如果是延时动作,就表示这次操作后到下次操作的延迟时间
}LEDCOFIG;
然后,我们定义一个动作序列
const LEDCOFIG LedSet[] = {
{LED_ACTION_ON,LED_1},
{LED_ACTION_DELAY,500}, //配对出现,动作和延时为一组动作,不可缺少
{LED_ACTION_ON,LED_2},
{LED_ACTION_DELAY,500},
{LED_ACTION_ON,LED_3},
{LED_ACTION_DELAY,500},
{LED_ACTION_ON,LED_4},
{LED_ACTION_DELAY,500},
{LED_ACTION_ON,LED_5},
{LED_ACTION_DELAY,500},
{LED_ACTION_ON,LED_6},
{LED_ACTION_DELAY,500},
{LED_ACTION_OFF,LED_1},
{LED_ACTION_DELAY,500},
{LED_ACTION_OFF,LED_2},
{LED_ACTION_DELAY,500},
{LED_ACTION_OFF,LED_3},
{LED_ACTION_DELAY,500},
{LED_ACTION_OFF,LED_4},
{LED_ACTION_DELAY,500},
{LED_ACTION_OFF,LED_5},
{LED_ACTION_DELAY,500},
{LED_ACTION_OFF,LED_6},
{LED_ACTION_DELAY,500},
{LED_ACTION_ON,LED_ALL},
{LED_ACTION_DELAY,500},
{LED_ACTION_OFF,LED_ALL},
{LED_ACTION_DELAY,500},
{LED_ACTION_ON,LED_ALL},
{LED_ACTION_DELAY,500},
{LED_ACTION_OFF,LED_ALL},
{LED_ACTION_DELAY,500},
{LED_ACTION_ON,LED_1|LED_6},
{LED_ACTION_DELAY,200},
{LED_ACTION_ON,LED_2|LED_5},
{LED_ACTION_DELAY,200},
{LED_ACTION_ON,LED_3|LED_4},
{LED_ACTION_DELAY,200},
{LED_ACTION_OFF,LED_3|LED_4},
{LED_ACTION_DELAY,200},
{LED_ACTION_OFF,LED_2|LED_5},
{LED_ACTION_DELAY,200},
{LED_ACTION_OFF,LED_1|LED_6},
{LED_ACTION_DELAY,1000},
};
最后,我们用一个简单的函数来实现流水灯的操作,这个函数的精妙之处在于你可以任意配置各种流水灯的花式,而不需要修改一行代码。
void LedOperation(void)
{
static UINT32 cnt = 0;
LEDCOFIG LedParm;
if(cnt < sizeof(LedSet)/sizeof(LedSet[0]))
{
LedParm = LedSet[cnt]; //读取动作
if(LedParm.action == LED_ACTION_ON)
{
LedOn(LedParm.led);
}
else if(LedParm.action == LED_ACTION_OFF)
{
LedOff(LedParm.led);
}
LedParm = LedSet[cnt+1]; //读取下一个延时时间
SetTimer(TIMER_ID1,LedParm.led,TRUE);
cnt += 2;
if(cnt >= sizeof(LedSet)/sizeof(LedSet[0]))
cnt = 0;
}
}
有没有一点茅塞顿开,眼前一亮的感觉!
如果扩展一下,我们把动作表放到flash里面,可以通过上位机下载,那是不是就变成了一个用户可以自己定义的流水灯设备了,就像大家经常看到的led广告牌一样。
喜欢的关注微信和博客,获取更多设计方法和技巧。
相关问题可以加QQ群‘开源斌哥开发群1’:1090541942讨论