转-一个LED状态模块,支持亮、灭时间和闪烁次数设定

admin 2017-7-10 3206

 

本帖最后由 Jmhh247 于 2015-8-2 20:07 编辑

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

我有个习惯就是在含有MCU的设计中,在资源允许时,都会用一颗LED指示设备的运行状态,没这个状态指示心里就会

觉得不踏实,不知道大家是不是喜欢这样干……相信有些人是喜欢的,反正,我觉得自己的强迫症是治不好了……就是在

这个背景下我写下了这个LED模块以复用。

好了,说重点:

首先是功能描述:

这个LED模块的主要功能就是做一些简单的状态指示,如闪烁、亮、灭这些基本的状态,这些状态支持时间或次数

的设定,模块的工作是基于状态机的,符合C99,便于移植复用。

接着是模块使用:

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

的 demo 供参考。

模块的接口函数有三个如下,初始化,用户设置,循环服务,非常典型的应用层驱动写法,我喜欢这种写法 。

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 …… 


上传的附件:
最新回复 [0]
返回