STM32 串口通信发送与接收信息
通过以上步骤和代码示例,我们可以实现 STM32 的串口通信发送与接收信息功能。在实际应用中,还可以根据具体需求对代码进行扩展,如使用中断方式进行数据接收,以提高系统的实时性;或者实现更复杂的数据处理逻辑,以满足不同的应用场景。掌握 STM32 串口通信技术,对于嵌入式系统开发具有重要的意义。
✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进
❤欢迎关注我的知乎:对error视而不见
代码获取、问题探讨及文章转载可私信。
☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。
🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!👇
一、引言
在嵌入式系统开发中,串口通信是一种常见且重要的通信方式。STM32 系列微控制器凭借其高性能、低功耗等特点,被广泛应用于各种领域。利用 STM32 的串口通信功能,可以实现与其他设备的数据交互,如传感器数据采集、与上位机通信等。本文将详细介绍 STM32 串口通信的原理、硬件连接、软件配置,并给出具体的代码示例,帮助读者掌握 STM32 串口通信的发送与接收信息功能。
二、串口通信原理
串口通信(Serial Communication)是指数据一位一位地按顺序传输,其特点是通信线路简单,只要一对传输线就可以实现双向通信,从而大大降低了成本,特别适用于远距离通信,但传输速度较慢。
在异步串口通信中,数据以帧为单位进行传输,每帧包含起始位、数据位、奇偶校验位(可选)和停止位。起始位通常为低电平,用于标志一帧数据的开始;数据位可以是 5、6、7 或 8 位,用于传输实际的数据;奇偶校验位用于检测数据传输过程中是否发生错误;停止位通常为高电平,用于标志一帧数据的结束。
三、硬件连接
以 STM32F103C8T6 为例,其 USART1 的 TX 引脚为 PA9,RX 引脚为 PA10。在进行串口通信时,需要将 STM32 的 TX 引脚连接到外部设备的 RX 引脚,将 STM32 的 RX 引脚连接到外部设备的 TX 引脚,同时要确保两者的地(GND)连接在一起,以提供统一的参考电位。
此外,为了实现与计算机的通信,还需要一个 USB 转串口模块,如 CH340 或 CP2102,将串口信号转换为 USB 信号,以便计算机能够识别。
四、软件配置
在进行软件配置之前,需要使用 STM32CubeMX 工具进行初始化配置。以下是具体的配置步骤:
- 创建新项目:选择合适的 STM32 芯片型号,如 STM32F103C8T6。
- 配置 RCC:选择外部晶振作为时钟源,配置系统时钟。一般将系统时钟设置为 72MHz。
- 配置 USART:选择要使用的串口,如 USART1,将模式设置为异步通信(Asynchronous),波特率设置为 115200,数据位为 8 位,停止位为 1 位,无校验位。
- 配置 GPIO:STM32CubeMX 会自动将与串口相关的 GPIO 引脚(PA9 和 PA10)配置为复用推挽输出(TX)和浮空输入(RX)。
- 生成代码:选择 Keil MDK 作为开发环境,生成代码。
五、代码实现
以下是一个完整的 STM32 串口通信发送与接收信息的代码示例:
#include "main.h"
#include "stm32f1xx_hal.h"
UART_HandleTypeDef huart1;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
char send_data[] = "Hello, STM32 Serial Communication!\r\n";
char receive_data[20];
while (1)
{
// 发送数据
HAL_UART_Transmit(&huart1, (uint8_t *)send_data, sizeof(send_data), 1000);
// 接收数据
HAL_UART_Receive(&huart1, (uint8_t *)receive_data, sizeof(receive_data), 1000);
// 处理接收到的数据
if (receive_data[0] != '\0') {
// 这里可以添加对接收到数据的处理逻辑
HAL_UART_Transmit(&huart1, (uint8_t *)receive_data, sizeof(receive_data), 1000);
}
HAL_Delay(1000);
}
}
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();
}
}
static void MX_USART1_UART_Init(void)
{
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();
}
}
static void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
}
void Error_Handler(void)
{
while(1)
{
}
}
六、代码解释
-
初始化部分
HAL_Init():初始化 HAL 库,为后续的硬件操作提供基础。SystemClock_Config():配置系统时钟,确保芯片以正确的时钟频率运行。MX_GPIO_Init():初始化 GPIO 引脚,将与串口相关的引脚配置为合适的模式。MX_USART1_UART_Init():初始化 USART1 串口,设置波特率、数据位、停止位等参数。
-
数据发送
HAL_UART_Transmit(&huart1, (uint8_t *)send_data, sizeof(send_data), 1000);:使用 HAL 库提供的函数将send_data数组中的数据发送出去。&huart1是串口句柄,(uint8_t *)send_data是要发送的数据指针,sizeof(send_data)是数据的长度,1000是超时时间(单位:毫秒)。
-
数据接收
HAL_UART_Receive(&huart1, (uint8_t *)receive_data, sizeof(receive_data), 1000);:使用 HAL 库提供的函数接收数据,并将其存储在receive_data数组中。
-
数据处理
if (receive_data[0] != '\0'):判断是否接收到了数据。如果接收到了数据,则可以在这个条件语句中添加具体的处理逻辑。这里只是简单地将接收到的数据再次发送出去。
七、注意事项
- 波特率匹配:STM32 的串口波特率必须与外部设备的波特率一致,否则会导致数据传输错误。
- 数据长度:在接收数据时,要确保接收缓冲区的大小足够大,避免数据溢出。
- 超时时间:
HAL_UART_Transmit和HAL_UART_Receive函数中的超时时间需要根据实际情况进行调整,避免因等待时间过长或过短而影响通信效果。
八、总结
通过以上步骤和代码示例,我们可以实现 STM32 的串口通信发送与接收信息功能。在实际应用中,还可以根据具体需求对代码进行扩展,如使用中断方式进行数据接收,以提高系统的实时性;或者实现更复杂的数据处理逻辑,以满足不同的应用场景。掌握 STM32 串口通信技术,对于嵌入式系统开发具有重要的意义。
更多推荐



所有评论(0)