使用UART和USART在STM32上进行双向通信

在本文中,我们将深入了解如何在STM32上使用UART(通用异步收发传输器)和USART(通用同步异步收发传输器)实现双向通信。UART和USART是常见的串口通信协议,通常用于与其他设备进行数据传输。我们将重点介绍如何配置UART和USART外设,以及如何在STM32中实现双向通信。

首先,我们需要选择适当的引脚,并在STM32的引脚配置中进行设置。假设我们选择了UART1和USART1,并将它们连接到两个不同的外部设备。下面是配置引脚的代码示例:

```c
// 引脚配置
GPIO_InitTypeDef GPIO_InitStruct = {0};// 使能GPIO时钟
__HAL_RCC_GPIOA_CLK_ENABLE();// 配置UART引脚
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);// 配置USART引脚
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_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_UART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
```

在上述代码中,我们启用了GPIOA的时钟,并将引脚9和引脚10设置为UART1的引脚。我们将引脚2和引脚3设置为USART1的引脚。这些引脚配置具体取决于你所选择的UART和USART外设以及引脚的可用性。

接下来,我们需要配置UART和USART外设,以使它们可以进行数据传输。我们分别配置UART1和USART1的示例代码如下:

```c
// UART配置
UART_HandleTypeDef huart1 = {0};// 使能UART时钟
__HAL_RCC_USART1_CLK_ENABLE();// 配置UART
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
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();
}// USART配置
USART_HandleTypeDef husart1 = {0};// 使能USART时钟
__HAL_RCC_USART1_CLK_ENABLE();// 配置USART
husart1.Instance = USART1;
husart1.Init.BaudRate = 115200;
husart1.Init.WordLength = USART_WORDLENGTH_8B;
husart1.Init.StopBits = USART_STOPBITS_1;
husart1.Init.Parity = USART_PARITY_NONE;
husart1.Init.Mode = USART_MODE_TX_RX;
husart1.Init.CLKPolarity = USART_POLARITY_LOW;
husart1.Init.CLKPhase = USART_PHASE_1EDGE;
husart1.Init.CLKLastBit = USART_LASTBIT_DISABLE;if (HAL_USART_Init(&husart1) != HAL_OK)
{// 初始化错误处理Error_Handler();
}
```

在上述代码中,我们先分别启用了UART1和USART1的时钟。然后,我们对它们进行了相应的配置。对于UART1,我们设置了波特率为9600,字长为8位,停止位为1,无奇偶校验。我们使能了发送和接收模式,同时禁用了硬件流控制。对于USART1,我们设置了波特率为115200,字长为8位,停止位为1,无奇偶校验。我们使能了发送和接收模式,设置了时钟极性和时钟相位,同时禁用了最后一位时钟。

现在,我们已经成功配置了UART和USART的引脚和外设参数。我们可以使用HAL库提供的函数来发送和接收数据。下面是通过UART和USART进行数据传输的代码示例:

```c
// UART发送数据
uint8_t uart_data_to_send[10] = "Hello UART!";
HAL_UART_Transmit(&huart1, uart_data_to_send, 11, HAL_MAX_DELAY);// UART接收数据
uint8_t uart_data_received[10];
HAL_UART_Receive(&huart1, uart_data_received, 10, HAL_MAX_DELAY);// USART发送数据
uint8_t usart_data_to_send[10] = "Hello USART!";
HAL_USART_Transmit(&husart1, usart_data_to_send, 12, HAL_MAX_DELAY);// USART接收数据
uint8_t usart_data_received[10];
HAL_USART_Receive(&husart1, usart_data_received, 10, HAL_MAX_DELAY);
```

在以上代码中,我们通过HAL_UART_Transmit和HAL_UART_Receive函数分别对UART进行发送和接收数据。通过HAL_USART_Transmit和HAL_USART_Receive函数分别对USART进行发送和接收数据。我们通过传递发送缓冲区的指针、数据长度以及最大延迟时间来实现数据的发送和接收。

最后,我们需要处理可能发生的错误。例如,如果在发送或接收期间发生了错误,我们可以使用回调函数来处理它们(与前面的文章中提到的错误回调函数类似)。

以上是使用UART和USART在STM32上进行双向通信的一个简单示例。通过适当的引脚配置和外设参数设置,我们可以轻松实现双向通信,并进行数据的发送和接收。

【代码】:
完整的代码示例如下:

```c
#include "stm32f4xx_hal.h"// 错误处理函数
void Error_Handler(void)
{while (1){// 错误处理}
}// UART错误回调函数
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{if (huart->Instance == USART1){// 处理UART错误Error_Handler();}
}// USART错误回调函数
void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
{if (husart->Instance == USART1){// 处理USART错误Error_Handler();}
}int main(void)
{// 引脚配置GPIO_InitTypeDef GPIO_InitStruct = {0};// 使能GPIO时钟__HAL_RCC_GPIOA_CLK_ENABLE();// 配置UART引脚GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;GPIO_InitStruct.Alternate = GPIO_AF7_USART1;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);// 配置USART引脚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_HIGH;GPIO_InitStruct.Alternate = GPIO_AF7_UART1;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);// UART配置UART_HandleTypeDef huart1 = {0};// 使能UART时钟__HAL_RCC_USART1_CLK_ENABLE();// 配置UARThuart1.Instance = USART1;huart1.Init.BaudRate = 9600;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();}// USART配置USART_HandleTypeDef husart1 = {0};// 使能USART时钟__HAL_RCC_USART1_CLK_ENABLE();// 配置USARThusart1.Instance = USART1;husart1.Init.BaudRate = 115200;husart1.Init.WordLength = USART_WORDLENGTH_8B;husart1.Init.StopBits = USART_STOPBITS_1;husart1.Init.Parity = USART_PARITY_NONE;husart1.Init.Mode = USART_MODE_TX_RX;husart1.Init.CLKPolarity = USART_POLARITY_LOW;husart1.Init.CLKPhase = USART_PHASE_1EDGE;husart1.Init.CLKLastBit = USART_LASTBIT_DISABLE;if (HAL_USART_Init(&husart1) != HAL_OK){// 初始化错误处理Error_Handler();}// UART发送数据uint8_t uart_data_to_send[15] = "Hello UART!";HAL_UART_Transmit(&huart1, uart_data_to_send, strlen(uart_data_to_send), HAL_MAX_DELAY);// UART接收数据uint8_t uart_data_received[15];HAL_UART_Receive(&huart1, uart_data_received, 14, HAL_MAX_DELAY);// USART发送数据uint8_t usart_data_to_send[15] = "Hello USART!";HAL_USART_Transmit(&husart1, usart_data_to_send, strlen(usart_data_to_send), HAL_MAX_DELAY);// USART接收数据uint8_t usart_data_received[15];HAL_USART_Receive(&husart1, usart_data_received, 14, HAL_MAX_DELAY);while (1){// 主循环}
}
```

以上是一个简单的例子,介绍了如何使用UART和USART在STM32上进行双向通信。你可以根据实际需求进行修改和扩展。

 嵌入式物联网的学习之路非常漫长,不少人因为学习路线不对或者学习内容不够专业而错失高薪offer。不过别担心,我为大家整理了一份150多G的学习资源,基本上涵盖了嵌入式物联网学习的所有内容。点击这里,0元领取学习资源,让你的学习之路更加顺畅!记得点赞、关注、收藏、转发哦。 

​ 点击链接扫码进入嵌入式交流群 ​https://fss.mpay8.cn/article/dmrjinh2C6fjejm

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】STL简介(了解)【STL的概念,STL的历史缘由,STL六大组件、STL的重要性、以及如何学习STL、STL的缺陷的讲解】

这里写自定义目录标题 一、什么是STL二、STL的版本1. 原始版本2. P. J. 版本3. RW版本★ 4. SGI版本 三、STL的六大组件四、STL的重要性五、如何学习STL六、STL的缺陷 一、什么是STL STL ( standard template libaray - 标准模板库 ):是C标准库 的重要组成部分&…

YoloV5改进策略:Swift Parameter-free Attention,无参注意力机制,超分模型的完美迁移

摘要 https://arxiv.org/pdf/2311.12770.pdf https://github.com/hongyuanyu/SPAN SPAN是一种超分网络模型。SPAN模型通过使用参数自由的注意力机制来提高SISR的性能。这种注意力机制能够增强重要信息并减少冗余,从而在图像超分辨率过程中提高图像质量。 具体来说,SPAN模…

HOST文件被挟持,无法上网,如何解决。

问题: 晚上开机,突然发现无法联网,提示网络异常 解决: 首先网络诊断,host文件被劫持,修复后,仍然不行。 然后测试手机热点,发现仍然无法联网 尝试用火绒修复,无果。 所有…

算法通关村第十六关-黄金挑战滑动窗口与堆的结合

大家好我是苏麟 , 今天带来一道小题 . 滑动窗口最大值 描述 : 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 题目 : …

通讯录管理系统(基于C语言)

模块设计 本通讯录管理系统功能模块共包括9个部分:1.输入数据、2.显示数据、 3.插入数据、4.删除数据、5.查看数据、6.修改数据、7.保存数据、 8.返回主菜单、9.退出系统. 一.总体设计 通讯录的每一条信息包括:姓名、性别、住址、联系电话…

VirtualBox安装Centos7.9

目录 1、下载Centos7.9镜像 2、新建虚拟电脑 3、虚拟电脑配置 3.1、配置CPU 3.2、设置启动顺序(光驱放在第一个) 3.3、设置存储 3.4、设置网络(桥接网卡) 4、启动 启动 等待 选择安装过程中语言 安装位置 开始安装 设置root账号密码 重启 输入用户名和密码登录…

[英语学习][7][Word Power Made Easy]的精读与翻译优化

[序言] 这次翻译, 遇到非常细微的短语, 让我差点翻车. 我从7点半开始思考到10点, 才恍然大悟. [英文学习的目标] 提升自身的英语水平, 对日后编程技能的提升有很大帮助. 希望大家这次能学到东西, 同时加入我的社区讨论与交流英语相关的内容. [原著英文与翻译版对照][第19] …

【模电】直流通路与交流通路

直流通路与交流通路 通常,在放大电路中,直流电源的作用和交流信号的作用总是共存的,即静态电流、电压和动态电流、电压总是共存的。但是由于电容、电感等电抗元件的存在,直流量所流经的通路与交流信号所流经的通路不完全相同。因此…

项目实战之RabbitMQ死信队列应用

🧑‍💻作者名称:DaenCode 🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。 😎人生感悟:尝尽人生百味,方知世间冷暖。 文章目录 🌟架构图&#x…

Java 基础学习(五)面向对象编程-对象和类

1 类和对象 1.1 面向对象概述 1.1.1面向对象简史 面向对象编程思想最初的起源可以追溯到1960年的Simula语言,这被认为是第一个支持面向对象编程概念的语言。Simula引入了类、对象、继承等概念,将数据和操作进行封装。Simula的创始人奥利-约翰达尔&…

【unity3D】创建游戏物体的三种方式

💗 未来的游戏开发程序媛,现在的努力学习菜鸡 💦本专栏是我关于游戏开发的学习笔记 🈶本篇是在unity中创建游戏物体的三种方式 unity中创建游戏物体 使用构造函数创建一个空的游戏对象根据现有的预制体资源或者场景中已有的物体进…

如何基于Akamai IoT边缘平台打造一个无服务器的位置分享应用

与地理位置有关的应用相信大家都很熟悉了,无论是IM软件里的位置共享或是电商、外卖应用中的配送地址匹配,我们几乎每天都在使用类似的功能与服务。不过你有没有想过,如何在自己开发的应用中嵌入类似的功能? 本文Akamai将为大家提…