介绍LED指示灯驱动,并举例
后台回复开源获取全部资料
概述
产品装机后,往往因各种情况需要调试,常规输出调试信息的方式很多,考虑到系统一般存在指示灯,那么能不能像摩尔斯电码,搞个闪烁的LED灯输出信息。
想法落地,设计一个LED驱动:
如何闪烁
常规思路,延时:
显然:
阻塞延时导致浪费CPU时间
其它任务怎么办
非阻塞延时,那别的LED无法刷新
没有什么东西是时间解决不了的,所以引入时基,给LED注入心跳:
这里采用占空比固定、变频的方案,只因代码简单好写。
如何编码
人眼、测量设备能识别出0、1两种状态
每个编码、每串编码做好时间间隔
自由调整编码
总的需求:
能解析ASCII码的高低序列,进行闪烁
运行时,编码位数自由调整
编码位数、数量可扩展
编码模式的应用
常规的应用:
三长两短周期性闪烁
周期性快闪、慢闪N次
解析一串字符,逐位闪烁,以灯光传递信息
设计数据结构
依据上述需求,设计LED对象:
秉承最小内存占用的精神,使用位域,能省就省
需要扩展编码时,就给它多分配一些
typedef struct
{
led_event_t *encode; /* 指向编码数组 */
uint8_t encode_num; /* 总的编码数 */
uint8_t encode_cnt; /* 编码已处理的计数器 */
uint8_t init_bits : 4; /* 编码的位数 */
uint8_t remaining_bits : 4; /* 当前未处理的位数 */
uint8_t encode_num : 4;
uint8_t encode_cnt : 4;
uint8_t init_bits : 3;
uint8_t remaining_bits : 3;
uint8_t encode_circular : 1; /* 编码是否循环处理 */
uint8_t open : 1; /* 开关控制 */
uint8_t tick; /* 时基 */
led_event_t event; /* LED的事件 */
void (*ctrl_cbk)(uint8_t); /* LED亮灭回调函数 */
}ry_led_t;
所有API
写代码,实现上述功能:
/* 创建一个LED,并设置其默认状态 */
extern void ry_led_create(E_user_led_sn_t led, led_event_t e, void (*ctrl_cbk)(uint8_t));
/* 配置LED的一般事件 */
extern void ry_led_event_cfg(E_user_led_sn_t led, led_event_t e);
/* 配置LED的循环编码模式 */
extern void ry_led_encode_circular_cfg(E_user_led_sn_t led, led_event_t *encode, uint8_t encode_num);
/* 设置LED的编码位数 */
extern void ry_set_led_encode_bits(E_user_led_sn_t led, uint8_t bits);
/* LED扫描,定时调用该函数实现LED控制 */
extern void ry_led_scan(void);
创建一个LED
先在“ry_led.h”中定义一个LED枚举:
/* 自行注册LED,如下注册了一个“LED_USER” */
typedef enum
{
LED_USER,
RY_LED_SN_MAX,
}E_user_led_sn_t;
开始注册LED、同时注册一个周期50ms的扫描任务:
static ry_task_t __taskLED;
static uint8_t __ledEncode[] = "ry_led";
void drv_led_create(void)
{
/* 创建一个LED */
ry_led_create(LED_USER, RY_LED_OFF, bsp_led_ctrl);
/* LED输出“ry_led”。慢闪为1,快闪为0,MSB方式 */
/* 字符间有短暂停顿,处理完一串字符后,有长停顿 */
ry_led_encode_circular_cfg(LED_USER, __ledEncode, 6);
/* 注册一个LED扫描任务 */
ry_task_reg(&__taskLED, /* 任务控制块 */
ry_led_scan, /* 任务主体 */
RY_TASK_MODE_NORMAL, /* 普通模式,周期性运行即可 */
RY_TASK_READY, /* 就绪态 */
"led", /* 任务名字 */
LED_SCAN_CYCLE); /* 扫描周期,1个系统时基1ms */
}
扫描任务启动后,就按照我们的意志运行下去。
实验现象
观察LED的闪烁情况,并抓取波形:
低电平亮灯
占空比固定,周期不同,实现快闪、慢闪
上图6个16进制数,对应:ry_led
最后的
示例源码,已按照最新的程序设计思想编写,如下:
-END-