STM32学习笔记

您所在的位置:网站首页 STM32串口2接收不到数据 STM32学习笔记

STM32学习笔记

2023-06-10 02:49| 来源: 网络整理| 查看: 265

STM32 HAL库 串口中断 前言准备及硬件调试CubeMX配置keil软件编写注解

前言

我在HC05的文章里面已经做了串口收发的实验。但是如果在实际项目中使用的话,会出现一些问题。

比如,程序会一直停留在检测串口的函数中,如果HC05不发送数据,那么程序会因为一直没有接收到数据,导致程序卡死。

当数据发送过来,而单片机在进行其他的操作时,会来不及更新接收到的数据,导致数据丢包。

所以在实际操作中,会对串口接收开启中断,并在中断函数内,做数据的解算并对单片机发送指令。

当然你还可以开启DMA来降低CPU的功耗,让你的单片机可以做更多的事情,但是对于一个小车来说,没有那个必要。 完成项目需求比炫技重要。后续更新了DMA我会在这里转载

准备及硬件调试

这里我就不多作解释了,不清楚的可以跳转到我之前的文章观看 stm32__hc05链接

CubeMX配置

按照之前文章的方式配置,注意你的晶振频率。完成前面的配置之后只需要再开启接收中断即可

在这里插入图片描述

keil软件编写 /* USER CODE BEGIN 0 */ #include "stdio.h" #include "string.h" #define RXBUFFERSIZE 256 //最大接收字节数 char RxBuffer[RXBUFFERSIZE]; //接收数据 uint8_t aRxBuffer; //接收中断缓冲 uint8_t Uart2_Rx_Cnt = 0; //接收缓冲计数 /* USER CODE END 0 */ /* USER CODE BEGIN 1 */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { /* Prevent unused argument(s) compilation warning */ UNUSED(huart); /* NOTE: This function Should not be modified, when the callback is needed, the HAL_UART_TxCpltCallback could be implemented in the user file */ if(Uart1_Rx_Cnt >= 255) //溢出判断 { Uart1_Rx_Cnt = 0; memset(RxBuffer,0x00,sizeof(RxBuffer)); HAL_UART_Transmit(&huart1, (uint8_t *)"数据溢出", 10,0xFFFF); } else { RxBuffer[Uart1_Rx_Cnt++] = aRxBuffer; // if(RxBuffer[0] == 'c'&&RxBuffer[1] == 'm')//当发送1时,cm { unit_change = 0; } else if(RxBuffer[0] == '+'&&RxBuffer[1] == 'm')//当发送2时,m { unit_change = 1; } if((RxBuffer[Uart1_Rx_Cnt-1] == 0x0A)&&(RxBuffer[Uart1_Rx_Cnt-2] == 0x0D)) //判断结束位 { HAL_UART_Transmit(&huart1, (uint8_t *)&RxBuffer, Uart1_Rx_Cnt,0xFFFF); //将收到的信息发送出去 while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);//检测UART发送结束 Uart1_Rx_Cnt = 0; memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组 } } HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1); //因为接收中断使用了一次即关闭,所以在最后加入这行代码即可实现无限使用 } /* USER CODE END 1 */

在usart.c中添加上面两段代码 HAL_UART_RxCpltCallback()函数是一个弱函数,所以我们直接重新写一个HAL_UART_RxCpltCallback()函数来写中断回调

/* Infinite loop */ /* USER CODE BEGIN WHILE */ HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1); while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */

在main函数中开启中断

注解

在这个回调函数里面,首先是if语句来检测是否数据溢出 然后将寄存器aRxBuffer的值传给RxBuffer[]

if(RxBuffer[0] == 'c'&&RxBuffer[1] == 'm')//当发送1时,cm { unit_change = 0; } else if(RxBuffer[0] == '+'&&RxBuffer[1] == 'm')//当发送2时,m { unit_change = 1; }

这一部分是我对接收到的数据作的解析判断,写在中断回调函数里的好处就是,每一次接收到数据,都能作一次解析判断,不会因为串口发送的频率过快导致指令更新不及时

if((RxBuffer[Uart1_Rx_Cnt-1] == 0x0A)&&(RxBuffer[Uart1_Rx_Cnt-2] == 0x0D)) //判断结束位 { HAL_UART_Transmit(&huart1, (uint8_t *)&RxBuffer, Uart1_Rx_Cnt,0xFFFF); //将收到的信息发送出去 while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);//检测UART发送结束 Uart1_Rx_Cnt = 0; memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组 }

判断结束位,数据接收完毕之后,将接收到的数据在发送回去,我这里串口连接的是电脑XCOM,所以XCOM发送什么数据过来,它会再显示一遍接收到的数据。 当然你也可以用蓝牙模块来代替XCOM这样就是手机端发送数据,然后手机端再接收一遍。 原理都是一样的,不过是发送和接收的平台变了而已

这里可以用来检测我们的数据有没有发错,可以把这儿的发送删掉,只保留memset()函数来清空数组 当然你也可以不清空或者不在这个地方清空,代码是死的,人是活的,一切看你自己的想法



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3