一、zigbee模块配置
使用的是cc2530的zigbee模块,DL-30版本
这个模块是透传模块,可以直接将收到的串口信息用zigbee无线传输出去,所以代码部分的重点也就是串口部分。
该模块支持多种波特率
配置方法,在模块掉电的情况下按住案件,上电则进入配置模式,这里我选择波特率为115200,具体的配置,买芯片的时候厂家会给芯片手册,以及配置资料,可以直接去找淘宝客服问,这里我就不过多叙述。
我一般配置波特率115200,信道的话两个模块保持一致就可以
二、stm32配置
板子使用的是野火的f429挑战者,具体使用哪个型号的板子都不影响,配置都是类似的
由于zigbee模块是透传的,需要先了解串口,下面先介绍串口的配置,如果这部分已经了解,直接看后面实验部分,介绍串口以串口一为例,zigbee通讯部分不使用串口一!!!
1.介绍usart
1.1stm32cubeMX配置
芯片选择部分我就跳过了,如果不会的话,先去学习一下怎么用软件,先配置时钟,选择外部时钟源
配置时钟树,时钟可以根据需要配置,频率不固定,我就按最大配置了
SYS配置
如果需要使用中断,则勾选中断,这里发送端不用中断,接收端用,接收端勾选,发送端不用选
接下来就是给工程命名,IDE要选MDK
记得勾选分文件编程
最后选择generate code即可生成工程文件
在MDK-ARM文件夹下找到工程文件打开,在上面写文件名那一步,有文件的路径,去里面找MDK-ARM文件夹
双击MDK-ARM文件夹进入 ,找到工程文件
打开就是生成好的代码
重定向输入输出
如果需要重定向输入输出到串口调试助手
将以下代码加入到uast.c,如果报错就添加头文件
void SendData(uint8_t *pData, uint16_t Size)
{
HAL_UART_Transmit(&huart1, pData, Size, 1000);
}
/***************** 发送字符串 **********************/
void Usart_SendString(uint8_t *str)
{
unsigned int k=0;
do
{
HAL_UART_Transmit(&huart1,(uint8_t *)(str + k) ,1,1000);
k++;
} while(*(str + k)!='\0');
}
///重定向c库函数printf到串口DEBUG_USART,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
/* 发送一个字节数据到串口DEBUG_USART */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);
return (ch);
}
///重定向c库函数scanf到串口DEBUG_USART,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
int ch;
HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, 1000);
return (ch);
}
需要注意的是,所有自己添加的代码都要写到/*USER CODE BNEGIN X*/之间,不然后续在stm32cubeMX改配置的话代码会被覆盖,或者构建自己的.c文件,在自己的c文件下写(我懒就没写)
如果你发现程序不往下运行,有没有报错,那么可能是没有勾选库
编译下载就可以在串口调试助手看到printf输出的语句了
收发函数
发送
发送用
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData,
uint16_t Size, uint32_t Timeout);
接收
接收用中断,在cubemx生成好的代码里添加以下代码
首先在main.c添加开启中断的代码HAL_UART_Receive_IT(&huart1,rxbuf,sizeof(rxbuf));
位置如下,用串口几,就选择对应的串口句柄huartx
然后添加中断回调函数
中断回调函数始终是这一个,但是里面的内容可以根据自己的需求改,最后一定要再次开启中断,不然就会只进入一次中断,后面就进不去了。
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart == &huart1)
{
printf("进入中断\n");
if(rxbuf[0]==0xaa){
flag=1;
printf("%d\n",flag);
for(i=0;i<3;i++){
battery[i]=rxbuf[i+1];
}
for(i=0;i<3;i++){
printf("%x",battery[i]);
}
}else if(rxbuf[0]==0xbb){
flag=2;
printf("%d\n",flag);
for(i=0;i<3;i++){
status[i]=rxbuf[i+1];
}
for(i=0;i<3;i++){
printf("%x",status[i]);
}
}else if(rxbuf[0]==0xcc){
flag=3;
printf("%d\n",flag);
for(i=0;i<3;i++){
command[i]=rxbuf[i+1];
}
for(i=0;i<3;i++){
printf("%x",command[i]);
}
}else{
printf("wrong code\n");
}
}
HAL_UART_Receive_IT(&huart1,rxbuf,sizeof(rxbuf)); // 再次开启接收
}
具体位置
建议先分别把收发代码和串口调试助手调试,确保双方都没有问题后,在将程序下载到两块板子上,连接板子调试。
我用的板子都是野火的f429系列的,一个是核心板,一个是开发板,这都不影响,有一点要注意的是,测试的时候两块板子需要共地才能通信成功,收发也是rx->tx tx->rx。至此,板子的串口通信部份测试完成。
2.zigbee通信实验
串口一可以实现printf的重定向,打印消息到串口调试助手,因为这个串口直连了CH430这个芯片,ZigBee模块是TTL电平通信,和连接了CH430的串口一,电平标准不一样,并且这个串口很多时候也用来烧录代码,有很多功能的复用。所以我们不能用串口1接入ZigBee/蓝牙模块实现数据的远程传输,换成串口三。原理如下,前面也说了,我用的zigbee模块是透传模块,只要写好串口部分,接上zigbee就可以直接用,所以usart3用来传输信息,usart2用来看现象,检测是否能收到数据。
补充一下,printf是重定向到串口调试助手的,如果一个串口同时用zigbee和串口助手会有冲突,所以需要两个串口,也不建议把printf重定向到usart2,即使把串口接到开发板自带的ch430上,串口助手也看不到现象,这边我选用了单独的CH430透传模块,这个模块也是透传的,可以不用重定向就能把数据打印到串口调试助手,避免了冲突问题。
2.1配置
配置跟usart1一样,发送端配置为异步,不要中断
接收端usart3,usart2都要中断,需要配置一下优先级,这里设置和zigbee直连的usart3
优先级最高,接收消息优先级第一
优先级在system core里改
配置好以后生成代码
2.2代码
发送端
发送端只需要调用发送函数HAL_UART_Transmit即可
根据自己需要发送的信息大小构建发送缓冲区,发送缓冲区就是数组,我这边传了四个字节,在mian里添加如下代码,记得在同样的位置添加,不然在cubemx里改配置以后会被覆盖
接收端
接收端这边需要usart3接收中断,再将usart3接收到的信息发给usart2,usart2接收消息,利用之前的CH430透传模块即可在串口助手上看到消息。
只需在main.c中调用中断回调函数即可,仍然需要加到固定位置,不然会被覆盖
这样就能成功通信了。