OpenHarmony轻量系统智能模块开发实战指南

文档概述

本文档基于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 点对点、简单可靠 设备间通信 硬件简单、成本低
相关推荐
路溪非溪9 小时前
Linux驱动中的红外遥控子系统
linux·arm开发·驱动开发
不染尘.1 天前
操作系统发展史和常见习题汇总
arm开发·嵌入式硬件·draw.io
橘色的喵1 天前
嵌入式 ARM Linux 平台高性能无锁异步日志系统设计与实现
linux·arm开发·cache line·ring buffer
鸿蒙小白龙1 天前
OpenHarmony轻量系统(Hi3861)RTOS API开发详解
openharmony·rtos·liteos·轻量系统
物随心转2 天前
硬盘的MBR
arm开发
landyjzlai3 天前
AMBA总线(15)关于AXI-stream(sg模式)
arm开发·fpga开发·amba
Dillon Dong4 天前
从C到Simulink: ARM Compiler 5 (RVDS) 为什么simulink 不能使用arm编译
c语言·arm开发·simulink
硅农深芯4 天前
ARM Cortex-M系列的内核型号有什么区别,该怎么选择
arm开发·单片机·芯片
小程同学>o<5 天前
Linux 应用层开发入门(一)| ARM平台交叉编译入门:打造你的第一个Linux应用
linux·arm开发·linux应用层