Jmhh247 发表于 2015-8-2 20:07:08

[代码分享]一个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:}



Jmhh247 发表于 2015-8-2 20:08:26

沙发自己占了,居然写了一个多小时……不知道发这个版块合适不,发帖的时候没看版块{:sweat:}

xujihu 发表于 2015-8-2 20:14:49

有个led调试其他东西也会方便多

nydxsydt0 发表于 2015-8-2 20:16:19

不错挺有用的

lovecxm 发表于 2015-8-2 20:58:29

楼主思路清洗,分层明确,有一个指示灯非常有用

miaoguoqiang 发表于 2015-8-2 21:22:31

关键的两个函数没有贴出
    zl_led_flash_loop();                /* zl led loop service */
    st_systick_delay_loop();            /* st systick delay loop service */

pchf005 发表于 2015-8-2 21:42:22

呵呵哈哈哈

foxpro2005 发表于 2015-8-2 21:50:36

本帖最后由 foxpro2005 于 2015-8-2 21:56 编辑

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

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

ijlc1314 发表于 2015-8-2 21:57:21

目前蜂鸣器就是这么干的,不过没用函数指针,用的宏

soos 发表于 2015-8-2 22:03:22

嗯,模块化思想最好了

TCMCU 发表于 2015-8-2 22:13:48

思想很好,赞一个

yick 发表于 2015-8-2 22:24:56

很好,先mark~~

aaabbbad 发表于 2015-8-2 22:54:22

写的很不错,谢谢楼主分享

lxk52000 发表于 2015-8-3 00:27:14

用上了,很好

nnnkey 发表于 2015-8-3 00:43:04

好,谢谢分享!

Jmhh247 发表于 2015-8-3 09:07:33

xujihu 发表于 2015-8-2 20:14
有个led调试其他东西也会方便多

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

Jmhh247 发表于 2015-8-3 09:08:38

nydxsydt0 发表于 2015-8-2 20:16
不错挺有用的

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

Jmhh247 发表于 2015-8-3 09:10:06

lxk52000 发表于 2015-8-3 00:27
用上了,很好

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

Jmhh247 发表于 2015-8-3 09:12:51

lovecxm 发表于 2015-8-2 20:58
楼主思路清洗,分层明确,有一个指示灯非常有用

谢谢肯定,看来你也喜欢指示灯{:smile:}

laojiao 发表于 2015-8-3 09:13:38

我也喜欢用led指示一下,不错

Jmhh247 发表于 2015-8-3 09:14:43

miaoguoqiang 发表于 2015-8-2 21:22
关键的两个函数没有贴出
    zl_led_flash_loop();                /* zl led loop service */
    st_syst ...

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

Jmhh247 发表于 2015-8-3 09:15:36

pchf005 发表于 2015-8-2 21:42
呵呵哈哈哈

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

Jmhh247 发表于 2015-8-3 09:27:30

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

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

你用的这个功能真的挺不错{:handshake:}

Jmhh247 发表于 2015-8-3 09:29:51

ijlc1314 发表于 2015-8-2 21:57
目前蜂鸣器就是这么干的,不过没用函数指针,用的宏

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

xingjianpeng 发表于 2015-8-3 09:30:12

mark,以备以后查用

蓝蓝的恋 发表于 2015-8-3 09:30:16

led我的最爱~

Jmhh247 发表于 2015-8-3 09:32:35

soos 发表于 2015-8-2 22:03
嗯,模块化思想最好了

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

youkebing 发表于 2015-8-3 09:33:51

我有一个需求,比如,亮(10ms)->灭(20ms)->亮(10ms)->灭(20ms)->亮(10ms)->灭(1000ms) 如此不停循环

Jmhh247 发表于 2015-8-3 09:34:47

TCMCU 发表于 2015-8-2 22:13
思想很好,赞一个

谢谢{:smile:}

Jmhh247 发表于 2015-8-3 09:35:23

yick 发表于 2015-8-2 22:24
很好,先mark~~

用用看{:smile:}

Jmhh247 发表于 2015-8-3 09:36:24

aaabbbad 发表于 2015-8-2 22:54
写的很不错,谢谢楼主分享

谢谢,谢谢,用用看,看看有改进的地方没{:smile:}

Jmhh247 发表于 2015-8-3 09:37:35

nnnkey 发表于 2015-8-3 00:43
好,谢谢分享!

谢谢肯定{:smile:}

留声而过 发表于 2015-8-3 10:00:00

我也是,做东西必须加个指示灯。我的程序没有你的复杂,只考虑亮和灭没考虑时间。

icevel 发表于 2015-8-3 12:13:12

这个不错,拿走了。很好用

makathy 发表于 2015-8-3 15:56:18

函数指针,调用方便

ijlc1314 发表于 2015-8-3 20:21:45

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

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

Jmhh247 发表于 2015-8-3 20:51:03

youkebing 发表于 2015-8-3 09:33
我有一个需求,比如,亮(10ms)->灭(20ms)->亮(10ms)->灭(20ms)->亮(10ms)->灭(1000ms) 如此不 ...

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

Jmhh247 发表于 2015-8-3 20:53:13

laojiao 发表于 2015-8-3 09:13
我也喜欢用led指示一下,不错

{:smile:}

Jmhh247 发表于 2015-8-3 20:53:57

xingjianpeng 发表于 2015-8-3 09:30
mark,以备以后查用

希望对你是有用的。{:smile:}

Jmhh247 发表于 2015-8-3 20:54:16

蓝蓝的恋 发表于 2015-8-3 09:30
led我的最爱~

{:smile:}

Jmhh247 发表于 2015-8-3 20:57:33

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

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

Jmhh247 发表于 2015-8-3 20:58:01

icevel 发表于 2015-8-3 12:13
这个不错,拿走了。很好用

{:smile:}

Jmhh247 发表于 2015-8-3 20:59:04

makathy 发表于 2015-8-3 15:56
函数指针,调用方便

{:smile:}

Jmhh247 发表于 2015-8-3 21:03:19

ijlc1314 发表于 2015-8-3 20:21
我用的一般都是小资源的单片机,用不起函数指针,有些编译器也不支持

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

amu 发表于 2015-8-4 10:41:41

顶,MARK备用

FireHe 发表于 2015-8-4 12:18:18

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

很有兴趣

foxpro2005 能说说实现的思路吗?

dswkl11 发表于 2015-8-4 12:35:45

不错,用在beep很好

zuokong2006 发表于 2015-8-4 13:23:59

我也这么做过

ponder2077 发表于 2015-8-4 15:38:01

这种程序LED输出时长只有两种状态, 即高电平时间和低电平时间,如果想要LED输出多种高低电平的时间,这个程序就不适用了.我一般用查表法.

ijlc1314 发表于 2015-8-4 21:40:18

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

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

Jmhh247 发表于 2015-8-5 09:31:42

ijlc1314 发表于 2015-8-4 21:40
小资源的单片机也是支持仿真的,只是如台系或是51,对函数指针的支持并不好或者是不根本就不支持 ...

感谢科普,涨姿势了{:lol:}

Jmhh247 发表于 2015-8-5 09:33:06

ponder2077 发表于 2015-8-4 15:38
这种程序LED输出时长只有两种状态, 即高电平时间和低电平时间,如果想要LED输出多种高低电平的时间,这个程序 ...

是的,查表很好。

hhww8280 发表于 2015-8-21 10:50:52

实用的好东西,收藏。

zl_123 发表于 2015-11-13 18:43:24

mark                     

maimaige 发表于 2016-4-9 18:51:03

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

Yvan 发表于 2016-4-16 20:38:16

这个状态机限制了只能使用一个LED。其实我也在考虑用状态机来做,但是想了之后好像每控制一个LED都需要一个状态机。

Jmhh247 发表于 2016-4-18 08:42:39

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

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

su33691 发表于 2017-7-10 06:06:35

MARK一下,备用。

122402902 发表于 2017-7-10 09:34:08

mark一下 后面要用到

kstepbill84 发表于 2017-7-10 10:25:43

模块化做的不错,mark一下

Jmhh247 发表于 2017-7-10 15:17:12

这么久了,今天突然有人回复了。。。

lnso 发表于 2023-8-28 17:12:21

可以设置固定的时间闪烁的次数吗?

ibmx311 发表于 2023-8-28 17:24:18

写代码走火入魔了吧,搞个灯还要闪,卡卡的那种

XIE2099 发表于 2023-8-28 17:32:46

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

tomzbj 发表于 2023-8-28 22:55:57

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

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

我还搞过按莫尔斯电码输出,具体怎么输出交给回调函数,蜂鸣器也行,LED也行。
页: [1]
查看完整版本: [代码分享]一个LED状态模块,支持亮、灭时间和闪烁次数设定