[代码分享]一个LED状态模块,支持亮、灭时间和闪烁次数设定
本帖最后由 Jmhh247 于 2015-8-2 20:07 编辑今天有闲暇的时间,整理了一个我常用的LED模块,分享出来,希望对大家有用,同时交流。
我有个习惯就是在含有MCU的设计中,在资源允许时,都会用一颗LED指示设备的运行状态,没这个状态指示心里就会
觉得不踏实,不知道大家是不是喜欢这样干……相信有些人是喜欢的,反正,我觉得自己的强迫症是治不好了……就是在
这个背景下我写下了这个LED模块以复用。
好了,说重点:
首先是功能描述:
这个LED模块的主要功能就是做一些简单的状态指示,如闪烁、亮、灭这些基本的状态,这些状态支持时间或次数
的设定,模块的工作是基于状态机的,符合C99,便于移植复用。
接着是模块使用:
模块包含两个文件,解压后得到一个 zlib_led.c 文件 和 一个 zlib_led.h 文件,随后我会给出一个stm32平台下
的 demo 供参考。
模块的接口函数有三个如下,初始化,用户设置,循环服务,非常典型的应用层驱动写法,我喜欢这种写法{:lol:} 。
bool zl_led_init(zlfn_led_t fn_led_on, zlfn_led_t fn_led_off);
void zl_led_flash_set(uint8_t chFlashCnt, uint16_t hwOnTime, uint16_t hwOffTime);
void zl_led_flash_loop(void);
模块的使用很简单,首先把两个文件添加到你的工程中,然后提供两个函数,一个负责关闭LED,一个负责
点亮LED,下面是我在 demo 中的实现
static void led_on(void)
{
GPIO_ResetBits(LED_PORT, LED_Pin_0);
}
static void led_off(void)
{
GPIO_SetBits(LED_PORT, LED_Pin_0);
}
完成这两个最基础的函数以后,就可以调用LED模块的初始化函数了,入参就是上面两个函数的指针,像这样
zl_led_init(led_on, led_off); /* 初始化 LED 模块 */
接着就是调用 ZL LED 模块的循环服务函数,它需要周期运行,我一般是把它放在一个 1ms 的时标中断里
/* S T _ S Y S T I C K _ I R Q _ S E R V I C E */
/*-------------------------------------------------------------------------
* 功能:时标服务,在 systick 中断里运行。
* 参数:无
* 返回:无
* 备注:OK.
-------------------------------------------------------------------------*/
void st_systick_irq_service(void)
{
zl_led_flash_loop(); /* zl led loop service */
st_systick_delay_loop(); /* st systick delay loop service */
}
现在就可以使用LED模块了,用户只要调设置函数即可,它有三个参数,见注释
/* Z L _ L E D _ F L A S H _ S E T */
/*-------------------------------------------------------------------------
* 功能:设置LED闪烁参数。
* 参数:1.闪烁次数,等于0表示无限次闪烁;
* 2.亮时间,等于0表示不亮;
* 3.灭时间,等于0表示不灭。
* 返回:无
* 备注:OK.
-------------------------------------------------------------------------*/
void zl_led_flash_set(uint8_t chFlashCnt, uint16_t hwOnTime, uint16_t hwOffTime)
{
/* 更新相关参数 */
s_chFlashCnt = chFlashCnt;
s_hwFlashOnTime= hwOnTime;
s_hwFlashOffTime = hwOffTime;
/* 复位状态机 */
s_chFlashFsmSta = 0;
}
需要说明的是,亮、灭时间的长度zl_led_flash_loop()的调用周期有关,在 demo 中
它是 1ms 中断里调用,所以设置的时间时基就是 1ms.
例子1,LED需要闪烁 10 次,亮时间是 30ms , 灭时间是 800ms , 可以这样设置
zl_led_flash_set(10, 30, 800); /* 设置 LED 状态,闪烁10次,亮 60ms,灭 800ms */
例子2,LED需要一直闪烁,亮时间是 600ms , 灭时间是 50ms , 可以这样设置
zl_led_flash_set(0, 600, 50); /* 设置 LED 状态,一直闪烁,亮 600ms,灭 50ms */
最后的说明:
从数据驱动的角度来讲,ZL LED 模块用于 BEEP 也是不错的选择,相信不少人也喜欢在设计
中这么干……需要注意的一点是,我这个模块并未考虑到数据的原子保护,需要用在严谨的
设计场合时,请自行修改源码……
就说这么多吧,有什么想起来后面再补充,欢迎交流,附件里有一个整理干净的 demo ……{:sleepy:}
沙发自己占了,居然写了一个多小时……不知道发这个版块合适不,发帖的时候没看版块{:sweat:} 有个led调试其他东西也会方便多 不错挺有用的 楼主思路清洗,分层明确,有一个指示灯非常有用 关键的两个函数没有贴出
zl_led_flash_loop(); /* zl led loop service */
st_systick_delay_loop(); /* st systick delay loop service */ 呵呵哈哈哈 本帖最后由 foxpro2005 于 2015-8-2 21:56 编辑
给你顶一个,很早以前就写了一个类似的模块, LED状态指示, 闪亮支持N多种显示方式,故障码指示, 比如:一长二短, 一长五短, 并且支持它们的混合显示。
刚看了一下源码,原理基本类似, 不过我增加了一个功能,可以支持,它们多种闪烁指示同时存在, 它们采用依次循环显示。(即可同时指示多种故障信息) 目前蜂鸣器就是这么干的,不过没用函数指针,用的宏 嗯,模块化思想最好了 思想很好,赞一个 很好,先mark~~ 写的很不错,谢谢楼主分享 用上了,很好 好,谢谢分享! xujihu 发表于 2015-8-2 20:14
有个led调试其他东西也会方便多
嗯嗯,led能再加个串口就更爽了 nydxsydt0 发表于 2015-8-2 20:16
不错挺有用的
谢谢肯定,用用看呀,有 bug 回头给我说说 lxk52000 发表于 2015-8-3 00:27
用上了,很好
对你有用真是太好了,我自己一直在用的,遇到 bug 的话给我说说呀 lovecxm 发表于 2015-8-2 20:58
楼主思路清洗,分层明确,有一个指示灯非常有用
谢谢肯定,看来你也喜欢指示灯{:smile:} 我也喜欢用led指示一下,不错 miaoguoqiang 发表于 2015-8-2 21:22
关键的两个函数没有贴出
zl_led_flash_loop(); /* zl led loop service */
st_syst ...
是我的问题,确实没贴出……因为有点长,担心影响阅读……但是附件的 demo 里有呀,你一定没下载看吧,看贴要认真呢{:titter:} pchf005 发表于 2015-8-2 21:42
呵呵哈哈哈
弱弱的问句,大哥,你这是几个意思呀……{:sleepy:} foxpro2005 发表于 2015-8-2 21:50
给你顶一个,很早以前就写了一个类似的模块, LED状态指示, 闪亮支持N多种显示方式,故障码指示, 比如: ...
你很厉害,我目前还写不出来你说的,惭愧呀……你说的循环显示,是指用的还是同一个LED,对吗?
如果是这样的话,建一个可以支持添加、删除LED状态参数的队列(或着类似队列吧),根据闪烁次数
与整体的故障数量,做为状态切换依据,然后循环,应该能完成类似你说的功能吧……不过说是这样说,
写起来还是有实现难度的,现在我还没时间做,以后有机会,可以试试看。
你用的这个功能真的挺不错{:handshake:} ijlc1314 发表于 2015-8-2 21:57
目前蜂鸣器就是这么干的,不过没用函数指针,用的宏
我以前也用宏,宏还显得精简一些,可是不知道后来就莫名的喜欢用函数指针了…… mark,以备以后查用 led我的最爱~ soos 发表于 2015-8-2 22:03
嗯,模块化思想最好了
是啊,最近我一直都在思考模块化与复用,也在尝试着这样做,为的是以后能偷点懒,毕竟我使用的平台比较固定,不想再学新东西了{:titter:} 我有一个需求,比如,亮(10ms)->灭(20ms)->亮(10ms)->灭(20ms)->亮(10ms)->灭(1000ms) 如此不停循环 TCMCU 发表于 2015-8-2 22:13
思想很好,赞一个
谢谢{:smile:} yick 发表于 2015-8-2 22:24
很好,先mark~~
用用看{:smile:} aaabbbad 发表于 2015-8-2 22:54
写的很不错,谢谢楼主分享
谢谢,谢谢,用用看,看看有改进的地方没{:smile:} nnnkey 发表于 2015-8-3 00:43
好,谢谢分享!
谢谢肯定{:smile:} 我也是,做东西必须加个指示灯。我的程序没有你的复杂,只考虑亮和灭没考虑时间。 这个不错,拿走了。很好用 函数指针,调用方便 Jmhh247 发表于 2015-8-3 09:29
我以前也用宏,宏还显得精简一些,可是不知道后来就莫名的喜欢用函数指针了…… ...
我用的一般都是小资源的单片机,用不起函数指针,有些编译器也不支持 youkebing 发表于 2015-8-3 09:33
我有一个需求,比如,亮(10ms)->灭(20ms)->亮(10ms)->灭(20ms)->亮(10ms)->灭(1000ms) 如此不 ...
目前的模块还不支持,你说的这个需求就是 8 楼坛友提到的,他已经实现了这个功能……你可以尝试着修改下源码去实现,可能要花点时间,但难度不会太大……我目前没时间做改动{:sleepy:} laojiao 发表于 2015-8-3 09:13
我也喜欢用led指示一下,不错
{:smile:} xingjianpeng 发表于 2015-8-3 09:30
mark,以备以后查用
希望对你是有用的。{:smile:} 蓝蓝的恋 发表于 2015-8-3 09:30
led我的最爱~
{:smile:} 留声而过 发表于 2015-8-3 10:00
我也是,做东西必须加个指示灯。我的程序没有你的复杂,只考虑亮和灭没考虑时间。 ...
哦,我的程序也不复杂的,加入时间设定后,就能灵活的展示更多的状态,就算是做一个简单的运行指示状态,
你也可以完全设定一个自己喜欢的亮灭时间进行闪烁……试用一下,绝对好玩{:titter:} icevel 发表于 2015-8-3 12:13
这个不错,拿走了。很好用
{:smile:} makathy 发表于 2015-8-3 15:56
函数指针,调用方便
{:smile:} ijlc1314 发表于 2015-8-3 20:21
我用的一般都是小资源的单片机,用不起函数指针,有些编译器也不支持
确实要看具体情况,我用stm32的时候较多,其次是stm8,资源总是够用的,现在想起来用函数指针是因为
我的水平比较菜,大多时候都需要仿真,从这个角度讲,函数指针比宏要方便些……如果让我用那些小资源单
片机,可能它们还不支持仿真,像我这么菜,估计什么都做不出来了{:sweat:} 顶,MARK备用 foxpro2005 发表于 2015-8-2 21:50
给你顶一个,很早以前就写了一个类似的模块, LED状态指示, 闪亮支持N多种显示方式,故障码指示, 比如: ...
很有兴趣
foxpro2005 能说说实现的思路吗? 不错,用在beep很好 我也这么做过 这种程序LED输出时长只有两种状态, 即高电平时间和低电平时间,如果想要LED输出多种高低电平的时间,这个程序就不适用了.我一般用查表法. Jmhh247 发表于 2015-8-3 21:03
确实要看具体情况,我用stm32的时候较多,其次是stm8,资源总是够用的,现在想起来用函数指针是因为
我的 ...
小资源的单片机也是支持仿真的,只是如台系或是51,对函数指针的支持并不好或者是不根本就不支持 ijlc1314 发表于 2015-8-4 21:40
小资源的单片机也是支持仿真的,只是如台系或是51,对函数指针的支持并不好或者是不根本就不支持 ...
感谢科普,涨姿势了{:lol:} ponder2077 发表于 2015-8-4 15:38
这种程序LED输出时长只有两种状态, 即高电平时间和低电平时间,如果想要LED输出多种高低电平的时间,这个程序 ...
是的,查表很好。 实用的好东西,收藏。 mark mark
一下:
[代码分享]一个LED状态模块,支持亮、灭时间和闪烁次数设定 这个状态机限制了只能使用一个LED。其实我也在考虑用状态机来做,但是想了之后好像每控制一个LED都需要一个状态机。
Yvan 发表于 2016-4-16 20:38
这个状态机限制了只能使用一个LED。其实我也在考虑用状态机来做,但是想了之后好像每控制一个LED都需要一个 ...
你说的非常正确。因为这个模块的设计需求,只是一个LED。……如果想控制多个,也很简单,
把与LED相关的变量做成结构体,状态算法的参数使用结构体指针,稍做修改就能控制多个了。 MARK一下,备用。 mark一下 后面要用到 模块化做的不错,mark一下 这么久了,今天突然有人回复了。。。 可以设置固定的时间闪烁的次数吗? 写代码走火入魔了吧,搞个灯还要闪,卡卡的那种 lnso 发表于 2023-8-28 17:12
可以设置固定的时间闪烁的次数吗?
(引用自62楼)
看看这个//单片机裸机实用组件--LED
https://blog.csdn.net/weixin_42378319/article/details/121938899?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522169321497916800225598014%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=169321497916800225598014&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-2-121938899-null-null.142^v93^chatsearchT3_1&utm_term=%E5%8D%95%E7%89%87%E6%9C%BA%E8%A3%B8%E6%9C%BA%E5%AE%9E%E7%94%A8%E7%BB%84%E4%BB%B6&spm=1018.2226.3001.4187 ibmx311 发表于 2023-8-28 17:24
写代码走火入魔了吧,搞个灯还要闪,卡卡的那种
(引用自63楼)
挺好的啊。。。本来就应该这么设计,把具体平台无关的逻辑抽象出来,平台相关代码用回调函数实现。
我还搞过按莫尔斯电码输出,具体怎么输出交给回调函数,蜂鸣器也行,LED也行。
页:
[1]