搜索
bottom↓
回复: 64

[代码分享]一个LED状态模块,支持亮、灭时间和闪烁次数设定

  [复制链接]

出0入8汤圆

发表于 2015-8-2 20:07:08 | 显示全部楼层 |阅读模式
本帖最后由 Jmhh247 于 2015-8-2 20:07 编辑

今天有闲暇的时间,整理了一个我常用的LED模块,分享出来,希望对大家有用,同时交流。

我有个习惯就是在含有MCU的设计中,在资源允许时,都会用一颗LED指示设备的运行状态,没这个状态指示心里就会
觉得不踏实,不知道大家是不是喜欢这样干……相信有些人是喜欢的,反正,我觉得自己的强迫症是治不好了……就是在
这个背景下我写下了这个LED模块以复用。


好了,说重点:

首先是功能描述:
这个LED模块的主要功能就是做一些简单的状态指示,如闪烁、亮、灭这些基本的状态,这些状态支持时间或次数
的设定,模块的工作是基于状态机的,符合C99,便于移植复用。


接着是模块使用:

模块包含两个文件,解压后得到一个 zlib_led.c 文件 和 一个 zlib_led.h 文件,随后我会给出一个stm32平台下
的 demo 供参考。

模块的接口函数有三个如下,初始化,用户设置,循环服务,非常典型的应用层驱动写法,我喜欢这种写法
  1. bool zl_led_init(zlfn_led_t fn_led_on, zlfn_led_t fn_led_off);
  2. void zl_led_flash_set(uint8_t chFlashCnt, uint16_t hwOnTime, uint16_t hwOffTime);
  3. void zl_led_flash_loop(void);
复制代码


模块的使用很简单,首先把两个文件添加到你的工程中,然后提供两个函数,一个负责关闭LED,一个负责
点亮LED,下面是我在 demo 中的实现
  1. static void led_on(void)
  2. {
  3.     GPIO_ResetBits(LED_PORT, LED_Pin_0);
  4. }


  5. static void led_off(void)
  6. {
  7.     GPIO_SetBits(LED_PORT, LED_Pin_0);
  8. }
复制代码



完成这两个最基础的函数以后,就可以调用LED模块的初始化函数了,入参就是上面两个函数的指针,像这样
  1.     zl_led_init(led_on, led_off);      /* 初始化 LED 模块 */
复制代码


接着就是调用 ZL LED 模块的循环服务函数,它需要周期运行,我一般是把它放在一个 1ms 的时标中断里
  1. /*   S T _ S Y S T I C K _ I R Q _ S E R V I C E   */
  2. /*-------------------------------------------------------------------------
  3.     * 功能:时标服务,在 systick 中断里运行。
  4.     * 参数:无
  5.     * 返回:无
  6.     * 备注:OK.
  7. -------------------------------------------------------------------------*/
  8. void st_systick_irq_service(void)
  9. {
  10.     zl_led_flash_loop();                /* zl led loop service */
  11.     st_systick_delay_loop();            /* st systick delay loop service */
  12. }
复制代码


现在就可以使用LED模块了,用户只要调设置函数即可,它有三个参数,见注释
  1. /*   Z L _ L E D _ F L A S H _ S E T   */
  2. /*-------------------------------------------------------------------------
  3.     * 功能:设置LED闪烁参数。
  4.     * 参数:1.闪烁次数,等于0表示无限次闪烁;
  5.     *       2.亮时间,等于0表示不亮;
  6.     *       3.灭时间,等于0表示不灭。
  7.     * 返回:无
  8.     * 备注:OK.
  9. -------------------------------------------------------------------------*/
  10. void zl_led_flash_set(uint8_t chFlashCnt, uint16_t hwOnTime, uint16_t hwOffTime)
  11. {
  12.     /* 更新相关参数 */
  13.     s_chFlashCnt     = chFlashCnt;
  14.     s_hwFlashOnTime  = hwOnTime;
  15.     s_hwFlashOffTime = hwOffTime;

  16.     /* 复位状态机 */
  17.     s_chFlashFsmSta = 0;
  18. }
复制代码


需要说明的是,亮、灭时间的长度zl_led_flash_loop()的调用周期有关,在 demo 中
它是 1ms 中断里调用,所以设置的时间时基就是 1ms.

例子1,LED需要闪烁 10 次,亮时间是 30ms , 灭时间是 800ms , 可以这样设置
  1.     zl_led_flash_set(10, 30, 800);     /* 设置 LED 状态,闪烁10次,亮 60ms,灭 800ms */
复制代码


例子2,LED需要一直闪烁,亮时间是 600ms , 灭时间是 50ms , 可以这样设置
  1.     zl_led_flash_set(0, 600, 50);     /* 设置 LED 状态,一直闪烁,亮 600ms,灭 50ms */
复制代码



最后的说明:
从数据驱动的角度来讲,ZL LED 模块用于 BEEP 也是不错的选择,相信不少人也喜欢在设计
中这么干……需要注意的一点是,我这个模块并未考虑到数据的原子保护,需要用在严谨的
设计场合时,请自行修改源码……



就说这么多吧,有什么想起来后面再补充,欢迎交流,附件里有一个整理干净的 demo ……



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入8汤圆

 楼主| 发表于 2015-8-2 20:08:26 | 显示全部楼层
沙发自己占了,居然写了一个多小时……不知道发这个版块合适不,发帖的时候没看版块

出0入8汤圆

发表于 2015-8-2 20:14:49 | 显示全部楼层
有个led调试其他东西也会方便多

出0入0汤圆

发表于 2015-8-2 20:16:19 | 显示全部楼层
不错挺有用的

出0入0汤圆

发表于 2015-8-2 20:58:29 来自手机 | 显示全部楼层
楼主思路清洗,分层明确,有一个指示灯非常有用

出0入0汤圆

发表于 2015-8-2 21:22:31 | 显示全部楼层
关键的两个函数没有贴出
    zl_led_flash_loop();                /* zl led loop service */
    st_systick_delay_loop();            /* st systick delay loop service */

出0入0汤圆

发表于 2015-8-2 21:42:22 来自手机 | 显示全部楼层
呵呵哈哈哈

出0入76汤圆

发表于 2015-8-2 21:50:36 | 显示全部楼层
本帖最后由 foxpro2005 于 2015-8-2 21:56 编辑

给你顶一个,很早以前就写了一个类似的模块, LED状态指示, 闪亮支持N多种显示方式,故障码指示, 比如:一长二短, 一长五短, 并且支持它们的混合显示。

刚看了一下源码,原理基本类似, 不过我增加了一个功能,可以支持,它们多种闪烁指示同时存在, 它们采用依次循环显示。(即可同时指示多种故障信息)

出0入0汤圆

发表于 2015-8-2 21:57:21 来自手机 | 显示全部楼层
目前蜂鸣器就是这么干的,不过没用函数指针,用的宏

出0入0汤圆

发表于 2015-8-2 22:03:22 来自手机 | 显示全部楼层
嗯,模块化思想最好了

出0入0汤圆

发表于 2015-8-2 22:13:48 | 显示全部楼层
思想很好,赞一个

出0入0汤圆

发表于 2015-8-2 22:24:56 | 显示全部楼层
很好,先mark~~

出0入0汤圆

发表于 2015-8-2 22:54:22 | 显示全部楼层
写的很不错,谢谢楼主分享

出0入0汤圆

发表于 2015-8-3 00:27:14 | 显示全部楼层
用上了,很好

出0入0汤圆

发表于 2015-8-3 00:43:04 来自手机 | 显示全部楼层
好,谢谢分享!

出0入8汤圆

 楼主| 发表于 2015-8-3 09:07:33 | 显示全部楼层
xujihu 发表于 2015-8-2 20:14
有个led调试其他东西也会方便多

嗯嗯,led能再加个串口就更爽了

出0入8汤圆

 楼主| 发表于 2015-8-3 09:08:38 | 显示全部楼层

谢谢肯定,用用看呀,有 bug 回头给我说说

出0入8汤圆

 楼主| 发表于 2015-8-3 09:10:06 | 显示全部楼层

对你有用真是太好了,我自己一直在用的,遇到 bug 的话给我说说呀

出0入8汤圆

 楼主| 发表于 2015-8-3 09:12:51 | 显示全部楼层
lovecxm 发表于 2015-8-2 20:58
楼主思路清洗,分层明确,有一个指示灯非常有用

谢谢肯定,看来你也喜欢指示灯

出0入0汤圆

发表于 2015-8-3 09:13:38 来自手机 | 显示全部楼层
我也喜欢用led指示一下,不错

出0入8汤圆

 楼主| 发表于 2015-8-3 09:14:43 | 显示全部楼层
miaoguoqiang 发表于 2015-8-2 21:22
关键的两个函数没有贴出
    zl_led_flash_loop();                /* zl led loop service */
    st_syst ...

是我的问题,确实没贴出……因为有点长,担心影响阅读……但是附件的 demo 里有呀,你一定没下载看吧,看贴要认真呢

出0入8汤圆

 楼主| 发表于 2015-8-3 09:15:36 | 显示全部楼层

弱弱的问句,大哥,你这是几个意思呀……

出0入8汤圆

 楼主| 发表于 2015-8-3 09:27:30 | 显示全部楼层
foxpro2005 发表于 2015-8-2 21:50
给你顶一个,很早以前就写了一个类似的模块, LED状态指示, 闪亮支持N多种显示方式,故障码指示, 比如: ...

你很厉害,我目前还写不出来你说的,惭愧呀……你说的循环显示,是指用的还是同一个LED,对吗?
如果是这样的话,建一个可以支持添加、删除LED状态参数的队列(或着类似队列吧),根据闪烁次数
与整体的故障数量,做为状态切换依据,然后循环,应该能完成类似你说的功能吧……不过说是这样说,
写起来还是有实现难度的,现在我还没时间做,以后有机会,可以试试看。

你用的这个功能真的挺不错

出0入8汤圆

 楼主| 发表于 2015-8-3 09:29:51 | 显示全部楼层
ijlc1314 发表于 2015-8-2 21:57
目前蜂鸣器就是这么干的,不过没用函数指针,用的宏

我以前也用宏,宏还显得精简一些,可是不知道后来就莫名的喜欢用函数指针了……

出0入0汤圆

发表于 2015-8-3 09:30:12 | 显示全部楼层
mark,以备以后查用

出0入8汤圆

发表于 2015-8-3 09:30:16 | 显示全部楼层
led我的最爱~

出0入8汤圆

 楼主| 发表于 2015-8-3 09:32:35 | 显示全部楼层
soos 发表于 2015-8-2 22:03
嗯,模块化思想最好了

是啊,最近我一直都在思考模块化与复用,也在尝试着这样做,为的是以后能偷点懒,毕竟我使用的平台比较固定,不想再学新东西了

出0入89汤圆

发表于 2015-8-3 09:33:51 | 显示全部楼层
我有一个需求,比如,亮(10ms)->灭(20ms)->亮(10ms)->灭(20ms)->亮(10ms)->灭(1000ms) 如此不停循环

出0入8汤圆

 楼主| 发表于 2015-8-3 09:34:47 | 显示全部楼层
TCMCU 发表于 2015-8-2 22:13
思想很好,赞一个

谢谢

出0入8汤圆

 楼主| 发表于 2015-8-3 09:35:23 | 显示全部楼层

用用看

出0入8汤圆

 楼主| 发表于 2015-8-3 09:36:24 | 显示全部楼层
aaabbbad 发表于 2015-8-2 22:54
写的很不错,谢谢楼主分享

谢谢,谢谢,用用看,看看有改进的地方没

出0入8汤圆

 楼主| 发表于 2015-8-3 09:37:35 | 显示全部楼层
nnnkey 发表于 2015-8-3 00:43
好,谢谢分享!

谢谢肯定

出0入0汤圆

发表于 2015-8-3 10:00:00 | 显示全部楼层
我也是,做东西必须加个指示灯。我的程序没有你的复杂,只考虑亮和灭没考虑时间。

出0入0汤圆

发表于 2015-8-3 12:13:12 | 显示全部楼层
这个不错,拿走了。很好用

出0入0汤圆

发表于 2015-8-3 15:56:18 | 显示全部楼层
函数指针,调用方便

出0入0汤圆

发表于 2015-8-3 20:21:45 | 显示全部楼层
Jmhh247 发表于 2015-8-3 09:29
我以前也用宏,宏还显得精简一些,可是不知道后来就莫名的喜欢用函数指针了…… ...

我用的一般都是小资源的单片机,用不起函数指针,有些编译器也不支持

出0入8汤圆

 楼主| 发表于 2015-8-3 20:51:03 | 显示全部楼层
youkebing 发表于 2015-8-3 09:33
我有一个需求,比如,亮(10ms)->灭(20ms)->亮(10ms)->灭(20ms)->亮(10ms)->灭(1000ms) 如此不 ...

目前的模块还不支持,你说的这个需求就是 8 楼坛友提到的,他已经实现了这个功能……你可以尝试着修改下源码去实现,可能要花点时间,但难度不会太大……我目前没时间做改动

出0入8汤圆

 楼主| 发表于 2015-8-3 20:53:13 | 显示全部楼层
laojiao 发表于 2015-8-3 09:13
我也喜欢用led指示一下,不错

出0入8汤圆

 楼主| 发表于 2015-8-3 20:53:57 | 显示全部楼层
xingjianpeng 发表于 2015-8-3 09:30
mark,以备以后查用

希望对你是有用的。

出0入8汤圆

 楼主| 发表于 2015-8-3 20:54:16 | 显示全部楼层

出0入8汤圆

 楼主| 发表于 2015-8-3 20:57:33 | 显示全部楼层
留声而过 发表于 2015-8-3 10:00
我也是,做东西必须加个指示灯。我的程序没有你的复杂,只考虑亮和灭没考虑时间。 ...

哦,我的程序也不复杂的,加入时间设定后,就能灵活的展示更多的状态,就算是做一个简单的运行指示状态,
你也可以完全设定一个自己喜欢的亮灭时间进行闪烁……试用一下,绝对好玩

出0入8汤圆

 楼主| 发表于 2015-8-3 20:58:01 | 显示全部楼层
icevel 发表于 2015-8-3 12:13
这个不错,拿走了。很好用

出0入8汤圆

 楼主| 发表于 2015-8-3 20:59:04 | 显示全部楼层
makathy 发表于 2015-8-3 15:56
函数指针,调用方便

出0入8汤圆

 楼主| 发表于 2015-8-3 21:03:19 | 显示全部楼层
ijlc1314 发表于 2015-8-3 20:21
我用的一般都是小资源的单片机,用不起函数指针,有些编译器也不支持

确实要看具体情况,我用stm32的时候较多,其次是stm8,资源总是够用的,现在想起来用函数指针是因为
我的水平比较菜,大多时候都需要仿真,从这个角度讲,函数指针比宏要方便些……如果让我用那些小资源单
片机,可能它们还不支持仿真,像我这么菜,估计什么都做不出来了

出0入0汤圆

发表于 2015-8-4 10:41:41 | 显示全部楼层
顶,MARK备用

出0入0汤圆

发表于 2015-8-4 12:18:18 | 显示全部楼层
foxpro2005 发表于 2015-8-2 21:50
给你顶一个,很早以前就写了一个类似的模块, LED状态指示, 闪亮支持N多种显示方式,故障码指示, 比如: ...

很有兴趣

foxpro2005 能说说实现的思路吗?

出0入0汤圆

发表于 2015-8-4 12:35:45 | 显示全部楼层
不错,用在beep很好

出0入0汤圆

发表于 2015-8-4 13:23:59 | 显示全部楼层
我也这么做过

出0入0汤圆

发表于 2015-8-4 15:38:01 | 显示全部楼层
这种程序LED输出时长只有两种状态, 即高电平时间和低电平时间,如果想要LED输出多种高低电平的时间,这个程序就不适用了.我一般用查表法.

出0入0汤圆

发表于 2015-8-4 21:40:18 | 显示全部楼层
Jmhh247 发表于 2015-8-3 21:03
确实要看具体情况,我用stm32的时候较多,其次是stm8,资源总是够用的,现在想起来用函数指针是因为
我的 ...

小资源的单片机也是支持仿真的,只是如台系或是51,对函数指针的支持并不好或者是不根本就不支持

出0入8汤圆

 楼主| 发表于 2015-8-5 09:31:42 | 显示全部楼层
ijlc1314 发表于 2015-8-4 21:40
小资源的单片机也是支持仿真的,只是如台系或是51,对函数指针的支持并不好或者是不根本就不支持 ...

感谢科普,涨姿势了

出0入8汤圆

 楼主| 发表于 2015-8-5 09:33:06 | 显示全部楼层
ponder2077 发表于 2015-8-4 15:38
这种程序LED输出时长只有两种状态, 即高电平时间和低电平时间,如果想要LED输出多种高低电平的时间,这个程序 ...

是的,查表很好。

出0入0汤圆

发表于 2015-8-21 10:50:52 | 显示全部楼层
实用的好东西,收藏。

出0入0汤圆

发表于 2015-11-13 18:43:24 | 显示全部楼层
mark                       

出0入0汤圆

发表于 2016-4-9 18:51:03 | 显示全部楼层
mark
一下:
[代码分享]一个LED状态模块,支持亮、灭时间和闪烁次数设定

出0入0汤圆

发表于 2016-4-16 20:38:16 | 显示全部楼层
这个状态机限制了只能使用一个LED。其实我也在考虑用状态机来做,但是想了之后好像每控制一个LED都需要一个状态机。

出0入8汤圆

 楼主| 发表于 2016-4-18 08:42:39 | 显示全部楼层
Yvan 发表于 2016-4-16 20:38
这个状态机限制了只能使用一个LED。其实我也在考虑用状态机来做,但是想了之后好像每控制一个LED都需要一个 ...

你说的非常正确。因为这个模块的设计需求,只是一个LED。……如果想控制多个,也很简单,
把与LED相关的变量做成结构体,状态算法的参数使用结构体指针,稍做修改就能控制多个了。

出0入0汤圆

发表于 2017-7-10 06:06:35 | 显示全部楼层
MARK一下,备用。

出0入0汤圆

发表于 2017-7-10 09:34:08 | 显示全部楼层
mark一下 后面要用到

出0入0汤圆

发表于 2017-7-10 10:25:43 | 显示全部楼层
模块化做的不错,mark一下

出0入8汤圆

 楼主| 发表于 2017-7-10 15:17:12 | 显示全部楼层
这么久了,今天突然有人回复了。。。

出0入0汤圆

发表于 2023-8-28 17:12:21 | 显示全部楼层
可以设置固定的时间闪烁的次数吗?

出0入300汤圆

发表于 2023-8-28 17:24:18 来自手机 | 显示全部楼层
写代码走火入魔了吧,搞个灯还要闪,卡卡的那种

出0入143汤圆

发表于 2023-8-28 17:32:46 | 显示全部楼层
lnso 发表于 2023-8-28 17:12
可以设置固定的时间闪烁的次数吗?
(引用自62楼)

看看这个  //  单片机裸机实用组件--LED
https://blog.csdn.net/weixin_423 ... 38899-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

出0入362汤圆

发表于 2023-8-28 22:55:57 | 显示全部楼层
ibmx311 发表于 2023-8-28 17:24
写代码走火入魔了吧,搞个灯还要闪,卡卡的那种
(引用自63楼)

挺好的啊。。。本来就应该这么设计,把具体平台无关的逻辑抽象出来,平台相关代码用回调函数实现。

我还搞过按莫尔斯电码输出,具体怎么输出交给回调函数,蜂鸣器也行,LED也行。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-29 00:31

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表