糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > 【嵌入式系统开发13】采用串口中断方式完成单字符接受与字符串接受

【嵌入式系统开发13】采用串口中断方式完成单字符接受与字符串接受

时间:2019-05-13 09:18:15

相关推荐

【嵌入式系统开发13】采用串口中断方式完成单字符接受与字符串接受

本文目的是主要介绍通过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是被广泛使用的。它集成了芯片选型、引脚分配和功能配置,中间件配置,时钟配置,初始代码和项目的功能。其中STM32CubeMXSTM32Cubeprogrammer,除了对所有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】采用串口中断方式完成单字符接受与字符串接受》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。