STM32 串口通讯

2024-06-20 22:04
文章标签 串口 stm32 通讯

本文主要是介绍STM32 串口通讯,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

使用STM32的串口通讯,接收串口助手的数据,并且将接收到的数据返回串口,重定义printf功能。

配置引脚信息

由于每次新建工程都需要配置信息,比较麻烦,好在STM32CubeIDE提供了导入.ioc文件的功能,可以帮我们节省时间。

1.从BEEP的项目里导入ioc文件,并命名为Serial。

将串口1的mode修改为Asynchronous同步通讯,波特率为115200,数据宽度:8位,检验:None,停止位:1位。

image-20220309173020409

2.添加DMA发送通道

image-20220309174341557

3.打开串口1中断设置。

image-20220309174427994

核心代码解释

1.在BSP中新建蜂鸣器的驱动库bsp_uart.h和bsp_uart.c文件。在bsp_uart.h中增加以下内容:

/** bsp_uart.h**  Created on: Mar 4, 2022*      Author: Administrator*/#ifndef BSP_UART_H_
#define BSP_UART_H_#include "stdint.h"void USART1_Init(void);
void USART1_Send_U8(uint8_t ch);
void USART1_Send_ArrayU8(uint8_t *BufferPtr, uint16_t Length);#endif /* BSP_UART_H_ */

2.在bsp_uart.c中添加以下内容:

/** bsp_uart.c**  Created on: Mar 4, 2022*      Author: Administrator*/#include "bsp_uart.h"
#include "bsp.h"#define ENABLE_UART_DMA    1uint8_t RxTemp = 0;// Initialize USART1  初始化串口1
void USART1_Init(void)
{HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxTemp, 1);
}// The serial port sends one byte  串口发送一个字节
void USART1_Send_U8(uint8_t ch)
{HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
}// The serial port sends a string of data  串口发送一串数据
void USART1_Send_ArrayU8(uint8_t *BufferPtr, uint16_t Length)
{#if ENABLE_UART_DMAHAL_UART_Transmit_DMA(&huart1, BufferPtr, Length);#elsewhile (Length--){USART1_Send_U8(*BufferPtr);BufferPtr++;}#endif
}// The serial port receiving is interrupted. Procedure  串口接收完成中断
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_RxCpltCallback can be implemented in the user file*/// 测试发送数据,实际应用中不应该在中断中发送数据// Test sending data. In practice, data should not be sent during interrupts  USART1_Send_U8(RxTemp);// Continue receiving data  继续接收数据HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxTemp, 1);
}#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
PUTCHAR_PROTOTYPE
{/* Place your implementation of fputc here *//* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);return ch;
}

USART1_Init():初始化串口相关内容,开启串口接收1个数据。

image-20220309183608315

USART1_Send_U8(ch):串口1发送一个字节。

image-20220309183632327

USART1_Send_ArrayU8(BufferPtr,Length):串口1发送一串数据,BufferPtr是数据的首地址,Length是数据的长度。ENABLE_UART_DMA是串口1 DMA的开关。

image-20220309183656718

3.由于串口1接收中断只进行一次,所以接收数据后需要再次调用接收数据。这里为了方便测试,所以在中断调用串口发送数据,实际应用中不应该在中断中发送数据,串口发送数据比较耗时,可能导致丢包甚至串口出错等问题。

image-20220309183851258

4.重新定义printf使用串口1发送数据。

image-20220309184205569

5.在BSP初始化中,调用USART1_Init()函数,请求接收数据。

image-20220310092311388

//bsp.c
#include "bsp.h"// LED显示当前运行状态,每10毫秒调用一次,LED灯每200毫秒闪烁一次。
// The LED displays the current operating status, which is invoked every 10 milliseconds, and the LED blinks every 200 milliseconds.  
static void Bsp_Led_Show_State_Handle(void)
{static uint8_t led_count = 0;led_count++;if (led_count > 20){led_count = 0;LED_TOGGLE();}
}// The peripheral device is initialized  外设设备初始化
void Bsp_Init(void)
{Beep_On_Time(50);USART1_Init();
}// main.c中循环调用此函数,避免多次修改main.c文件。
// This function is called in a loop in main.c to avoid multiple modifications to the main.c file
void Bsp_Loop(void)
{// Detect button down events   检测按键按下事件if (Key1_State(KEY_MODE_ONE_TIME)){Beep_On_Time(50);static int press = 0;press++;printf("press:%d\n", press);}Bsp_Led_Show_State_Handle();// The buzzer automatically shuts down when times out   蜂鸣器超时自动关闭Beep_Timeout_Close_Handle();HAL_Delay(10);
}

 

6.在按键按下后,增加printf()函数,通过串口1打印信息。

image-20220310092529061

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2022 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 "dma.h"
#include "usart.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "bsp.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* 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_DMA_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */Bsp_Init();/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){Bsp_Loop();/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* 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 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 */

实验效果

烧录程序后,LED灯每隔200毫秒闪一次,将扩展板通过micro-USB数据线与电脑连接后并打开串口助手(具体参数如下图所示),每按一次按键,蜂鸣器都会响50毫秒,可以看到串口助手会显示press:xx,每按一次按键xx自动加1。串口助手发送字符a,扩展板会自动将字符a返回。由于上面使用在中断中发送数据,所以不能一次发送太多个字符,否则会出现字符丢失甚至串口错误。

image-20220310094043392

 

这篇关于STM32 串口通讯的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1079378

相关文章

零基础STM32单片机编程入门(一)初识STM32单片机

文章目录 一.概要二.单片机型号命名规则三.STM32F103系统架构四.STM32F103C8T6单片机启动流程五.STM32F103C8T6单片机主要外设资源六.编程过程中芯片数据手册的作用1.单片机外设资源情况2.STM32单片机内部框图3.STM32单片机管脚图4.STM32单片机每个管脚可配功能5.单片机功耗数据6.FALSH编程时间,擦写次数7.I/O高低电平电压表格8.外设接口

407串口01发送

实验一: 工程。 链接:https://pan.baidu.com/s/1g8DV4yZWOix0BbcZ08LYDQ?pwd=2176 提取码:2176 串口1的使用。发送功能。 单片机发送信息到电脑。 通过串口进行通信。 首先单片机这边。 单片机这边,需要对单片机的串口模块进行使能初始化,设置串口的格式。 单片机和电脑的串口收发格式要配置一致。不然A和B肯定通信不成功,鸡和鸭讲,

STM32单片机PWR电源控制详解

文章目录 1. PWR概述 2. 电源结构框图 3. 上电复位和掉电复位 4. 可编程电压监测器 5. 低功耗模式 6. 模式选择 6.1 睡眠模式 6.2 停止模式 6.3 待机模式 7. 代码示例 1. PWR概述 PWR(Power Control)电源控制,负责管理STM32内部的电源供电部分,可以实现可编程电压监测器和低功耗模式的功能。 可编程电压监测器

xilinx FPGA 串口设计笔记

xilinx FPGA  串口设计笔记 在设计中,需要用 FPGA 读取 GPS 内部的信息,GPS 的通信方式为串口,所以在 FPGA 中移植了串口程序。 本次移植的程序源代码是特权的串口程序,本以为移植应该很快就能完成, 但其中还是 出了一写小问题,耽误了不少的时间,下面将问题进行一个总结! 以下是串口的时序: 在设计中,耽误时间最长的问题就是数据老是出错,为了找出问题

STM32学习之一:什么是STM32

目录 1.什么是STM32 2.STM32命名规则 3.STM32外设资源 4. STM32的系统架构 5. 从0到1搭建一个STM32工程 学习stm32已经很久了,因为种种原因,也有很久一段时间没接触过stm32了。等我捡起来的时候,发现很多都已经忘记了,重新捡起来吧。 每次谈到stm32如何如何,那么该如何解释什么是stm32呢? 1.什么是STM32 stm32

TX2 关闭console serial使用该串口

由于项目变更,GPU型号从Tx1变成Tx2,原来的硬件接口没有变,但是把原来UART0的console serial功能关闭变成一个串口使用的方法没法使用了。这就导致了数据通过该串口发送的数据变的很有问题,无法使用了。 经过测试,终于找到了解决的方法。 首先在虚拟机上,安装编辑设备树的软件: $sudo apt-get update $sudo apt-get install device

JetSon Tx1 串口使用记录

最近在学习使用Jetson Tx1,下面是使用串口遇到的问题,做为我的第一篇博客。 Jetson Tx1串口是TTL电平。 Jetson Tx1的UART0在Linux上的设备号是“/dev/tty0”,但是在Tx1刷的系统中,UART0默认是做为console serail设备使用的,这个具体有什么作用,我也不大清楚了,百度一下也不是很懂。这就导致了在Linux上使用串口调试工具和PC机相连

STM32学习 修改系统主频

前面时钟树的学习说明单片机的主频是可以修改的,那么怎么更改系统的主频,这里做一个简单的介绍。首先要明白,单片机的程序是如何运行,这里简单说明一下。 对应的代码在startup_stm32....文件里面,这里是复位程序的汇编代码。 复位子程序是系统上电后第一个执行的程序,调用 SystemInit 函数初始化系统时钟,然后调用 C 库函数 _mian,最终调用 main 函数去到 C

使用J-Link Commander查找STM32死机问题

接口:PA13,PA14,请勿连接复位引脚。 输入usb命令 这里我已经连接过了STM32F407VET6了。 再输入connect命令 这里我已经默认选择了SWD接口,4000K速率。 可以输入speed 4000命令选择4000K速率: 写一段崩溃代码进行测试: void CashCode(void){*((volatile uint32_t*) 0x080FFFFF)

谁说串口通信波特率越高越好?

在电子世界里,串口通信就像是电子设备之间的“悄悄话”,它们通过串行数据传输来交换信息。但你知道吗?串口通信的波特率并不是越高越好,这事儿得好好聊聊。 1.什么是串口通信? 串口通信,就像它的名字一样,是一种串行的数据传输方式。它允许设备通过一根线(或几根线)来传递信息。想象一下,你通过一根绳子传递小纸条给朋友,这就是串口通信的基本概念。 2.串口通信波特率是什么?