本文目的是主要介绍通过STM32F103C8T6接收到字符“s”时,停止持续发送“hello windows!”; 当接收到字符“t”时,持续发送“hello windows!”;接收到字符“stop stm32!”时,停止持续发送“hello windows!”; 当接收到字符“go stm32!”时,持续发送“hello windows!”。
文章目录
前言(一)需求分析(二)“小试牛刀”——单字符发收1.中断模式介绍2.软件配置2.1 STM32cubeMX2.2 Keil 3.串口助手3.工程新创4.设置RCC5.设置SYS6.设置USART7.设置NVIC8.生成项目 (三)代码编译与收发实现1.在KEIL中进行代码编写2.main函数中的while循环里面添加传输代码3.在main函数下面重写中断处理函数4.代码汇总5.打开串口助手 (四)“大刀阔斧”——字符串发收1.新建工程2.代码编写3.烧录打开串口助手 (五)总结(六)参考文献前言
※ 在stm32CubeMX环境配置下,去实现串口通信,可参考博主的博客:/qq_52199251/article/details/127348478
※ 本文主要讲解HAL库中断方式进行串口通信。
(一)需求分析
※ 采用串口中断方式,分别实现
:
1)当stm32接收到字符“s”时,停止持续发送“hello windows!”; 当接收到字符“t”时,持续发送“hello windows!”(提示:采用一个全局标量做信号灯);
2)当stm32接收到字符“stop stm32!”时,停止持续发送“hello windows!”; 当接收到字符“go stm32!”时,持续发送“hello windows!”(提示:要将接收到的连续字符保存到一个字符数组里,进行判别匹配。写一个接收字符串的函数。
(二)“小试牛刀”——单字符发收
1.中断模式介绍
● 由于博主已经详细介绍过中断模式了,在这里就不进行赘述,请参考博主:/qq_52199251/article/details/127453957
2.软件配置
2.1 STM32cubeMX
●STM32CubeMX
是被广泛使用的。它集成了芯片选型、引脚分配和功能配置,中间件配置,时钟配置,初始代码和项目的功能。其中STM32CubeMX
和STM32Cubeprogrammer
,除了对所有STM32芯片系列,和所有应用的通用支持之外,还有一些对特定应用的支持,比如STM32Cube.AI就是基于STM32CubeMX的插件功能,来把训练好的模型部署到STM32上;还比如在安全固件升级和安全固件安装,即SBSFU和SFI操作里,STM32CubeProgrammer
就启动了代码加密,HSM实例化等功能。STM32支持丰富的开源和ST自主知识产权中间件,比如来自开源社区的FreeRTOS,FatFS,mbedTLS;ST自己的USB主机和设备协议栈,TouchGFX等。
关于STM32CubeMX介绍及安装参考博主:/qq_44629109/article/details/126299438
2.2 Keil
●keil安装
链接:/s/1ttrDhv6kXgAvPiYINf9iGw
提取码:1234
通过以上链接下载mdk和注册器,点击安装mdk,根据提示自行更改软件路径和支持包路径,填写完注册信息后NEXT,等待安装。安装完成,点击Finish。
●注册
链接:/s/1T11pBKpD6xc-cNmXBskcaw
提取码:1234
●支持包安装
链接:/s/1a7UDSVeLC4ktHNN9lV9oIA
提取码:1234
点击运行下载的支持包,NEXT开始安装,安装完成,点击Finish。
3.串口助手
● 可在CSDN上或官网下载对应的串口小助手。
3.工程新创
● 点击ACCESS TO MCU SELECTOR
● 选择STMF103C8T6芯片。
4.设置RCC
● 可以发现此时芯片部分引脚高亮。
5.设置SYS
● 发现P14、P13
引脚高亮。
6.设置USART
● 发现P10、P9
引脚高亮。
7.设置NVIC
● 点击USART1 global interrupt
。
8.生成项目
(三)代码编译与收发实现
1.在KEIL中进行代码编写
● 点击在main函数前定义全局变量
。
char c;//指令 s:停止 t:开始char message[]="hello Windows\n";//输出信息char tips[]="CommandError\n";//提示1char tips1[]="Start.....\n";//提示2char tips2[]="Stop......\n";//提示3int flag=0;//标志 s:停止发送 t:开始发送
● 在main函数中设置接收中断
。
● 函数原型:
HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
● 其函数的功能
功能:串口中断接收,以中断方式接收指定长度数据。
大致过程是,设置数据存放位置,接收数据长度,然后使能串口接收中断。
接收到数据时,会触发串口中断。
再然后,串口中断函数处理,直到接收到指定长度数据
而后关闭中断,进入中断接收回调函数,不再触发接收中断。(只触发一次中断)
● 参数说明:
UART_HandleTypeDef *huart UATR的别名
huart1 *pData 接收到的数据存放地址
Size 接收的字节数
HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1);
2.main函数中的while循环里面添加传输代码
if(flag==1){//发送信息HAL_UART_Transmit(&huart1, (uint8_t *)&message, strlen(message),0xFFFF); //延时HAL_Delay(1000);}
3.在main函数下面重写中断处理函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){//当输入的指令为s时,发送提示并改变flagif(c=='s'){flag=0;HAL_UART_Transmit(&huart1, (uint8_t *)&tips2, strlen(tips2),0xFFFF); }//当输入的指令为t时,发送提示并改变flagelse if(c=='t'){flag=1;HAL_UART_Transmit(&huart1, (uint8_t *)&tips1, strlen(tips1),0xFFFF); }//当输入不存在指令时,发送提示并改变flagelse {flag=0;HAL_UART_Transmit(&huart1, (uint8_t *)&tips, strlen(tips),0xFFFF); }//重新设置中断HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1); }
4.代码汇总
#include "main.h"#include "usart.h"#include "gpio.h"#include <string.h>void SystemClock_Config(void);char c;//指令 s:停止 t:开始char message[]="hello Windows\n";//输出信息char tips[]="CommandError\n";//提示1char tips1[]="Start.....\n";//提示2char tips2[]="Stop......\n";//提示3int flag=0;//标志 s:停止发送 t:开始发送int main(void){HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();//设置接受中断HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1);//当flag为1时,每秒发送一次信息//当flag为0时,停止while (1){if(flag==1){//发送信息HAL_UART_Transmit(&huart1, (uint8_t *)&message, strlen(message),0xFFFF); //延时HAL_Delay(1000);}}}void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){//当输入的指令为s时,发送提示并改变flagif(c=='s'){flag=0;HAL_UART_Transmit(&huart1, (uint8_t *)&tips2, strlen(tips2),0xFFFF); }//当输入的指令为t时,发送提示并改变flagelse if(c=='t'){flag=1;HAL_UART_Transmit(&huart1, (uint8_t *)&tips1, strlen(tips1),0xFFFF); }//当输入不存在指令时,发送提示并改变flagelse {flag=0;HAL_UART_Transmit(&huart1, (uint8_t *)&tips, strlen(tips),0xFFFF); }//重新设置中断HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1); }/* USER CODE END 4 *//*** @brief System Clock Configuration* @retval None*/void SystemClock_Config(void){RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK){Error_Handler();}}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief This function is executed in case of error occurrence.* @retval None*/void Error_Handler(void){/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */}
发现没有报错。
5.打开串口助手
实现效果如下:
视频
(四)“大刀阔斧”——字符串发收
1.新建工程
● 生成工程的过程如上:
2.代码编写
● main.c文件代码如下:
/* USER CODE BEGIN Header *//********************************************************************************* @file : main.c* @brief: Main program body******************************************************************************* @attention** Copyright (c) STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************//* USER CODE END Header *//* Includes ------------------------------------------------------------------*/#include "main.h"#include "usart.h"#include "gpio.h"#include "stdio.h"#include "string.h"/* Private includes ----------------------------------------------------------*//* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*//* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*//* USER CODE BEGIN PD */uint8_t aRxBuffer;//½ÓÊÕÖжϻº³åuint8_t Uart1_RxBuff[256];//½ÓÊÕ»º³åuint8_t str1[20] = "stop stm32";uint8_t str2[20] = "go stm32";uint8_t Uart1_Rx_Cnt = 0;//½ÓÊÕ»º³å¼ÆÊýuint8_tcAlmStr[] = "Êý¾ÝÒç³ö(´óÓÚ256)\r\n";unsigned int flag = 1;/* USER CODE END PD *//* Private macro -------------------------------------------------------------*//* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/void SystemClock_Config(void);/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*//* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief The application entry point.* @retval int*/int main(void){/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */if(flag == 1){printf("ppm Hello windows!\r\n");}else{//printf("stop stm32 NO!\r\n");}HAL_Delay(500);}/* USER CODE END 3 */}/*** @brief System Clock Configuration* @retval None*/void SystemClock_Config(void){RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}}/* USER CODE BEGIN 4 *//* USER CODE BEGIN 4 *//*** @brief Rx Transfer completed callbacks.* @param huart pointer to a UART_HandleTypeDef structure that contains*the configuration information for the specified UART module.* @retval None*/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 (strcmp(Uart1_RxBuff, str1) == 0) flag = 0;if (strcmp(Uart1_RxBuff, str2) == 0) flag = 1;//if(Uart1_RxBuff[0]=='g') flag = 1;//if(Uart1_RxBuff[0]=='s') flag = 0;if(Uart1_Rx_Cnt >= 255) //Òç³öÅжÏ{Uart1_Rx_Cnt = 0;memset(Uart1_RxBuff,0x00,sizeof(Uart1_RxBuff));HAL_UART_Transmit(&huart1, (uint8_t *)&cAlmStr, sizeof(cAlmStr),0xFFFF);}else{Uart1_RxBuff[Uart1_Rx_Cnt++] = aRxBuffer; //½ÓÊÕÊý¾Ýת´æif((Uart1_RxBuff[Uart1_Rx_Cnt-1] == 0x0A)&&(Uart1_RxBuff[Uart1_Rx_Cnt-2] == 0x0D)) //ÅжϽáÊøλ{HAL_UART_Transmit(&huart1, (uint8_t *)&Uart1_RxBuff, Uart1_Rx_Cnt,0xFFFF); //½«ÊÕµ½µÄÐÅÏ¢·¢ËͳöÈ¥Uart1_Rx_Cnt = 0;memset(Uart1_RxBuff,0x00,sizeof(Uart1_RxBuff)); //Çå¿ÕÊý×é}}HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1); //ÔÙ¿ªÆô½ÓÊÕÖжÏ}/* USER CODE END 4 *//* USER CODE END 4 *//*** @brief This function is executed in case of error occurrence.* @retval None*/void Error_Handler(void){/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */}#ifdef USE_FULL_ASSERT/*** @brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* @param file: pointer to the source file name* @param line: assert_param error line source number* @retval None*/void assert_failed(uint8_t *file, uint32_t line){/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */}#endif /* USE_FULL_ASSERT */
● 发现无报错
3.烧录打开串口助手
●打开串口助手,实现效果如下:
视频
(五)总结
本文介绍了如何在嵌入式系中通过STM32F103C8T6接收到字符“s”时,停止持续发送“hello windows!”; 当接收到字符“t”时,持续发送“hello windows!”;接收到字符“stop stm32!”时,停止持续发送“hello windows!”; 当接收到字符“go stm32!”时,持续发送“hello windows!”。在转GIF动图的过程中,遇到了一些困难,但耐心细心还是做了下去。
寄语:戒骄戒躁
从容面对
没有任何能伤害你,伤害你的只有你自己。
所以热爱生活,爱惜自己,便可抵挡岁月漫长!
(六)参考文献
[1]/qq_53112972/article/details/127450778
如果觉得《【嵌入式系统开发13】采用串口中断方式完成单字符接受与字符串接受》对你有帮助,请点赞、收藏,并留下你的观点哦!