单片机串口通讯实战:详解STM32的串口编程与数据传输

news2025/1/18 13:57:25

 

引言: 单片机串口通讯是应用非常广泛的通讯方式,具有简单、灵活、稳定等特点。本文将深入探讨单片机串口通讯的原理、应用和性能优化,同时介绍如何使用STM32单片机进行串口编程,并提供详细的代码示例和注释。

一、单片机串口通讯的原理和工作方式

1.1 串口通讯的基本原理

1.2 串口通讯的工作流程

1.3 串口通讯的通信协议(如RS-232、RS-485等)

二、STM32单片机串口通讯的编程方法

2.1 STM32串口寄存器和配置

2.2 串口初始化和配置

2.3 串口发送和接收数据

三、STM32单片机串口通讯的数据传输

3.1 串口发送数据

3.2 串口接收数据

3.3 数据传输中的常见问题和解决方法

四、STM32单片机串口通讯的性能优化

4.1 波特率的选择与优化

4.2 缓冲区设计与数据流控制

4.3 中断和DMA的应用

五、STM32单片机串口通讯的实例代码和注释

#include "stm32f4xx.h"
#include "stm32f4xx_hal.h"

UART_HandleTypeDef huart2;

void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);

int main(void)
{
  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();
  MX_USART2_UART_Init();
  
  uint8_t dataToSend[20] = "Hello, world!\r\n";
  uint8_t receivedData[20];
  
  while (1)
  {
    HAL_UART_Transmit(&huart2, dataToSend, 20, HAL_MAX_DELAY);
    HAL_UART_Receive(&huart2, receivedData, 20, HAL_MAX_DELAY);
  }
}

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 360;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  if (HAL_PWREx_EnableOverDrive() != HAL_OK)
  {
    Error_Handler();
  }

  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_5) != HAL_OK)
  {
    Error_Handler();
  }
}

static void MX_USART2_UART_Init(void)
{
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
}

static void MX_GPIO_Init(void)
{
  __HAL_RCC_GPIOA_CLK_ENABLE();

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void Error_Handler(void)
{
  while (1)
  {
  }
}

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if (huart->Instance == USART2)
  {
    __HAL_RCC_USART2_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  }
}

代码说明和注释:

  • 代码开头部分包含了必要的头文件和初始化函数的声明。

  • main()函数中,我们进行了单片机的初始化,配置了系统时钟和串口。

  • 在主循环中,我们通过调用HAL_UART_Transmit()HAL_UART_Receive()函数进行串口数据的发送和接收。

  • SystemClock_Config()函数配置了系统时钟,使用的是外部高速晶振。

  • MX_USART2_UART_Init()函数对串口进行初始化,配置波特率、数据位、停止位等参数。

  • MX_GPIO_Init()函数对引脚进行初始化,将引脚设置为复用功能,与串口功能相对应。

  • Error_Handler()函数是错误处理函数,当出现错误时将会进入死循环。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/884706.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

都错了!机械硬盘远比SSD更省电 最多领先94%

相信在绝大多数人的认知中,SSD固态硬盘因为没有HDD机械硬盘那样的移动部件,不但更稳定,还更省电。 但是,存储服务商Scality的研究表明,恰恰相反,HDD更省电。 他们以美光6500 ION 30.72TB QLC SSD、希捷银河…

如何安装Python?

如何安装Python? 安装Python非常简单,让我们一步步来进行。 1. 访问官方网站 首先,您需要访问Python官方网站(https://www.python.org/)。在首页上,您会看到一个大大的「Downloads」按钮,点击…

深信服数据中心管理系统 XXE漏洞复现

0x01 产品简介 深信服数据中心管理系统DC为AC的外置数据中心,主要用于海量日志数据的异地扩展备份管理,多条件组合的高效查询,统计和趋势报表生成,设备运行状态监控等功能。 0x02 漏洞概述 深信服数据中心管理系统DC存在XML外部实…

Python的变量命名规则是什么?

Python的变量命名规则 在Python中,变量是用来存储数据的,而变量命名是为了方便我们理解和引用这些数据。Python的变量命名规则相对灵活,但也有一些基本规则和约定,让我们一起来了解一下。 基本规则 只能包含字母、数字和下划线&…

使用 flatMap 进行扁平化映像处理数据

实战背景 : 小伙伴遇到了数据处理方面的问题如下 : 只能说看到这里我也一头雾水,毕竟我也是菜🐶,那就请教大佬吧 : Map.flat 循环 二维 变 一维 就是 flatMap 了 啊这,,但是 flatM…

[python] 安装numpy+scipy+matlotlib+scikit-learn及问题解决

这篇文章主要讲述Python如何安装Numpy、Scipy、Matlotlib、Scikit-learn等库的过程及遇到的问题解决方法。最近安装这个真是一把泪啊,各种不兼容问题和报错,希望文章对你有所帮助吧!你可能遇到的问题包括: ImportError: N…

Spring Boot+ redis执行lua脚本的5种方式

Spring Boot redis执行lua脚本示例 文章目录 Spring Boot redis执行lua脚本示例0.前言1.基础介绍2.步骤2.1. 引入依赖1. 使用Jedis作为Redis客户端:2. 使用Lettuce作为Redis客户端: 2.2. 配置文件使用Jedis作为Redis客户端的配置文件(applica…

突破防线!泛微OA任意文件上传Getshell

子曰:“巧言令色,鲜矣仁。” 漏洞复现 访问漏洞url: 存在漏洞的路径为 /weaver/weaver.common.Ctrl/.css?arg0com.cloudstore.api.service.Service_CheckApp&arg1validateApp漏洞利用: 漏洞证明: 文笔生疏&…

2021年12月 C/C++(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题:统计指定范围里的数 给定一个数的序列S,以及一个区间[L, R], 求序列中介于该区间的数的个数,即序列中大于等于L且小于等于R的数的个数。 时间限制:1000 内存限制:65536 输入 第一行1个整数n、,分别表…

Intel 12代酷睿集体大降价!三折太离谱了

之前有德国媒体报道称,Intel 12/13代酷睿以及即将发布的14代酷睿,将会全面涨价。 没想到,12代酷睿大降价了,幅度相当不可思议,不过至少目前仅限美国市场,新蛋、亚马逊、MicroCenter等大型零售商集体行动。 …

C#__匿名方法和Lambda表达式

class Program{static void Main(string[] args){// 匿名方法&#xff1a;方法没有名字Func<int, int, int> plus delegate (int a, int b){return a b;};// 这里相当于直接把要引用的方法直接写在后面// 优点&#xff1a;减少了要编写的代码&#xff0c;减少代码的复杂…

BGP的路由反射器和联邦

1、规划IP及拓扑图 172.16.0.0/16 借到24位 可用范围网段&#xff1a;0-31 172.16.0.0/24 要分6个网段IP借3位 172.16.0.0/27 172.16.0.32/27 172.16.0.64/27 172.16.0.96/27 172.16.0.128/27 172.16.0.160/27 作为骨干网段 172.16.1.0/24 6个建邻环回…

生信豆芽菜-相关性散点图

网址&#xff1a;http://www.sxdyc.com/panCancerScatterDiagram 1、数据准备 第一个文件&#xff1a;相关性分析结果 2、选择想要显示的肿瘤的名称&#xff0c;如果是多个&#xff0c;就用逗号隔开&#xff08;这里的逗号为英文字符下的逗号&#xff09; 3、结果 当然&…

Lie group 专题:Lie 群

Lie group 专题&#xff1a;Lie 群 流形 流形的定义 一个m维流形是满足以下条件的集合M&#xff1a;存在可数多个称为坐标卡&#xff08;图集&#xff09;的子集合族.以及映到的连通开子集上的一对一映射&#xff0c;,称为局部坐标映射&#xff0c;满足以下条件 坐标卡覆盖M…

Program Evaluation and Review Technique(PERT)

Program Evaluation and Review Technique&#xff08;PERT&#xff09;计划评估和审查技术 大多数的时候&#xff0c;我不太记得概念&#xff0c;大致是这么回事&#xff0c;为了方便记忆&#xff0c;从小到大 1)beta distribution 贝塔分布&#xff08;成本&#xff0c;也可以…

C++11并发与多线程笔记(2)线程启动、结束,创建线程多法、join,detach

C11并发与多线程笔记&#xff08;2&#xff09; 线程启动、结束&#xff0c;创建线程多法、join&#xff0c;detach 1. 范例演示线程运行的开始1.1 创建一个线程&#xff1a;1.2 join1.3 datch1.4 joinable 2. 其他创建线程的方法2.1 用类 重载了函数调用运算符2.2 lambda表达式…

行业常识_Modbus

文章目录 1 Modbus1.1 Modbus是啥1.2 应用1.3 协议变体及区别1.3.1 物理层1.3.2 帧结构1.3.3 传输速率1.3.4 连接方式1.3.5 网络依赖性1.3.5 安全性 1.4 传输方式1.4.1 协议数据单元 1.5 Modbus协议数据模型1.6 Modbus地址模式 1 Modbus 1.1 Modbus是啥 Modbus是一种协议。 其…

AUTOSAR规范与ECU软件开发(实践篇)3.2 ETAS AUTOSAR系统解决方案介绍(上)

1、ETAS AUTOSAR系统解决方案介绍 博世集团ETAS公司基于其强大的研发实力为用户提供了一套高效、 可靠的AUTOSAR系统解决方案&#xff0c; 该方案覆盖了软件架构设计、 应用层模型设计、 基础软件开发、 软件虚拟验证等各个方面&#xff0c; 如图3.5所示&#xff0c; 其中深色…

什么是接口测试,如何做接口测试?

比起点点点的功能测试&#xff0c;“接口测试”显得专业又高大上&#xff0c;也因此让有些初级测试人员“望而生畏”。别担心&#xff0c;其实接口测试也是功能测试的一种&#xff0c;它是针对接口进行的功能测试。 写在前面&#xff1a;本文参考了茹炳晟老师的《测试工程师 全…

四张图片道清AI大模型的发展史(1943-2023)

四张图片道清AI大模型的发展史(1943-2023) 现在最火的莫过于GPT了&#xff0c;也就是大规模语言模型(LLM)。“LLM” 是 “Large Language Model”&#xff08;大语言模型&#xff09;的简称&#xff0c;通常用来指代具有巨大规模参数和复杂架构的自然语言处理模型&#xff0c;…