我正在使用STM32F411RE NUCLEO板来创建Zigbee网状网络。我购买了Zigbee开发版。了解设备的工具包。
起初,我使用Digi的XCTU软件来配置设备。在一切正常之后,我尝试通过Zigbee设备通过UART与NUCLEO板进行通信。
要进入AT命令模式,我必须通过UART发送“ +++”。
这是CUBEMX如何生成我的UART初始化
static void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
}
我编写了第一个功能以进入AT命令模式。在main.c中,我包含了存储我的函数的Header。
#include <XBEE_AT_CMD.h>
在while循环内,我这样调用我的函数,并传递了huart1。
while (1)
{
if( AT_enter_CMDmode(&huart1) == 1 )
{
printf("OK \n");
}
else
{
printf("failed entering CMD mode \n");
}
HAL_Delay(1000);
}
其自身的功能如下所示。它只是向Zigbee发送“ +++”。之后,我会收到答案。
int AT_enter_CMDmode(UART_HandleTypeDef *huart)
{
char receive[3];
HAL_UART_Transmit(huart,(uint8_t*)"+++", 3, 100);
HAL_UART_Receive(huart, (uint8_t*)receive, 3, 100);
if( strcmp(receive,OK) == 0 )
{
return 1;
}
else
{
return 0;
}
}
我通过发送“ +++”进入AT命令模式后,设备将以“确定”进行应答。但这有时是可行的。我尝试应用一些延迟,因为在数据表中它说您应该在进入命令模式之前和之后实施保护时间。有时我得到的答案与期望值“ OK”相似,但结尾没有回车符,或者两个“ O”和一个“ K”。当我在HAL_UART_Receive(huart, (uint8_t*)receive, 3, 100);
之后放置一个断点时,我会从设备中看到不同的答案。
答案1:“ \ rOK”
答案2:“ \ r”
答案3:“ O”
答案4:“确定”
我正在寻找的答案是“确定\ r”
看来UART时序可能有问题?我是否以正确的方式将UART处理程序传递给了函数?感觉好像我没有正确读取UART,但不确定。
要进入命令模式,您实际上(默认情况下)需要1秒钟的“安静时间”(不发送字节),然后是“ +++”,然后是另一秒钟的安静时间。因此,您至少需要等待一秒钟,然后才能看到“确定”响应。
您还应该对处理程序进行编码,以读取尽可能多的字节,以免最终没有缓冲的数据。
我强烈建议您围绕API模式而不是透明模式设计代码。 API模式发送包含AT命令的数据帧(因此您无需进入命令模式),并允许将数据发送到网络上的多个节点(透明模式使用寄存器来设置单个目标)。
Digi提供了Open Source host library in C(在其他语言中),您应该能够将其集成到硬件中。您可以在Windows或Linux / macOS中进行测试和制作原型。
您的解析正确无误,但是主要的问题是您需要执行proper framing才能每次都获得一致的“ OK \ r \ n”答案。
并且您需要将代码更改为handle all possible Final result codes。由于您的代码现在才是OK
,因此如果调制解调器返回ERROR
,则当您扩展代码以执行比当前测试循环更有用的操作时,您的代码将不同步/可能会挂起。