基于FreeRTOS的LED点灯代码设计

1、需求分析    

        需求:设计一个LED驱动程序:1、支持0-100Hz频率闪烁   2、常亮、常灭   3、指定频率(0-100Hz)闪烁或亮指定一段时间

        潜在需求:1、需要能同时处理多个LED,也就是同时控制多个GPIO口的LED灯  2、LED控制需要支持多线程操作  3、LED可以动态增删

2、程序设计

        程序实现上首先考虑0~100Hz范围(事实上超过100Hz的闪烁,人眼就很难分辨了),而且要支持多个LED控制,那么可以用一个定时器,定时1ms,处理LED链表上的所有LED,通过链表上每个LED结点自己记录自己的亮灭计时,来控制LED灯。

有了这个想法设计链表上LED节点结构体如下

typedef uint64_t led_time_t;

typedef struct led_handle {
    int gpio;
	int always;
    int periodic;
	int counter;
	int period;
    int used;
	led_time_t time;
	led_time_t on_time;
	led_time_t total_time;
	struct list_head list;
}*led_handle_t;

有了节点结构体,现在要考虑往链表上添加和删除led节点,设计链表头结构体如下:


typedef struct led_control
{
    SemaphoreHandle_t mutex;
    struct list_head head;
}led_ctrl_t;

然后,就需要创建LED、销毁LED、添加LED、删除LED接口,设计如下:

创建LED:需要初始化LED的GPIO,分配 led_handle_t 作为控制句柄,供后续操作。

销毁LED:就是创建的反向操作,释放掉GPIO,释放掉句柄。

添加LED:添加LED,根据上面需求,需要有三个参数,分别表示周期,也就是闪烁频率;闪烁时亮灭时间比,类似PWM的占空比;还有时长。这里设计注意,假如是常亮、常灭,周期就指定为0Hz,占空比为100,同时通过设置 led->always 为1,指示一直常亮。参数都设置完成之后,就添加到LED全局链表上,需要注意加锁。

删除LED:添加的反向操作,从链表上把LED删除掉,注意要加锁

led_ctrl_t led_ctrl;  //全局定义LED链表头

void led_set(led_handle_t led, led_state_e state)
{
    gpio_set_level(led->gpio, state);
}

led_handle_t led_create(int gpio_num)
{
	led_handle_t led;
	led = (led_handle_t)heap_caps_malloc(sizeof(*led), MALLOC_CAP_SPIRAM);
    if (!led) {
        ESP_LO
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值