文档概述
本文档基于Hi3861平台HarmonyOS轻量系统下的6个智能应用模块(智能小车、智能测距、智能农场、智能灯具、智能安防、智能温湿度
一、项目概述
1.1 技术栈
- 操作系统: HarmonyOS轻量系统(LiteOS内核)
- 开发平台: Hi3861开发板(Hispark Pegasus)
- 编程接口: CMSIS-RTOS2 API 2.1.3
- 通信协议: MQTT、UDP、UART
- 数据格式: JSON(cJSON库)
- 显示技术: SSD1306 OLED显示屏(128×64像素)
- 传感器: SHT20温湿度传感器、超声波测距传感器等
- 网络协议: lwIP轻量级TCP/IP协议栈
1.2 模块列表
| 模块名称 | 目录路径 | 主要功能 | 任务数量 | 通信方式 |
|---|---|---|---|---|
| 智能小车 | smartCar_uart_udp |
车辆状态监控、UDP通信、OLED显示 | 4个 | UDP+UART |
| 智能测距 | smartDistance |
距离测量、UART通信、数据显示 | 1个 | UART |
| 智能农场 | smartFarm |
环境监测、MQTT通信、自动控制 | 3个 | MQTT |
| 智能灯具 | smartLamp |
灯光控制、MQTT通信、RGB调色 | 3个 | MQTT |
| 智能安防 | smartSecurityDefense |
安全监控、MQTT通信、传感器采集 | 3个 | MQTT |
| 智能温湿度 | smartTemp |
温湿度监测、OLED显示 | 1个 | - |
二、应用场景详解
2.1 智能小车模块(smartCar_uart_udp)
应用场景
智能小车模块适用于以下场景:
- 远程监控: 通过UDP网络实时监控车辆运行状态
- 数据采集: 收集车辆速度、电量、距离等运行参数
- 状态显示: 在OLED屏幕上实时显示车辆状态信息
- 多设备通信: 通过UART与语音模块、传感器模块进行数据交互
- 自动避障: 基于超声波测距实现自动停车功能
核心功能
- 车辆状态实时监控(速度、电量、距离)
- UDP网络数据收发
- OLED屏幕信息显示
- 多任务并发处理
- 自动避障控制
- 电池电量报警
技术架构
┌─────────────────────────────────────────────────────┐
│ smartCar_uart_udp │
├─────────────────────────────────────────────────────┤
│ OLED显示任务 │ UART接收任务 │ UDP发送任务 │ UDP接收任务 │
├─────────────────────────────────────────────────────┤
│ CMSIS-RTOS2 任务管理 │
├─────────────────────────────────────────────────────┤
│ SSD1306驱动 │ UART驱动 │ UDP协议栈 │ cJSON库 │
└─────────────────────────────────────────────────────┘
源码分析
1. 主程序入口(smartCar_demo.c)
c
static void smartCar_example(void)
{
// 1. 外设初始化
SC_peripheral_init();
// 2. NFC联网
if (nfc_connect_wifi_init() == -1) {
return;
}
// 3. UDP服务端创建
if (SC_udp_init() == -1) {
return;
}
// 4. 创建任务
osThreadAttr_t options;
options.attr_bits = 0;
options.cb_mem = NULL;
options.cb_size = 0;
options.stack_mem = NULL;
options.stack_size = TASK_STACK_SIZE; // 5KB
// UART接收任务(优先级osPriorityNormal1)
options.name = "uart_recv_task";
options.priority = osPriorityNormal1;
uart_recv_task_id = osThreadNew((osThreadFunc_t)uart_recv_task, NULL, &options);
// OLED显示任务(优先级osPriorityNormal)
options.name = "oled_show_task";
options.priority = osPriorityNormal;
oled_show_task_id = osThreadNew((osThreadFunc_t)oled_show_task, NULL, &options);
// UDP发送和接收任务...
}
2. UART接收任务(uart_recv_task.c)
c
void uart_recv_task(void)
{
hi_u8 uart_buff[20] = {0};
hi_u8 last_len = 0;
while (1) {
// 阻塞接收UART2数据
hi_u32 len = hi_uart_read(HI_UART_IDX_2, uart_buff, sizeof(uart_buff));
if (len > 0) {
// 拼接数据到缓冲区
memcpy_s((char *)pbuff, len, (char *)uart_buff, len);
pbuff += len;
// 检测数据包结束(当前接收长度小于上次)
if (len < last_len) {
pbuff = recvBuff; // 回到缓冲区头部
parse_json_data(recvBuff); // 解析JSON数据
memset_s((char *)recvBuff, sizeof(recvBuff), 0, sizeof(recvBuff));
}
last_len = len;
memset_s((char *)uart_buff, sizeof(uart_buff), 0, sizeof(uart_buff));
}
}
}
3. JSON数据解析
c
static void parse_json_data(uint8_t *pstr)
{
cJSON *json_root = cJSON_Parse((const char *)pstr);
if (json_root) {
cJSON *json_status = cJSON_GetObjectItem(json_root, "status");
if (json_status) {
// 提取距离数据
cJSON *json_distance = cJSON_GetObjectItem(json_status, "distance");
if (json_distance) {
systemValue.distance = json_distance->valueint;
}
// 提取电池电压
cJSON *json_carPower = cJSON_GetObjectItem(json_status, "carPower");
if (json_carPower) {
systemValue.battery_voltage = json_carPower->valueint;
}
// 提取左电机速度
cJSON *json_L_speed = cJSON_GetObjectItem(json_status, "L_speed");
if (json_L_speed) {
systemValue.left_motor_speed = json_L_speed->valueint;
}
// 提取右电机速度
cJSON *json_R_speed = cJSON_GetObjectItem(json_status, "R_speed");
if (json_R_speed) {
systemValue.right_motor_speed = json_R_speed->valueint;
}
}
cJSON_Delete(json_root);
}
}
4. OLED显示任务(oled_show_task.c)
c
void oled_show_task(void)
{
// 显示IP地址
SSD1306_ShowStr(OLED_TEXT16_COLUMN_0, OLED_TEXT16_LINE_0,
(uint8_t *)WiFi_GetLocalIP(), TEXT_SIZE_16);
te_car_status_t last_car_status;
uint8_t t_times = 0;
while (1) {
// 显示电池电量
memset_s((char *)oledShowBuff, sizeof(oledShowBuff), 0, sizeof(oledShowBuff));
if (sprintf_s((char *)oledShowBuff, sizeof(oledShowBuff), "power: %02.01fV",
(float)(systemValue.battery_voltage) / 1000.0) > 0) {
SSD1306_ShowStr(OLED_TEXT16_COLUMN_0, OLED_TEXT16_LINE_1,
oledShowBuff, TEXT_SIZE_16);
}
// 显示车辆状态(状态变化时更新)
if (systemValue.car_status != last_car_status) {
SSD1306_ShowStr(OLED_TEXT16_COLUMN_0, OLED_TEXT16_LINE_2,
" ", TEXT_SIZE_16);
memset_s((char *)oledShowBuff, sizeof(oledShowBuff), 0, sizeof(oledShowBuff));
if (sprintf_s((char *)oledShowBuff, sizeof(oledShowBuff), "car: %s",
get_CurrentCarStatus(systemValue)) > 0) {
SSD1306_ShowStr(OLED_TEXT16_COLUMN_0, OLED_TEXT16_LINE_2,
oledShowBuff, TEXT_SIZE_16);
}
last_car_status = systemValue.car_status;
}
// 显示左右电机速度
memset_s((char *)oledShowBuff, sizeof(oledShowBuff), 0, sizeof(oledShowBuff));
if (sprintf_s((char *)oledShowBuff, sizeof(oledShowBuff), "L: %04d R: %04d",
systemValue.left_motor_speed,
systemValue.right_motor_speed) > 0) {
SSD1306_ShowStr(OLED_TEXT16_COLUMN_0, OLED_TEXT16_LINE_3,
oledShowBuff, TEXT_SIZE_16);
}
// 电池电量报警(小于10V)
if (systemValue.battery_voltage <= 10000) {
if (!(t_times % 4)) { // 每200ms
systemValue.car_status = CAR_STATUS_OFF;
uart_send_buff("{\"control\":{\"power\":\"off\"}}",
strlen("{\"control\":{\"power\":\"off\"}}"));
buzzer_status ^= 0x01;
buzzer_status ? set_buzzer(true) : set_buzzer(false);
}
}
// 自动避障(距离小于100mm)
if ((systemValue.auto_abstacle_flag) && (systemValue.distance <= 100)) {
systemValue.car_status = CAR_STATUS_OFF;
uart_send_buff("{\"control\":{\"turn\":\"stop\"}}",
strlen("{\"control\":{\"turn\":\"stop\"}}"));
buzzer_status ^= 0x01;
buzzer_status ? set_buzzer(true) : set_buzzer(false);
} else {
set_buzzer(false);
}
// 系统状态指示灯(每500ms闪烁)
if (!(t_times % 5)) {
led_status ^= 0x01;
led_status ? set_led(true) : set_led(false);
}
t_times++;
usleep(50 * 1000); // 50ms延时
}
}
5. UDP发送任务(udp_send_task.c)
c
void udp_send_task(void)
{
int ret = 0;
while (1) {
// 创建JSON对象
cJSON *json_root = cJSON_CreateObject();
cJSON *json_speed = cJSON_CreateObject();
if (json_root) {
// 添加车辆状态
cJSON_AddItemToObject(json_root, "carStatus",
cJSON_CreateString(get_CurrentCarStatus(systemValue)));
// 添加速度对象
cJSON_AddItemToObject(json_root, "carSpeed", json_speed);
cJSON_AddItemToObject(json_speed, "left",
cJSON_CreateNumber(systemValue.left_motor_speed));
cJSON_AddItemToObject(json_speed, "right",
cJSON_CreateNumber(systemValue.right_motor_speed));
// 添加电池电压和距离
cJSON_AddItemToObject(json_root, "carPower",
cJSON_CreateNumber(systemValue.battery_voltage));
cJSON_AddItemToObject(json_root, "distance",
cJSON_CreateNumber(systemValue.distance));
}
// 转换为JSON字符串(无格式化)
char *payload = cJSON_PrintUnformatted(json_root);
// 通过UDP发送数据
ret = sendto(systemValue.udp_socket_fd, payload, strlen(payload), 0,
(struct sockaddr *)&client, sizeof(client));
// 释放内存
cJSON_Delete(json_root);
free(payload);
usleep(50 * 1000); // 50ms延时
}
}
2.2 智能测距模块(smartDistance)
应用场景
智能测距模块适用于以下场景:
- 工业测距: 工业自动化中的距离测量
- 智能仓储: 货物距离检测与定位
- 机器人导航: 移动机器人障碍物检测
- 安防监控: 区域入侵检测
核心功能
- 超声波距离测量
- UART数据接收与解析
- OLED屏幕距离显示(支持小数点)
- JSON数据处理
技术架构
┌─────────────────────────────────────────────────────┐
│ smartDistance │
├─────────────────────────────────────────────────────┤
│ UART接收任务 (单任务架构) │
├─────────────────────────────────────────────────────┤
│ JSON数据解析与显示 │
├─────────────────────────────────────────────────────┤
│ SSD1306驱动 │ UART驱动 │ cJSON库 │
└─────────────────────────────────────────────────────┘
源码分析
1. 主程序入口(smartDistance_demo.c)
c
static void smartDistance_main(void)
{
printf("Enter smartDistance_main()!\r\n");
// 外设初始化
PCF8574_Init(); // IO扩展芯片初始化
SSD1306_Init(); // OLED显示屏初始化
SSD1306_CLS(); // 清屏
SSD1306_ShowStr(OLED_TEXT16_COLUMN_0, OLED_TEXT16_LINE_0,
" Smart Distance", TEXT_SIZE_16);
// 创建UART接收任务
osThreadAttr_t options;
options.name = "uart_recv_task";
options.attr_bits = 0;
options.cb_mem = NULL;
options.cb_size = 0;
options.stack_mem = NULL;
options.stack_size = TASK_STACK_SIZE; // 5KB
options.priority = osPriorityNormal;
uart_recv_task_id = osThreadNew((osThreadFunc_t)uart_recv_task, NULL, &options);
}
2. 距离显示页面
c
void show_page(uint16_t val)
{
// 显示标题
SSD1306_ShowStr(OLED_TEXT16_COLUMN_0, OLED_TEXT16_LINE_0,
" Smart Distance", TEXT_SIZE_16);
// 显示数字(千位)
uint8_t x = val / 1000;
SSD1306_DrawBMP(bmp_number_1.left, bmp_number_1.top,
bmp_number_1.width, bmp_number_1.hight,
bmp_16X32_number[x]);
// 显示数字(百位)
x = val / 100 % 10;
SSD1306_DrawBMP(bmp_number_2.left, bmp_number_2.top,
bmp_number_2.width, bmp_number_2.hight,
bmp_16X32_number[x]);
// 显示数字(十位)
x = val / 10 % 10;
SSD1306_DrawBMP(bmp_number_3.left, bmp_number_3.top,
bmp_number_3.width, bmp_number_3.hight,
bmp_16X32_number[x]);
// 显示数字(个位)
x = val % 10;
SSD1306_DrawBMP(bmp_number_4.left, bmp_number_4.top,
bmp_number_4.width, bmp_number_4.hight,
bmp_8X16_number[x]);
// 显示小数点
SSD1306_DrawBMP(bmp_dian.left, bmp_dian.top,
bmp_dian.width, bmp_dian.hight,
bmp_16X16_dian);
// 显示单位cm
SSD1306_DrawBMP(bmp_danwei.left, bmp_danwei.top,
bmp_danwei.width, bmp_danwei.hight,
bmp_32X32_cm);
}
3. JSON数据解析
c
void parse_json_data(void)
{
cJSON *json_root = cJSON_Parse((const char *)recvBuff);
if (json_root) {
cJSON *json_status = cJSON_GetObjectItem(json_root, "status");
if (json_status) {
cJSON *json_distance = cJSON_GetObjectItem(json_status, "distance");
if (json_distance) {
sys_msg_data.distance = json_distance->valueint;
show_page(sys_msg_data.distance); // 显示距离
}
}
cJSON_Delete(json_root);
}
}
2.3 智能农场模块(smartFarm)
应用场景
智能农场模块适用于以下场景:
- 温室环境监测: 实时监测温湿度、光照等环境参数
- 自动灌溉控制: 根据土壤湿度自动控制水泵
- 远程数据上传: 通过MQTT将数据上传到云平台
- 智能通风控制: 根据温度自动控制风扇
核心功能
- SHT20温湿度传感器数据采集
- OLED屏幕环境数据显示
- MQTT数据收发
- 风扇自动控制
- 湿度阈值报警
技术架构
┌─────────────────────────────────────────────────────┐
│ smartFarm │
├─────────────────────────────────────────────────────┤
│ 传感器采集 │ MQTT发送 │ MQTT接收 │
├─────────────────────────────────────────────────────┤
│ CMSIS-RTOS2 任务管理 │
├─────────────────────────────────────────────────────┤
│ SHT20驱动 │ MQTT客户端 │ SSD1306 │ cJSON库 │
└─────────────────────────────────────────────────────┘
源码分析
1. 主程序入口(smartFarm_demo.c)
c
static void smartFarm_Project_example(void)
{
printf("Enter smartFarm_Project_example()!\r\n");
// 设置MQTT接收回调函数
p_MQTTClient_sub_callback = &mqttClient_sub_callback;
// 1. 外设初始化
SF_peripheral_init();
// 2. NFC联网
if (nfc_connect_wifi_init() == -1) {
return;
}
// 3. MQTT初始化
mqtt_init();
// 4. 创建任务
osThreadAttr_t options;
options.name = "mqtt_send_task";
options.attr_bits = 0;
options.cb_mem = NULL;
options.cb_size = 0;
options.stack_mem = NULL;
options.stack_size = TASK_STACK_SIZE; // 5KB
options.priority = osPriorityNormal;
// MQTT发送任务
mqtt_send_task_id = osThreadNew((osThreadFunc_t)mqtt_send_task, NULL, &options);
// MQTT接收任务
options.name = "mqtt_recv_task";
mqtt_recv_task_id = osThreadNew((osThreadFunc_t)mqtt_recv_task, NULL, &options);
// 传感器采集任务
options.name = "sensor_collect_task";
sensor_collect_task_id = osThreadNew((osThreadFunc_t)sensor_collect_task, NULL, &options);
}
2. NFC联网初始化
c
int nfc_connect_wifi_init(void)
{
uint8_t ndefLen = 0;
uint8_t ndef_Header = 0;
uint32_t result_code = 0;
oled_consle_log("===start nfc===");
// 读取NDEF数据包头
if (result_code = NT3HReadHeaderNfc(&ndefLen, &ndef_Header) != true) {
printf("NT3HReadHeaderNfc is failed. result_code = %d\r\n", result_code);
return -1;
}
ndefLen += NDEF_HEADER_SIZE; // 加上头部字节
if (ndefLen <= NDEF_HEADER_SIZE) {
printf("ndefLen <= 2\r\n");
return -1;
}
// 分配内存读取NDEF数据
uint8_t *ndefBuff = (uint8_t *)malloc(ndefLen + 1);
if (ndefBuff == NULL) {
printf("ndefBuff malloc is Falied!\r\n");
return -1;
}
if (result_code = get_NDEFDataPackage(ndefBuff, ndefLen) != HI_ERR_SUCCESS) {
printf("get_NDEFDataPackage is failed. result_code = %d\r\n", result_code);
return -1;
}
// 打印NDEF数据
printf("start print ndefBuff.\r\n");
for (size_t i = 0; i < ndefLen; i++) {
printf("0x%x ", ndefBuff[i]);
}
oled_consle_log("=== end nfc ===");
sleep(1);
oled_consle_log("== start wifi==");
// 连接WiFi
while (NFC_configuresWiFiNetwork(ndefBuff) != WIFI_SUCCESS) {
printf("nfc connect wifi is failed!\r\n");
oled_consle_log("=== wifi no ===");
sleep(1);
SSD1306_CLS();
}
printf("nfc connect wifi is SUCCESS\r\n");
oled_consle_log("===wifi yes===");
sleep(1);
return 0;
}
3. MQTT初始化
c
int mqtt_init(void)
{
// 连接MQTT服务器
while (MQTTClient_connectServer(SERVER_IP_ADDR, SERVER_IP_PORT) != WIFI_SUCCESS) {
printf("mqttClient_connectServer\r\n");
oled_consle_log("==mqtt ser no==");
sleep(1);
SSD1306_CLS();
}
printf("mqttClient_connectServer\r\n");
oled_consle_log("==mqtt ser yes=");
sleep(1);
// 初始化MQTT客户端
while (MQTTClient_init(MQTT_CLIENT_ID, MQTT_USER_NAME, MQTT_PASS_WORD) != WIFI_SUCCESS) {
printf("mqttClient_init\r\n");
oled_consle_log("==mqtt cli no==");
sleep(1);
SSD1306_CLS();
}
printf("mqttClient_init\r\n");
oled_consle_log("==mqtt cli yes=");
sleep(1);
// 订阅MQTT主题
while (MQTTClient_subscribe(MQTT_TOPIC_SUB_COMMANDS) != 0) {
printf("mqttClient_subscribe\r\n");
oled_consle_log("==mqtt sub no==");
sleep(1);
SSD1306_CLS();
}
printf("mqttClient_subscribe\r\n");
oled_consle_log("=mqtt sub yes==");
sleep(1);
SSD1306_CLS();
return 0;
}
2.4 智能灯具模块(smartLamp)
应用场景
智能灯具模块适用于以下场景:
- 智能家居: 远程控制灯具开关和亮度
- 氛围营造: RGB颜色调节,营造不同氛围
- 定时控制: 根据时间自动开关灯
- 场景模式: 预设多种灯光场景(阅读、睡眠、聚会等)
核心功能
- MQTT远程控制(开关、亮度、颜色)
- RGB三色LED控制
- JSON命令解析
- 灯光状态反馈
技术架构
┌─────────────────────────────────────────────────────┐
│ smartLamp │
├─────────────────────────────────────────────────────┤
│ 传感器采集 │ MQTT发送 │ MQTT接收 │
├─────────────────────────────────────────────────────┤
│ CMSIS-RTOS2 任务管理 │
├─────────────────────────────────────────────────────┤
│ GPIO驱动 │ MQTT客户端 │ cJSON库 │
└─────────────────────────────────────────────────────┘
2.5 智能安防模块(smartSecurityDefense)
应用场景
智能安防模块适用于以下场景:
- 家庭安防: 门窗状态监控、入侵检测
- 商业安防: 仓库、商铺安全监控
- 报警联动: 检测到异常时触发报警
- 远程监控: 通过MQTT实时上报安全状态
核心功能
- 多传感器数据采集(门窗、红外、震动等)
- MQTT安全状态上报
- 报警信息推送
- 实时监控显示
技术架构
┌─────────────────────────────────────────────────────┐
│ smartSecurityDefense │
├─────────────────────────────────────────────────────┤
│ 传感器采集 │ MQTT发送 │ MQTT接收 │
├─────────────────────────────────────────────────────┤
│ CMSIS-RTOS2 任务管理 │
├─────────────────────────────────────────────────────┤
│ 传感器驱动 │ MQTT客户端 │ cJSON库 │
└─────────────────────────────────────────────────────┘
2.6 智能温湿度模块(smartTemp)
应用场景
智能温湿度模块适用于以下场景:
- 环境监测: 室内外温湿度实时监测
- 冷链物流: 运输过程中温湿度监控
- 农业大棚: 农作物生长环境监测
- 机房监控: 服务器机房环境监控
核心功能
- SHT20温湿度传感器读取
- OLED屏幕数据显示
- 单任务轮询架构
- 简洁高效的数据采集
技术架构
┌─────────────────────────────────────────────────────┐
│ smartTemp │
├─────────────────────────────────────────────────────┤
│ 主任务 (单任务架构) │
├─────────────────────────────────────────────────────┤
│ 传感器读取与显示 │
├─────────────────────────────────────────────────────┤
│ SHT20驱动 │ SSD1306驱动 │ I2C │
└─────────────────────────────────────────────────────┘
三、核心开发技术详解
3.1 CMSIS-RTOS2 任务管理
3.1.1 任务创建
所有模块均使用osThreadNew函数创建任务:
c
osThreadAttr_t options;
options.name = "task_name"; // 任务名称
options.attr_bits = 0; // 属性位
options.cb_mem = NULL; // 控制块内存
options.cb_size = 0; // 控制块大小
options.stack_mem = NULL; // 栈内存
options.stack_size = 5 * 1024; // 栈大小(5KB)
options.priority = osPriorityNormal; // 优先级
osThreadId_t task_id = osThreadNew((osThreadFunc_t)task_func, NULL, &options);
3.1.2 任务配置参数
| 参数 | 常用值 | 说明 | 实际应用 |
|---|---|---|---|
| 栈大小 | 1024-5120字节 | 根据任务复杂度设置 | 简单任务1024,网络任务4096,显示任务2048 |
| 优先级 | osPriorityNormal (24) | 优先级范围9-38 | osPriorityNormal1(25)用于UART接收 |
| 任务数量 | 1-4个 | 根据功能需求 | 智能小车4个任务,智能测距1个任务 |
典型配置:
- 简单任务: 栈大小1024字节,优先级osPriorityNormal
- 网络任务: 栈大小4096字节,优先级osPriorityNormal
- 显示任务: 栈大小2048字节,优先级osPriorityNormal
- UART接收: 栈大小5120字节,优先级osPriorityNormal1
3.1.3 任务延时
使用osDelay函数进行任务延时:
c
osDelay(100); // 延时100ms
使用usleep函数进行微秒级延时:
c
usleep(50 * 1000); // 延时50ms
3.2 外设驱动技术
3.2.1 UART串口通信
初始化配置:
c
hi_io_set_func(HI_IO_NAME_GPIO_11, HI_IO_FUNC_GPIO_11_UART2_TXD);
hi_io_set_func(HI_IO_NAME_GPIO_12, HI_IO_FUNC_GPIO_12_UART2_RXD);
hi_uart_attribute uart_param = {
.baud_rate = 115200, // 波特率
.data_bits = 8, // 数据位
.stop_bits = 1, // 停止位
.parity = 0, // 校验位
};
hi_uart_init(HI_UART_IDX_2, &uart_param, NULL);
数据接收:
c
hi_u8 uart_buff[20] = {0};
hi_u32 len = hi_uart_read(HI_UART_IDX_2, uart_buff, sizeof(uart_buff));
数据发送:
c
hi_uart_write(HI_UART_IDX_2, (uint8_t *)data, len);
3.2.2 I2C通信(OLED、SHT20)
OLED初始化:
c
PCF8574_Init(); // IO扩展芯片初始化
SSD1306_Init(); // OLED显示屏初始化
SSD1306_CLS(); // 清屏
OLED显示:
c
// 显示字符串
SSD1306_ShowStr(column, line, "text", TEXT_SIZE_16);
// 显示位图
SSD1306_DrawBMP(x, y, width, height, bitmap_data);
SHT20温湿度读取:
c
float temperature = 0, humidity = 0;
SHT20_ReadData(&temperature, &humidity);
3.2.3 GPIO控制
GPIO初始化:
c
hi_io_set_func(HI_IO_NAME_GPIO_9, HI_IO_FUNC_GPIO_9_GPIO);
hi_gpio_set_dir(HI_GPIO_IDX_9, HI_GPIO_DIR_OUT);
GPIO输出:
c
hi_gpio_set_ouput_val(HI_GPIO_IDX_9, HI_GPIO_VALUE1); // 高电平
hi_gpio_set_ouput_val(HI_GPIO_IDX_9, HI_GPIO_VALUE0); // 低电平
3.3 网络通信技术
3.3.1 MQTT通信
MQTT连接:
c
// 初始化MQTT客户端
MQTTClient_connect();
// 订阅主题
MQTTClient_sub("topic", qos);
MQTT发送:
c
// 创建JSON数据
cJSON *root = cJSON_CreateObject();
cJSON_AddStringToObject(root, "key", "value");
char *json_str = cJSON_Print(root);
// 发送MQTT消息
MQTTClient_pub("topic", json_str, qos);
// 释放内存
free(json_str);
cJSON_Delete(root);
MQTT接收回调:
c
void mqtt_recv_callback(char *topic, char *payload)
{
// 解析JSON数据
cJSON *root = cJSON_Parse(payload);
// 处理数据...
cJSON_Delete(root);
}
3.3.2 UDP通信
UDP服务端创建:
c
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
UDP数据发送:
c
sendto(sockfd, buffer, len, 0, (struct sockaddr *)&client_addr, addr_len);
UDP数据接收:
c
recvfrom(sockfd, buffer, sizeof(buffer), 0,
(struct sockaddr *)&client_addr, &addr_len);
3.4 JSON数据处理
3.4.1 JSON创建
c
// 创建JSON对象
cJSON *root = cJSON_CreateObject();
// 添加字符串
cJSON_AddStringToObject(root, "device", "smartLamp");
// 添加数字
cJSON_AddNumberToObject(root, "temperature", 25.5);
// 添加嵌套对象
cJSON *status = cJSON_CreateObject();
cJSON_AddNumberToObject(status, "distance", 100);
cJSON_AddItemToObject(root, "status", status);
// 转换为字符串
char *json_str = cJSON_Print(root);
3.4.2 JSON解析
c
// 解析JSON字符串
cJSON *root = cJSON_Parse(json_str);
// 获取对象
cJSON *status = cJSON_GetObjectItem(root, "status");
// 获取值
cJSON *distance = cJSON_GetObjectItem(status, "distance");
int dist_value = distance->valueint;
// 释放内存
cJSON_Delete(root);
3.5 传感器数据采集
3.5.1 SHT20温湿度传感器
c
float temperature = 0, humidity = 0;
SHT20_ReadData(&temperature, &humidity);
printf("Temperature: %.1f°C, Humidity: %.1f%%\n",
temperature, humidity);
3.5.2 超声波测距传感器
c
// 通过UART接收距离数据
hi_u32 len = hi_uart_read(HI_UART_IDX_2, uart_buff, sizeof(uart_buff));
if (len > 0) {
// 解析JSON数据获取距离
parse_json_data(uart_buff);
}
3.6 自动控制逻辑
3.6.1 智能农场风扇控制
c
// 根据湿度自动控制风扇
if (humidity < 40) {
set_fan(true); // 湿度低,开启风扇
} else if (humidity > 60) {
set_fan(false); // 湿度高,关闭风扇
}
3.6.2 智能灯具控制
c
// 解析MQTT控制命令
cJSON *cmd = cJSON_GetObjectItem(root, "cmd");
if (strcmp(cmd->valuestring, "on") == 0) {
set_led(true); // 开灯
} else if (strcmp(cmd->valuestring, "off") == 0) {
set_led(false); // 关灯
}
四、技术架构总结
4.1 通用架构模式
所有模块都遵循以下架构模式:
┌─────────────────────────────────────────────────────┐
│ 应用层(业务逻辑) │
├─────────────────────────────────────────────────────┤
│ 任务层(CMSIS-RTOS2) │
├─────────────────────────────────────────────────────┤
│ 驱动层(外设驱动) │
├─────────────────────────────────────────────────────┤
│ 硬件层(Hi3861芯片) │
└─────────────────────────────────────────────────────┘
4.2 任务架构对比
| 模块 | 任务数量 | 任务类型 | 架构特点 | 栈大小 | 优先级 |
|---|---|---|---|---|---|
| smartCar | 4个 | OLED、UART、UDP收发 | 多任务并发 | 5KB | Normal/Normal1 |
| smartDistance | 1个 | UART接收 | 单任务轮询 | 5KB | Normal |
| smartFarm | 3个 | 传感器、MQTT收发 | 多任务协作 | 5KB | Normal |
| smartLamp | 3个 | 传感器、MQTT收发 | 多任务协作 | 5KB | Normal |
| smartSecurityDefense | 3个 | 传感器、MQTT收发 | 多任务协作 | 5KB | Normal |
| smartTemp | 1个 | 主任务 | 单任务轮询 | 5KB | Normal |
4.3 通信协议对比
| 协议 | 使用模块 | 特点 | 应用场景 | 优势 |
|---|---|---|---|---|
| MQTT | smartFarm、smartLamp、smartSecurityDefense | 发布订阅、轻量级 | 物联网云平台通信 | 支持离线消息、QoS保证 |
| UDP | smartCar | 无连接、低延迟 | 局域网实时通信 | 传输速度快、开销小 |
| UART | smartCar、smartDistance | 点对点、简单可靠 | 设备间通信 | 硬件简单、成本低 |