一、建STM32CubeMX工程
1、打开STM32CubeMX软件,选择以MCU开始项目。
2、搜索自己用的MCU,然后双击搜索出来的结果,开始编辑工程。
3、选择系统Debug,这里选择Serial Wire方式。
4、选择系统时钟,这里选择Crystal/Ceramic Resonator。
5、USART1选择Asynchronous模式,即异步通信模式。配置串口通信的参数,这里选择波特率115200,8数据位,无奇偶校验,1停止位。
6、打开USART1中断。
7、配置时钟,直接在HCLK中输入72MHZ,点击回车,软件将自动配置好。
8、 输入工程名称、工程保存地址、以及编译环境(KEIL5)。
9、选择下图中左边这个选项,软件会为每个外设建立单独的.c/.h文件,不过我的习惯是不使用。最后,点击GENERATE CODE生成整个工程。
二、程序编写
1、找到工程保存的位置,打开KEIL5工程如下:
2、在main.c文件中加入必要的头文件,定义需要用到的变量参数。
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <string.h>
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define MAXSIZE 256 //最大接收字节数
char RXBUFFER[MAXSIZE]; //存储接收数据的数组
uint8_t RXDATA; //接收中断缓冲
uint8_t RX_COUNT = 0; //接收缓冲计数
uint8_t RXFLAG=0; //结束位判断正确标志
/* USER CODE END PTD */
3、在USART1初始化函数中开启接收中断,并将接收的数据存储到RXDATA。
/**
* @brief USART1 Initialization Function
* @param None
* @retval None
*/
static void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
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();
}
/* USER CODE BEGIN USART1_Init 2 */
HAL_UART_Receive_IT(&huart1, (uint8_t *)&RXDATA, 1);//开启接收中断,将接收数据存储到RXDATA
/* USER CODE END USART1_Init 2 */
}
4、重定义USART1接收中断回调函数,这里的处理逻辑是,当数据结尾是0x0d 0x0a,即认为接收到有用的数据了,标志位RXFLAG置1,然后while(1)中对数据进行处理。另外还重定义了printf和scanf函数到USART1。
/* USER CODE BEGIN 4 */
//重定义接收中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(RX_COUNT >= 255) //溢出判断
{
RX_COUNT = 0;
memset(RXBUFFER,0x00,sizeof(RXBUFFER));
HAL_UART_Transmit(&huart1, (uint8_t *)"数据溢出", 10,0xFFFF);
}
else
{
RXBUFFER[RX_COUNT++] = RXDATA; //接收数据转存
if((RXBUFFER[RX_COUNT-1] == 0x0A)&&(RXBUFFER[RX_COUNT-2] == 0x0D)) //判断\r\n结束位
{
RXFLAG = 1;
}
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)&RXDATA, 1); //再开启接收中断
}
//函数功能: 重定向c库函数printf到USART1
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
//函数功能: 重定向c库函数getchar,scanf到USART1
int fgetc(FILE *f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
return ch;
}
/* USER CODE END 4 */
5、在while(1)中对接收数据进行处理,将接收到的数据发送出去。
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(RXFLAG==1)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&RXBUFFER, RX_COUNT,0xFFFF); //将收到的信息发送出去
RX_COUNT = 0;
memset(RXBUFFER,0x00,sizeof(RXBUFFER)); //清空数组
RXFLAG = 0;
}
}
/* USER CODE END 3 */
三、程序运行
1、选择烧写后即运行(Reset and Run),然后编译、烧写。
2、运行结果。