本帖最后由 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 ……