更新时间:2024-11-25 08:05:57下载pdf
MCU SDK 是根据涂鸦开发者平台定义的产品功能自动生成的 MCU 代码,能够协助您快速完成 MCU 程序的开发。本文为您介绍 Zigbee 通用方案移植 MCU SDK 的流程以及注意事项。
在移植 MCU SDK 前,您需要了解其文件结构:
| 文件 | 说明 | 
|---|---|
zigbee.h | 
提供通用宏的定义 | 
system.h | 
system.h 包含以下信息:
  | 
system.c | 
system.c 包含以下信息:
  | 
protocol.h | 
protocol.h 包含以下信息:
  | 
protocol.c | 
protocol.c 包含以下信息:
  | 
mcu_api.h | 
mcu_api.h 包含以下信息:
  | 
mcu_api.c | 
mcu_api.c 包含以下信息:
  | 
更多信息,参考 附录 - 文件详细说明。
完成移植流程后,用户可参考 使用流程 体验 MCU SDK。
下载 MCU SDK。具体步骤,参考 MCU 低代码开发。
将 MCU SDK 文件夹中的 .c 和 .h 文件分别添加到项目工程的源文件和头文件引用路径下。
在 项目工程 中需要使用 MCU SDK 接口的文件里,添加代码 #include "zigbee.h"。
在 mcu_api.h 中,如果需要打印调试信息,使能宏 MCU_SDK_DEBUG。然后,把宏 PROJECT_PRINT_FUNC 替换为项目工程的调试信息打印函数(可能需要引用项目工程的头文件)。
#ifndef MCU_SDK_DEBUG
#define MCU_SDK_DEBUG                           1
#endif
#if MCU_SDK_DEBUG
#include "xx_print.h"
#define PRINT_DEBUG(fmt, ...)                   my_debug_print(fmt, ##__VA_ARGS__)
#else
#define PRINT_DEBUG(fmt, ...)
#endif
在 mcu_api.h 中,确认缓冲区尺寸,包括 UART_RX_BUF_LEN_LMT、UART_TX_BUF_LEN_LMT 和 UART_QUEUE_BUF_LEN_LMT。
#define UART_RX_BUF_LEN_LMT                     256
#define UART_TX_BUF_LEN_LMT                     256
#define UART_QUEUE_BUF_LEN_LMT                  512
在 mcu_api.h 中,修改 OTA 单包尺寸(OTA_PACKET_SIZE)以及 Zigbee 模组唤醒 MCU 时等待 MCU 的时间(ZG_WAIT_MCU_TIME_DEFAULT)。
///< OTA single packet payload length (UART command ID: 0x0c 0x0d 0x0e)
#define OTA_PACKET_SIZE                         0x30            // max: 0x30
///< The waiting time after the Zigbee module starts to wake up the MCU (UART command ID: 0x2b)
#if SLEEP_END_DEVICE
#define ZG_WAIT_MCU_TIME_DEFAULT                10
#endif
在 项目工程 的串口数据接收处理函数中,调用 uart_servive_rx_store() 函数处理接收的每个字节。
int main(void)
{
    ...
    // MCU 接收串口初始化
    recv_uart_init(recv_uart_callback);
    ...
}
void recv_uart_callback(uint8_t *buff, uint16_t len)
{
    for (uint16_t i = 0; i < len; i++) {
        uart_servive_rx_store(buff[i]);
    }
}
在 项目工程 的主循环或定时器中断(循环执行)中,调用 uart_service_parse() 函数。
如果采用中断方式,则程序正常初始化完成后,建议不要关闭中断,因为关闭中断会导致串口数据接收丢失。如果必须关闭中断,则关闭中断时间必须短。禁止在中断内调用上报函数。
int main(void)
{
    ...
    while(1) {
        uart_service_parse();
    }
    ...
}
在 项目工程 中实现 uart_send_byte() 函数,只需要在里面调用项目工程的串口单字节发送函数。
int main(void)
{
    ...
    ...
}
void uart_send_byte(unsigned char value)
{
    my_uart_send_a_byte(value);
}
对于低功耗设备,在 项目工程 中初始化低功耗唤醒 GPIO,并实现以下其中一个低功耗唤醒发送函数:
mcu_wakeup_zg_level_method() 函数,电平唤醒
mcu_wakeup_zg_pulse_method() 函数,脉冲唤醒
具体实现方式,参考 低功耗唤醒 。
int main(void)
{
    ...
    // MCU 唤醒模组 GPIO 初始化
    // 模组唤醒 MCU GPIO 初始化
    wakeup_gpio_init();
    ...
}
void mcu_wakeup_zg_level_method(unsigned char *data, unsigned short data_len)
{
    // 请根据串口协议的低功耗唤醒章节自行实现
}
在 项目工程 中,必须实现串口协议的 所有 的帧接收处理函数(用户接口,mcu_recv_ 前缀),可以实现为空函数。
void mcu_recv_factory_recovery_cb(void)
{
    PRINT_DEBUG("factory recovery\r\n");
}
void mcu_recv_zg_nwk_status_notify_cb(unsigned char nwk_status)
{
}
unsigned char mcu_recv_beacon_notify_cb(void)
{
    return 1;
}
在 mcu_api.c 中,对于低功耗设备,在 uart_send_frame() 函数中开启一个 MCU 唤醒发送函数(需要在项目工程中实现),并禁用另一个 MCU 唤醒发送函数。
void uart_send_frame(unsigned short payload_len)
{
#if SLEEP_END_DEVICE
    mcu_wakeup_zg_level_method((unsigned char *)g_uart_tx_buf, payload_len + FRAME_LEN_WITHOUT_PAYLOAD);
    // mcu_wakeup_zg_pulse_method((unsigned char *)g_uart_tx_buf, payload_len + FRAME_LEN_WITHOUT_PAYLOAD);
#else
    uart_send_bytes((unsigned char *)g_uart_tx_buf, payload_len + FRAME_LEN_WITHOUT_PAYLOAD);
#endif
}
在 protocol.h 中,确认设备信息。
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| PRODUCT_KEY | 产品 ID,即 PID | 这是每个产品的唯一标识,可在 涂鸦开发者平台 的产品详情页面获取 | 
| MCU_VER | MCU 固件版本 | 关于 OTA 升级流程,参考 OTA 升级说明-平台配置 | 
| SUPPORT_RECEIVE_BROADCAST_DATA | MCU 是否需要区分群控消息 | 
  | 
| DEVICE_TYPE | 设备类型 | 
  | 
#define PRODUCT_KEY "ksubawat"    //在开发者平台创建产品后生成,16 位字符组成的产品唯一标识
#define MCU_VER          "1.0.0"     // MAX 3.3.15,BIT 7~0,XX.XX.XXXX
#define SUPPORT_RECEIVE_BROADCAST_DATA    1     // 0:不支持,1:支持
#define DEVICE_TYPE     0     // 0:标准功耗设备(router),1:低功耗设备(sleep end device),2:场景开关(scene switch)
#if (DEVICE_TYPE == 1)
#define SLEEP_END_DEVICE     1     // 只有该设备类型才支持的命令:0x2b
#elif (DEVICE_TYPE == 2)
#define SCENE_SWITCH     1     // 只有该设备类型才支持的命令:0x0a,0x41,0x42 和 0x43,只有该设备类型不支持的命令:0x25,0x26 和 0x2a
#endif
在 protocol.h 中,确认 DP ID 宏(DPID_ 前缀)。
#define DPID_TEMP_ROOM 101
#define DPID_AIRCOND_SWITCH 102
#define DPID_AIRCOND_TEMP_SET 103
...
在 protocol.c 中,确认 DP 信息数组。
const DOWNLOAD_CMD_S download_cmd[] =
{
  {DPID_TEMP_ROOM, DP_TYPE_VALUE},
  {DPID_AIRCOND_SWITCH, DP_TYPE_BOOL},
  {DPID_AIRCOND_TEMP_SET, DP_TYPE_VALUE},
  ...
};
在 protocol.c 里的 mcu_rx_gw_check_dp 函数中,确认设备接收到网关查询 DP 命令后,设备上报 DP 的方式。
0x06 命令字。0x2c 命令字。static void mcu_rx_gw_check_dp(UART_FRAME_T *uart_frame)
{
    ///< 1. 发送 0x28,不携带 payload
    ...
    ///< 2. DP 上报类型(是否触发联动)
    g_dp_send_type = DP_SEND_TYPE_REPORT_LINKAGE;       // 0x06
    // g_dp_send_type = DP_SEND_TYPE_REPORT_NOT_LINKAGE;   // 0x2c
    ///< 3. 上报 DP
    ...
}
在 protocol.c 中,完善 all_data_update() 函数,例如传入代表当前 DP 真实值的变量(该变量需要用户自行提供)。
static void all_data_update(void)
{
    mcu_dp_bool_update(DPID_AIRCOND_SWITCH,my_aircond_switch_value);
    mcu_dp_bool_update(DPID_AIRCOND_ECO,my_aircond_eco_value);
    ...
}
在 protocol.c 中,完善 specific_DP_update() 函数。只需要根据 DP ID,调用符合 DP 数据类型的 DP 上报函数。
static void specific_dp_update(unsigned char dp_id)
{
    switch (dp_id) {
        /** please refer the following example and 'all_data_update()'
         *
         *     case DPID_SCENE_1: {
         *         mcu_dp_enum_update(DPID_SCENE_1,当前场景 1); //枚举型数据上报
         *         break;
         *     }
         *
         *     case DPID_SCENE_2: {
         *         mcu_dp_enum_update(DPID_SCENE_2,当前场景 2); //枚举型数据上报
         *         break;
         *     }
         */
        case DPID_AIRCOND_SWITCH: {
            mcu_dp_bool_update(DPID_AIRCOND_SWITCH,my_aircond_switch_value);
            break;
        }
        case DPID_AIRCOND_ECO: {
            mcu_dp_bool_update(DPID_AIRCOND_ECO,my_aircond_eco_value);
            break;
        }
        default: {
            break;
        }
    }
}
在 protocol.c 中,查看 dp_msg_handle() 函数,并完善该函数使用的 DP 下发处理函数。DP_download_xxxxxx_handle() 格式,不同 DP 的函数内容稍有差异。
static unsigned char dp_msg_handle(unsigned char dp_id, const unsigned char *value, unsigned short length)
{
    unsigned char ret;
    if (NULL == value) {
        return ERROR;
    }
    switch (dp_id) {
        case DPID_AIRCOND_SWITCH:
            ret = dp_download_aircond_switch_handle(value,length);
        break;
        ...
        default :
            break;
    }
    return ret;
}
static unsigned char dp_download_aircond_switch_handle(const unsigned char value[], unsigned short length)
{
    unsigned char ret;
    //0:off/1:on
    unsigned char aircond_switch;
    aircond_switch = mcu_get_dp_download_bool(value,length);
    if(aircond_switch == 0) {
        //bool off
        ...
        my_aircond_switch_off_handle();
        ...
    }else {
        //bool on
        my_aircond_switch_on_handle();
    }
    //There should be a report after processing the DP
    ret = mcu_dp_bool_update(DPID_AIRCOND_SWITCH,aircond_switch);
    if(ret == SUCCESS)
        return SUCCESS;
    else
        return ERROR;
}
移植成功后,用户只需要关心如下内容:
帧发送函数(mcu_tx_ 前缀)
MCU 主动发送帧的接口。
用户可直接调用这些函数,发送串口协议帧给烧录了通用对接固件的 Zigbee 模组。
/*
void mcu_tx_let_zigbee_reset(void)
{
    unsigned short payload_len = 0;
    uart_framing_fill_payload_byte(&payload_len, 0x00);
    uart_framing_fill_protocol_field(UART_CMD_RESET_OR_JOIN, payload_len, NULL);
    uart_send_frame(payload_len);
}
*/
int main(void)
{
    ...
    mcu_tx_let_zigbee_reset();
    ...
}
帧接收处理函数(完整流程,mcu_rx_ 前缀)
MCU 接收到帧后 完整的处理流程。禁止用户修改。
用户可结合 串口协议 相应命令的时序图,了解该命令的接收处理流程。
static void mcu_rx_factory_recovery_notify(UART_FRAME_T *uart_frame)
{
    if (NULL == uart_frame || NULL == uart_frame->frame_payload) {
        return;
    }
    ///< 1. 发送帧
    unsigned short payload_len = 0;
    uart_framing_fill_payload_byte(&payload_len, 0x01);
    uart_framing_fill_protocol_field(UART_CMD_FACTORY_RECOVERY, payload_len, &uart_frame->frame_seq);
    uart_send_frame(payload_len);
    ///< 2. 恢复出厂设置
    mcu_recv_factory_recovery_cb();
}
帧接收处理函数(用户接口,mcu_recv_ 前缀)
MCU 接收到帧后 提供给用户进行处理的接口,需要用户实现。
用户可查看这些函数被调用的位置,然后结合 串口协议 相应命令的时序图,确定这些函数的工作时点。
功能
通用宏
源代码
#ifndef TRUE
#define TRUE                    1
#endif
#ifndef FALSE
#define FALSE                   0
#endif
#ifndef NULL
#define NULL                    ((void *)0)
#endif
#ifndef SUCCESS
#define SUCCESS                 1
#endif
#ifndef ERROR
#define ERROR                   0
#endif
#ifndef INVALID
#define INVALID                 0xFF
#endif
#ifndef ENABLE
#define ENABLE                  1
#endif
#ifndef DISABLE
#define DISABLE                 0
#endif
功能
通用功能函数
函数说明
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| get_seq_num | 生成 16 位序列号 | 用于发送串口协议帧给模组 | 
| get_u8_checksum | 计算 8 位校验和 | 用户计算串口协议帧的校验和 | 
| my_strlen | 和 strlen 功能一致 | 
- | 
| my_memset | 和 memset 功能一致 | 
- | 
| my_memcpy | 和 memcpy 功能一致 | 
- | 
| my_strcpy | 和 strcpy 功能一致 | 
最后一个字节会被替换为 ‘\0’ | 
| my_strcmp | 和 strcmp 功能一致 | 
- | 
| my_strncmp | 和 strncmp 功能一致 | 
- | 
| hex_to_bcd | 16 进制数据转为 BCD 码 | - | 
| int_to_byte | 32 位数据转为 4 个 8 位数据 | - | 
| byte_to_int | 4 个 8 位数据转为 32 位数据 | - | 
| ascii_to_hex | ASCII 码转为 16 进制数据 | - | 
队列处理函数
函数说明
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| queue_dequeue_byte | 出队(单字节) | 出队前,会进行空队检测TRUE:出队成功 | 
| queue_enqueue_byte | 入队(单字节) | 入队前,会进行满队检测TRUE:入队成功 | 
组帧函数
函数说明
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| uart_framing_fill_payload_byte | 协议帧 payload 字段填充:单字节 | - | 
| uart_framing_fill_payload_buff | 协议帧 payload 字段填充:多字节 | - | 
| uart_framing_fill_payload_add_group_id | 协议帧 payload 字段填充:在 payload 字段的开头插入 group ID,2 字节 | 仅用于发送群组 DP 消息(串口协议命令字 0x43) | 
| uart_framing_fill_protocol_field | 协议帧其它字段填充 | - | 
功能
队列处理函数
函数说明
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| queue_is_empty | 空队检测 | TRUE:空队 | 
| queue_is_full | 满队检测 | TRUE:满队 | 
功能
配置项
设备信息
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| PRODUCT_KEY | PID | 只有前 8 位有效。 用户需要检查是否为通用对接设备的 PID。  | 
| MCU_VER | MCU 固件版本(本地) | MCU 会上报该固件号。 MCU 接收到 OTA 升级通知后,会把 OTA 包中的版本号与该版本号进行比较。  | 
| SUPPORT_RECEIVE_BROADCAST_DATA | MCU 是否需要区分群控消息
  | 
Zigbee 模组会通过产品信息命令(命令字 0x01)获取该值。
  | 
| DEVICE_TYPE | 设备类型
  | 
如需了解不同设备类型的命令支持情况,参考通用对接串口协议文档。 | 
| SLEEP_END_DEVICE | 设备类型标识:低功耗 | - | 
| SCENE_SWITCH | 设备类型标识:标准功耗(场景开关) | - | 
#define PRODUCT_KEY "ksubawat"    //在开发者平台创建产品后生成,16 位字符组成的产品唯一标识
#define MCU_VER                                 "1.0.0"         // MAX 3.3.15,BIT 7~0,XX.XX.XXXX
#define SUPPORT_RECEIVE_BROADCAST_DATA          1               // 0:不支持,1:支持
#define DEVICE_TYPE                             0               // 0:标准功耗设备(router),1:低功耗设备(sleep end device),2:场景开关(scene switch)
#if (DEVICE_TYPE == 1)
#define SLEEP_END_DEVICE                        1               // 只有该设备类型才支持的命令:0x2b
#elif (DEVICE_TYPE == 2)
#define SCENE_SWITCH                            1               // 只有该设备类型才支持的命令:0x0a,0x41,0x42 和 0x43,只有该设备类型不支持的命令:0x25,0x26 和 0x2a
#endif
DP ID
示例
#define DPID_TEMP_ROOM 101
#define DPID_AIRCOND_SWITCH 102
#define DPID_AIRCOND_TEMP_SET 103
...
协议信息
帧字段 ID
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| FRAME_FIELD_HDR_HIGH | 帧头的高字节的序号 | - | 
| FRAME_FIELD_HDR_LOW | 帧头的低字节的序号 | - | 
| FRAME_FIELD_PROT_VER | 串口协议版本的序号 | - | 
| FRAME_FIELD_SEQ_HIGH | 帧序列号的高字节的序号 | - | 
| FRAME_FIELD_SEQ_LOW | 帧序列号的低字节的序号 | - | 
| FRAME_FIELD_CMD_ID | 帧命令字的序号 | - | 
| FRAME_FIELD_PAYLOAD_LEN_HIGH | 帧 payload 长度的高字节的序号 | 如无 payload,则长度高低字节都为 0 | 
| FRAME_FIELD_SEQ_LOW | 帧 payload 长度的低字节的序号 | - | 
| FRAME_FIELD_PAYLOAD_START | 帧 payload 的起始序号 | - | 
| FRAME_LEN_WITHOUT_PAYLOAD | 最小帧长 | 不携带 payload 时的帧长 | 
帧尾为校验和,因为 payload 长度可变,所以不使用序号来表示帧尾。
#define FRAME_FIELD_HDR_HIGH                    0
#define FRAME_FIELD_HDR_LOW                     1
#define FRAME_FIELD_PROT_VER                    2
#define FRAME_FIELD_SEQ_HIGH                    3
#define FRAME_FIELD_SEQ_LOW                     4
#define FRAME_FIELD_CMD_ID                      5
#define FRAME_FIELD_PAYLOAD_LEN_HIGH            6
#define FRAME_FIELD_PAYLOAD_LEN_LOW             7
#define FRAME_FIELD_PAYLOAD_START               8
#define FRAME_LEN_WITHOUT_PAYLOAD               9           // the shortest frame length (no payload)
帧字段值
| 标识 | 说明 | 
|---|---|
| FRAME_VALUE_HDR_HIGH | 帧头的高字节的值 | 
| FRAME_VALUE_HDR_LOW | 帧头的低字节的值 | 
| FRAME_VALUE_HDR | 帧头的值 | 
| FRAME_VALUE_PROT_VER | 串口协议版本的值 | 
帧头 和 版本号 被用于识别通用对接串口协议帧。
#define FRAME_VALUE_HDR_HIGH                    0x55
#define FRAME_VALUE_HDR_LOW                     0xaa
#define FRAME_VALUE_HDR                         0x55aa
#define FRAME_VALUE_PROT_VER                    0x02
命令字
如果想详细了解,参考 串口协议。
#define UART_CMD_FACTORY_RECOVERY               0x00
#define UART_CMD_PRODUCT_INFO                   0x01
#define UART_CMD_ZG_NWK_STATUS_NOTIFY           0x02
#define UART_CMD_RESET_OR_JOIN                  0x03
#define UART_CMD_RX_DP                          0x04
#define UART_CMD_RESPOND_DP                     0x05
#define UART_CMD_REPORT_DP_LINKAGE              0x06
#define UART_CMD_ZG_INFO                        0x07
#define UART_CMD_RF_TEST                        0x08
#define UART_CMD_SCENE_INFO                     0x0A
#define UART_CMD_MCU_VER                        0x0B
#define UART_CMD_OTA_NOTIFY                     0x0C
#define UART_CMD_OTA_DATA                       0x0D
#define UART_CMD_OTA_RESULT                     0x0E
#define UART_CMD_ZG_NWK_STATUS_REQUEST          0x20
#define UART_CMD_DOUBLE_DONGLE_DATA_NOTIFY      0x21
#define UART_CMD_DOUBLE_DONGLE_REPORT           0x22
#define UART_CMD_TIME_SYNC                      0x24
#define UART_CMD_MCU_CHECK_GW_NWK_STAUTS        0x25
#define UART_CMD_MCU_SET_ZG_NWK_PARAM           0x26
#define UART_CMD_SEND_DP_BROADCAST              0x27
#define UART_CMD_GW_CHECK_DP                    0x28
#define UART_CMD_BEACON_TEST                    0x29
#define UART_CMD_RX_DP_GROUP                    0x2A
#define UART_CMD_ZG_WAIT_MCU_TIME               0x2B
#define UART_CMD_REPORT_DP_NOT_LINKAGE          0x2C
#define UART_CMD_CONFIG_ZG_GPIO                 0x36
#define UART_CMD_READ_ZG_GPIO                   0x37
#define UART_CMD_WRITE_ZG_GPIO                  0x38
#define UART_CMD_ZG_GPIO_IRQ                    0x39
#define UART_CMD_WEATHER_REQUEST                0x3A
#define UART_CMD_WEATHER_RESPONSE               0x3B
#define UART_CMD_SCENE_CONFIG                   0x41
#define UART_CMD_SEND_CMD_GROUP                 0x42
#define UART_CMD_SEND_DP_GROUP                  0x43
命令相关信息
DP 数据类型
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| DP_TYPE_RAW | 透传型 | - | 
| DP_TYPE_BOOL | 布尔型 | - | 
| DP_TYPE_VALUE | 数值型 | - | 
| DP_TYPE_STRING | 字符型 | - | 
| DP_TYPE_ENUM | 枚举型 | - | 
| DP_TYPE_BITMAP | 位图型 | - | 
| DP_TYPE_FAULT | 故障型 | 该类型的处理和 DP_TYPE_BITMAP 的处理完全一致 | 
#define DP_TYPE_RAW                             0x00
#define DP_TYPE_BOOL                            0x01
#define DP_TYPE_VALUE                           0x02
#define DP_TYPE_STRING                          0x03
#define DP_TYPE_ENUM                            0x04
#define DP_TYPE_BITMAP                          0x05
#define DP_TYPE_FAULT                           DP_TYPE_BITMAP
Zigbee 模组信息查询标识(命令字 0x07)
| 标识 | 说明 | 
|---|---|
| ZG_INFO_TYPE_SW_VER | MCU 想查询 Zigbee 模组的固件版本 | 
| ZG_INFO_TYPE_AUTH | MCU 想查询 Zigbee 模组的授权信息 | 
| ZG_INFO_TYPE_MAC_ADDR | MCU 想查询 Zigbee 模组的 MAC 地址 | 
#define ZG_INFO_TYPE_SW_VER                     0x01
#define ZG_INFO_TYPE_AUTH                       0x02
#define ZG_INFO_TYPE_MAC_ADDR                   0x03
Zigbee 模组网络参数(命令字 0x26)
| 标识 | 说明 | 
|---|---|
| HEART_PERIOD_DEFAULT_SET | MCU 想设置 Zigbee 模组的 心跳周期 为默认值 | 
| JOIN_TIMEOUT_DEFAULT_SET | MCU 想设置 Zigbee 模组的 JOIN 超时时长 为默认值 | 
| REJOIN_INTERVAL_DEFAULT_SET | MCU 想设置 Zigbee 模组的 每轮 REJOIN 的间隔 为默认值 | 
| POLL_INTERVAL_DEFAULT_SET | MCU 想设置 Zigbee 模组的 POLL 间隔 为默认值 | 
| FAST_POLL_PERIOD_DEFAULT_SET | MCU 想设置 Zigbee 模组的 上电 POLL 的时间 为默认值 | 
| POLL_FAIL_TIMES_DEFAULT_SET | MCU 想设置 Zigbee 模组的 POLL 最大失败次数 为默认值 | 
| APP_DATA_TRIG_REJOIN_DEFAULT_SET | MCU 想设置 Zigbee 模组的 数据触发 REJOIN 为默认值 | 
| REJOIN_TRY_TIMES_DEFAULT_SET | MCU 想设置 Zigbee 模组的 每轮 REJOIN 的尝试次数 为默认值 | 
| RF_POWER_DEFAULT_SET | MCU 想设置 Zigbee 模组的 发送功率 为默认值 | 
| NWK_PARAM_DEFAULT_SET | MCU 想设置 Zigbee 模组的 所有参数 为默认值 | 
#define HEART_PERIOD_DEFAULT_SET                0xfffe
#define JOIN_TIMEOUT_DEFAULT_SET                0xfffe
#define REJOIN_INTERVAL_DEFAULT_SET             0xfffe
#define POLL_INTERVAL_DEFAULT_SET               0xfffe
#define FAST_POLL_PERIOD_DEFAULT_SET            0xfffe
#define POLL_FAIL_TIMES_DEFAULT_SET             0xfe
#define APP_DATA_TRIG_REJOIN_DEFAULT_SET        0xfe
#define REJOIN_TRY_TIMES_DEFAULT_SET            0xfe
#define RF_POWER_DEFAULT_SET                    0xfe
#define NWK_PARAM_DEFAULT_SET                   {HEART_PERIOD_DEFAULT_SET, JOIN_TIMEOUT_DEFAULT_SET, REJOIN_INTERVAL_DEFAULT_SET, POLL_INTERVAL_DEFAULT_SET, FAST_POLL_PERIOD_DEFAULT_SET, POLL_FAIL_TIMES_DEFAULT_SET, APP_DATA_TRIG_REJOIN_DEFAULT_SET, REJOIN_TRY_TIMES_DEFAULT_SET, RF_POWER_DEFAULT_SET}
命令相关数据类型
模组网络状态(命令字 0x02 和 0x20)
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| ZG_NWK_STATUS_NOT_JOIN | 未配网 | - | 
| ZG_NWK_STATUS_JOINED | 已配网 | - | 
| ZG_NWK_STATUS_ERROR | 网络状态异常 | 表示模组尚未收到 MCU 返回的产品信息 | 
| ZG_NWK_STATUS_JOINING | 正在配网 | - | 
typedef enum {
    ZG_NWK_STATUS_NOT_JOIN = 0,
    ZG_NWK_STATUS_JOINED,
    ZG_NWK_STATUS_ERROR,
    ZG_NWK_STATUS_JOINING,
} ZG_NWK_STATUS_E;
时间同步结构体(命令字 0x24)
| 标识 | 说明 | 
|---|---|
| TIME_SYNC_CALENDAR_T | 用于存放时间戳的转换结果 | 
typedef struct {
    unsigned short w_year;
    unsigned char w_month;
    unsigned char w_day;
    unsigned char hour;         // +8 for Beijing time
    unsigned char min;
    unsigned char sec;
} TIME_SYNC_CALENDAR_T;
网关联网状态(命令字 0x25)
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| GW_NWK_STATUS_OFFLINE | 离线 | 网关未连接互联网 | 
| GW_NWK_STATUS_ONLINE | 在线 | - | 
| GW_NWK_STATUS_RESPOND_TIMEOUT | 网关回复超时 | - | 
typedef enum {
    GW_NWK_STATUS_OFFLINE = 0,
    GW_NWK_STATUS_ONLINE,
    GW_NWK_STATUS_RESPOND_TIMEOUT,
} GW_NWK_STATUS_E;
Zigbee 模组网络参数结构体(命令字 0x26)
| 标识 | 说明 | 
|---|---|
| NWK_PARAM_T | 用于配置 Zigbee 模组的网络参数 | 
typedef struct {
    unsigned short heart_period;
    unsigned short join_timeout;
    unsigned short rejoin_interval;
    unsigned short poll_interval;
    unsigned short fast_poll_period;            // power on poll period
    unsigned char poll_fail_times;
    unsigned char app_data_trig_rejoin;
    unsigned char rejoin_try_times;
    unsigned char rf_power;
} NWK_PARAM_T;
Zigbee 模组 GPIO(命令字 0x36、0x37 和 0x38)
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| MCU_CONFIG_GPIO_T | 用于配置 Zigbee 模组的 GPIO 电平 | - | 
| MCU_READ_GPIO_T | 用于读 Zigbee 模组的 GPIO 电平 | 支持 input 或 output 模式的 GPIO | 
| MCU_WRITE_GPIO_T | 用于写 Zigbee 模组的 GPIO 电平 | 仅支持 output 模式的 GPIO | 
typedef struct {
    unsigned char port_num;
    unsigned char pin_num;
    unsigned char gpio_mode;
    unsigned char gpio_level;
} MCU_CONFIG_GPIO_T;
typedef struct {
    unsigned char port_num;
    unsigned char pin_num;
} MCU_READ_GPIO_T;
typedef struct {
    unsigned char port_num;
    unsigned char pin_num;
    unsigned char gpio_level;
} MCU_WRITE_GPIO_T;
天气/城市信息(命令字 0x3b)
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| WEATHER_INFO_T | 用于处理模组返回的天气信息 | 需要结合协议文档,解析天气信息 | 
| CITY_INFO_T | 用于处理模组返回的城市信息 | 需要结合协议文档,解析城市信息 | 
typedef struct {
    unsigned char version;                  // 0x11
    unsigned char addr_type;
    unsigned char forecast_flag;            // 0x12
    unsigned char forecast_days;
    unsigned char real_time_weather_flag;   // 0x13
    unsigned char real_time_enable;
    unsigned char *weather_detail;
    unsigned char weather_detail_len;
} WEATHER_INFO_T;
typedef struct {
    unsigned char version;                  // 0x11
    unsigned char addr_type;
    unsigned char *city_detail;
    unsigned char city_detail_len;
} CITY_INFO_T;
群组标准命令(命令字 0x42)
| 标识 | 说明 | 
|---|---|
| MCU_SEND_CMD_GROUP_T | 用于发送群组标准命令给 Zigbee 模组 | 
#if SCENE_SWITCH
typedef struct {
    unsigned short group_id;
    unsigned short cluster_id;
    unsigned char command_id;
    unsigned char *payload;
    unsigned char payload_len;
} MCU_SEND_CMD_GROUP_T;
#endif
DP 发送类型
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| DP_SEND_TYPE_NOT_SEND | 接收到 DP 消息后,不进行应答 | MCU 接收到群控 DP 消息(命令字 0x2a)时,不需要进行应答 | 
| DP_SEND_TYPE_RESPOND | 接收到 DP 消息后,进行应答(命令字 0x05) | 
MCU 接收到 DP 消息(命令字 0x04)时,需要进行应答 | 
| DP_SEND_TYPE_REPORT_LINKAGE | 上报 DP 消息,触发联动(命令字 0x06) | 
- | 
| DP_SEND_TYPE_REPORT_NOT_LINKAGE | 上报 DP 消息,不触发联动(命令字 0x2c) | 
- | 
| DP_SEND_TYPE_SEND_BROADCAST | 发送广播 DP 消息(命令字 0x27) | 
- | 
| DP_SEND_TYPE_SEND_GROUP | 发送群组 DP 消息(命令字 0x43) | 
- | 
typedef enum {
    DP_SEND_TYPE_NOT_SEND,                      // Not send: when the MCU receives a broadcast DP message (UART command ID: 0x2a), it doesn't need to respond.
    DP_SEND_TYPE_RESPOND,                       // Respond to DP messages (UART command ID: 0x05): when the MCU receives a DP message (UART command ID: 0x04), it needs to respond to the Zigbee module.
    DP_SEND_TYPE_REPORT_LINKAGE,                // Report a DP message with linkage trigger (UART command ID: 0x06)
    DP_SEND_TYPE_REPORT_NOT_LINKAGE,            // Report a DP message without linkage trigger (UART command ID: 0x2c)
    DP_SEND_TYPE_SEND_BROADCAST,                // Send a DP message broadcast (UART command ID: 0x27)
    DP_SEND_TYPE_SEND_GROUP,                    // Send a DP message to a group (UART command ID: 0x43)
} DP_SEND_TYPE_E;
帧接收函数
函数说明
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| frame_rx_handle | 帧接收处理总接口 | 帧解析成功后,会进入该函数,然后根据命令字调用相应的帧接收处理函数(完整流程) | 
DP 处理函数
函数说明
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| dp_info_check | 检查 DP ID、数据类型 | - | 
| mcu_get_dp_download_bool … mcu_get_dp_download_value  | 
获取 DP 数据值 | - | 
| mcu_dp_raw_update … mcu_dp_fault_update  | 
发送 DP | 这些函数均通过 __dp_send_type_handle 发送 DP 消息 | 
功能
协议和命令相关定义
源代码
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| DOWNLOAD_CMD_S | DP 消息数组的数据类型 | 包含 DP ID 和对应的 DP 数据类型 | 
| UART_FRAME_T | 串口协议帧的数据结构体(不完整) | 不包含校验和,校验和的使用场合只有帧解析过程 | 
| OTA_FW_INFO_T | MCU 固件 OTA 升级信息 | - | 
typedef struct {
    unsigned char DP_id;
    unsigned char DP_type;
} DOWNLOAD_CMD_S;
typedef struct {
    unsigned short frame_hdr;
    unsigned char frame_ver;
    unsigned short frame_seq;
    unsigned char frame_cmd;
    unsigned short frame_payload_len;
    unsigned char *frame_payload;
} UART_FRAME_T;
typedef struct {
    unsigned char ota_pid[8];               // MCU PID
    unsigned char ota_fw_ver;               // new MCU fw version
    unsigned int ota_fw_size;               // MCU firmware total size
    unsigned int ota_current_offset;        // MCU firmware current offset
    unsigned int ota_expect_checksum;       // MCU firmware expective checksum
} OTA_FW_INFO_T;
帧接收处理函数(完整流程)
函数说明
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| mcu_rx_factory_recovery_notify … mcu_rx_scene_config  | 
mcu_rx_ 前缀各命令字的帧接收处理函数(完整流程)  | 
这些函数体现了帧接收处理的完整流程。对于需要用户处理的时点,均提供了用户接口(mcu_recv_ 前缀) | 
DP 消息处理函数
函数说明
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| __dp_send_type_handle | 发送 DP (底层) | 调用本函数前,需要先指定 g_dp_send_type 的值(即 DP 发送类型)。 | 
| DP_download_xxxxxx_handle | 特定 DP ID 的下发处理函数 | 这些函数由云平台生成,用户需要完善这些函数。 | 
| DP_msg_handle | 所有 DP ID 的下发处理总接口 | - | 
| all_data_update | 全 DP 上报函数 | MCU 接收到网关查询 DP 命令(命令字 0x28)后,如果查询列表为空,则 MCU 需要上报所有 DP。用户需要完善该函数,例如使用代表 DP 真实值的变量。 | 
| specific_DP_update | 单 DP 上报函数 | MCU 接收到网关查询 DP 命令(命令字 0x28)后,如果查询列表非空,则 MCU 需要上报列表包含的 DP。用户需要参考 all_data_update() 完善该函数,即根据不同的 DP ID,调用相应的 DP 值上报函数。 | 
功能
用户可以结合 串口协议 的时序图,对照 帧接收处理函数(完整流程),了解 帧接收处理函数(用户接口) 的调用时点,从而准确处理帧接收数据。
配置项
调试信息打印开关
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| MCU_SDK_DEBUG | 调试打印开关 | 
  | 
| PRINT_DEBUG(fmt, …) | 调试打印的实现 | 用户需要把 PROJECT_PRINT_FUNC 替换为工程的调试信息打印函数 | 
#ifndef MCU_SDK_DEBUG
#define MCU_SDK_DEBUG           1
#endif
#if MCU_SDK_DEBUG
#define PRINT_DEBUG(fmt, ...)   PROJECT_PRINT_FUNC(fmt, ##__VA_ARGS__)
#else
#define PRINT_DEBUG(fmt, ...)
#endif
串口及队列缓冲区的尺寸
| 标识 | 说明 | 
|---|---|
| UART_RX_BUF_LEN_LMT | 串口接收缓冲区的尺寸 | 
| UART_TX_BUF_LEN_LMT | 串口发送缓冲区的尺寸 | 
| UART_QUEUE_BUF_LEN_LMT | 队列缓冲区的尺寸 | 
MCU SDK 串口数据接收处理流程:
MCU SDK 串口数据发送流程:
#define UART_RX_BUF_LEN_LMT                     256
#define UART_TX_BUF_LEN_LMT                     256
#define UART_QUEUE_BUF_LEN_LMT                  512
命令相关信息
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| OTA_PACKET_SIZE | OTA 单包尺寸 | 在接收 OTA 升级数据时使用,最大值为 0x30。 | 
| ZG_WAIT_MCU_TIME_DEFAULT | Zigbee 模组等待 MCU 退出休眠状态的时间 | 在 Zigbee 模组电平唤醒 MCU 或 MCU 脉冲唤醒 Zigbee 模组时使用。用户需要根据使用的 MCU 情况修改该值。 | 
///< OTA single packet payload length (uart command id: 0x0c 0x0d 0x0e)
#define OTA_PACKET_SIZE                         0x30            // max: 0x30
///< Zigbee module waits MCU time after Zigbee module starting wakeuping MCU (uart command id: 0x2b)
#if SLEEP_END_DEVICE
#define ZG_WAIT_MCU_TIME_DEFAULT                10
#endif
串口服务函数
函数说明
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| uart_servive_rx_store | 串口数据单字节接收处理函数 | 该函数会把串口接收到的每个字节数据入队。用户需要把该函数添加到工程的串口数据单字节接收处理函数中。 | 
| uart_service_parse | 帧解析函数 | 该函数会出队,然后解析出队的所有数据(含之前未解析成功的数据)。用户需要把该函数添加到工程里的主循环或定时器回调中。 | 
串口数据发送函数
函数说明
| 标识 | 说明 | 注意事项 | 
|---|---|---|
| uart_send_frame | 帧发送函数 | 对于低功耗设备,用户需要在本函数中选择 MCU 唤醒 Zigbee 模组的方式,并在工程里实现对应的唤醒发送函数 | 
| uart_send_bytes | 串口多字节发送函数 | - | 
| uart_send_byte | 串口单字节发送函数 | 用户需要在工程里实现该函数,只需要在本函数里调用工程的串口数据单字节发送函数 | 
MCU 唤醒 Zigbee 函数
函数说明
| 标识 | 说明 | 
|---|---|
| mcu_wakeup_zg_level_method | MCU 唤醒 Zigbee 模组函数,电平唤醒 | 
| mcu_wakeup_zg_pulse_method | MCU 唤醒 Zigbee 模组函数,脉冲唤醒 | 
帧接收处理函数(用户接口)
函数说明
| 标识 | 说明 | 
|---|---|
| mcu_recv_factory_recovery_cb … mcu_recv_scene_config_cb  | 
mcu_recv_ 前缀,各命令字的帧接收处理函数(用户接口) | 
帧发送函数
函数说明
| 标识 | 说明 | 
|---|---|
| mcu_tx_let_zigbee_reset … mcu_tx_send_DP_group  | 
mcu_tx_ 前缀,各命令字的帧发送函数 | 
功能
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈