更新时间:2024-11-13 08:08:35下载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_ 前缀,各命令字的帧发送函数 |
功能
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈