LED控制模块在整个项目中属于最基础也是最简单的应用模块,在本项目中可以通过网页对板载的三个LED进行开关操作。本项目选用的LED软件包为SignalLed软件包。但由于在本项目的第一个版本中LED的控制逻辑极为简单,只有开与关两个操作,因此最终并没有用到该软件包,但后续的更新中很可能加入更多的LED元素,因此在本章节开头还是会与大家介绍一下该软件包。
目录
SignalLed软件包的使用
LED控制选用SignalLed软件包,查看软件包链接。
在介绍该软件包之前,我们先来思考一下,如果我有一个LED的工作逻辑:先亮500毫秒,再灭100毫秒,再亮200毫秒,再灭500ms,接着亮1000毫秒,最后灭2000毫秒。如此循环三次。我们应该怎么编程?这个逻辑并不复杂,编程也比较方便。无非就是打开,延时,关闭,延时,打开,延时……然而,一旦我们要操作的LED数量增加,或者逻辑变得更加复杂的时候,一个个的开关操作,一行行的延时就会占据大量的代码空间,不仅不美观,还会使代码臃肿冗长,影响我们的心情。
//常规LED操作
for(int i=0;i<3;i++)
{
LED_ON;
delay_ms(500);
LED_OFF;
delay_ms(100);
LED_ON;
delay_ms(200);
LED_OFF;
delay_ms(500);
LED_ON;
delay_ms(1000);
LED_OFF;
delay_ms(2000);
}
SignalLed对LED的闪烁逻辑进行了抽象,使使用者无需关注过多的引脚电平操作,也无需编写一行又一行的延时代码,取而代之的,使一串简单明了的字符串。接下来,我们用该软件包实现上文的逻辑。
//SignalLed软件包操作
led_set_mode(led0, 3, "500,100,200,500,1000,2000,"); //闪烁模式字符串以逗号结尾
仅仅需要一行代码,即可实现上文十几行代码所实现的逻辑。该函数的第一个参数为所要控制的led句柄,第二个参数为循环次数,第三个参数为闪烁模式,字符串中的数字即亮、灭的时间,单位毫秒,顺序为 “亮、灭、亮、灭……”。经过对比,相信该软件包的魅力也已经呈现在大家眼前。当然,还需要强调一下,由于目前版本并没有涉及到这种复杂的闪烁模式,所以并没有使用该软件包,若感兴趣的朋友可以点击上文的软件包链接,里面有非常详细的教程文档供大家参考!
LED模块源码详解
LED模块的源代码位于 /W601_APP/module 文件夹下的 board_module.c 与 board_module.h 两个源文件中。
模块结构体
//LED 枚举类型
typedef enum
{
RED,
GREEN,
BLUE
} led_id_e;
//LED结构体
typedef struct
{
uint8_t red_led_status;
uint8_t green_led_status;
uint8_t blue_led_status;
} board_device_t;
LED模块包含一个区分具体哪一个LED的枚举类型与一个LED结构体,由于板载红、绿、蓝三个LED,所以其枚举也对应为RED、GREEN、BLUE三个类型。而LED结构体也相对简单,只有三个标志变量,分别存储每个LED所处的状态。
模块函数简介
函数名 | 函数简介 |
led_module_init | 初始化LED模块 |
led_write | 控制LED开关 |
json_create_device_status | 生成LED状态json字符串 |
模块函数详解
led_module_init
该函数为led模块的初始化函数,函数体中主要实现了LED IO 的初始化,并且将LED结构体中的状态复位(置为关闭状态)。
void led_module_init(void)
{
rt_pin_mode(PIN_LED_R, PIN_MODE_OUTPUT);
rt_pin_mode(PIN_LED_G, PIN_MODE_OUTPUT);
rt_pin_mode(PIN_LED_B, PIN_MODE_OUTPUT);
w601_board.blue_led_status = LED_OFF;
w601_board.green_led_status = LED_OFF;
w601_board.red_led_status = LED_OFF;
}
led_write
该函数实现了三个LED的状态设置功能,同时也是对外的LED控制接口。通过函数体可以看到,只需传入对应的枚举值和亮灭状态(LED_ON或LED_OFF)即可操作对应的灯与状态。同时LED结构体会记录更新后的LED状态。
void led_write(led_id_e led, uint8_t status)
{
switch (led)
{
case RED:
rt_pin_write(PIN_LED_R, status);
w601_board.red_led_status = status;
break;
case GREEN:
rt_pin_write(PIN_LED_G, status);
w601_board.green_led_status = status;
break;
case BLUE:
rt_pin_write(PIN_LED_B, status);
w601_board.blue_led_status = status;
break;
default:
break;
}
}
json_create_device_status
该函数会将三个LED的状态从结构体中取出,并且生成一个LED状态的json字符串,传输给网页并在前端进行LED状态显示。
char *json_create_device_status(void)
{
char *json_data = RT_NULL;
cJSON *root = cJSON_CreateObject();
if (w601_board.red_led_status == LED_ON)
{
cJSON_AddItemToObject(root, "redLedStatus", cJSON_CreateString("ON"));
}
else
{
cJSON_AddItemToObject(root, "redLedStatus", cJSON_CreateString("OFF"));
}
if (w601_board.green_led_status == LED_ON)
{
cJSON_AddItemToObject(root, "greenLedStatus", cJSON_CreateString("ON"));
}
else
{
cJSON_AddItemToObject(root, "greenLedStatus", cJSON_CreateString("OFF"));
}
if (w601_board.blue_led_status == LED_ON)
{
cJSON_AddItemToObject(root, "blueLedStatus", cJSON_CreateString("ON"));
}
else
{
cJSON_AddItemToObject(root, "blueLedStatus", cJSON_CreateString("OFF"));
}
json_data = cJSON_PrintUnformatted(root);
cJSON_Delete(root);
return json_data;
}