一、介绍

通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。USART利用分数波特率发生器提供宽范围的波特率选择。它支持同步单向通信和半双工单线通信,也支持LIN(局部互连网),智能卡协议和IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。使用多缓冲器配置的DMA方式,可以实现高速数据通信。

二、硬件连接

  1. 串口之间的接线方式

  2. TTL与RS232的电平标准

  3. STM32 USART框图

三、通信协议

  1. 数据包

    串口通讯的数据包由发送设备通过自身的TXD接口传输到接收设备得RXD接口,在协议层中规定了数据包的内容,具体包括起始位、主体数据(8位或9位)、校验位以及停止位,通讯的双方必须将数据包的格式约定一致才能正常收发数据。

  2. 波特率

    由于异步通信中没有时钟信号,所以接收双方要约定好波特率,常见的波特率有4800、9600、115200等。

  3. 起始和停止信号

    数据包的首尾分别是起始位和停止位,数据包的起始信号由一个逻辑0的数据位表示,停止位信号可由0.5、1、1.5、2个逻辑1的数据位表示,双方需约定一致。

  4. 有效数据

    有效数据规定了主题数据的长度,一般为8或9位。

  5. 数据校验

    在有效数据之后,有一个可选的数据校验位。由于数据通信相对更容易受到外部干扰导致传输数据出现偏差,可以在传输过程加上校验位来解决这个问题。校验方法有奇校验(odd)、偶校验(even)、 0 校验(space)、 1 校验(mark)以及无(noparity)。

4、STM32 USART的寄存器

  1. STM32 USART的配置的寄存器,库函数中的结构体积是基于寄存器进行封装的,还没学会怎么看寄存器的小伙伴可以看我之前的笔记
寄存器 偏移 复位值 描述
USART_SR 0x00 0x00C0 状态寄存器
USART_DR 0x04 不确定 数据寄存器
USART_BRR 0x08 0x0000 波特比率寄存器
USART_CR1 0x0C 0x0000 控制寄存器1
USART_CR2 0x10 0x0000 控制寄存器2
USART_CR3 0x14 0x0000 控制寄存器3
USART_GTPR 0x18 0x0000 保护时间和预分频寄存器
  1. 寄存器的地址映象

四、代码分析

  1. 配置串口的结构体
typedef struct
{
uint32_t USART_BaudRate; // 波特率设置
uint16_t USART_WordLength; //数据位数设置
uint16_t USART_StopBits; //停止位设置
uint16_t USART_Parity; //是否奇偶校验
uint16_t USART_Mode; //接收与发送都使能
uint16_t USART_HardwareFlowControl; //硬件流控制模式设置
} USART_InitTypeDef;
  1. 中断配置结构体
typedef struct
{
uint8_t NVIC_IRQChannel; // 配置USART为中断源
uint8_t NVIC_IRQChannelPreemptionPriority; // 抢断优先级
uint8_t NVIC_IRQChannelSubPriority; // 子优先级
FunctionalState NVIC_IRQChannelCmd; // 使能中断
} NVIC_InitTypeDef;
  1. 配置USART 的 IO引脚

    将Tx配置为复用推挽输出,将Rx配置为浮空输入
    /* USART1 使用IO端口配置 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA
  1. 配置USART 的工作模式配置
    /* USART1 工作模式配置 */
USART_InitStructure.USART_BaudRate = 115200; //波特率设置:115200
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位数设置:8位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位设置:1位
USART_InitStructure.USART_Parity = USART_Parity_No ; //是否奇偶校验:无
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制模式设置:没有使能
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//接收与发送都使能
  1. 将Rx读取配置为中断读取模式
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 设置NVIC中断分组2:2位抢占优先级,2位响应优先级 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // 配置USART为中断源
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 抢断优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; // 子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断
NVIC_Init(&NVIC_InitStructure); // 初始化配置NVIC
}
  1. 中断函数使用

    当串口接收到数据后此中断函数会被调用,调用次函数后,会将接收到的信息有通过串口发送获取。这里的中断函数名已经在启动文件中已经定义好了的,建议不做更改。



    注意:有的小伙伴编写好程序后,发现串口无法收到发送的信息,可能是这里的中断函数名写错了。
void USART1_IRQHandler(void)
{
uint16_t res;
/* 判断是否收到中断信号 */
if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
{
res = USART_ReceiveData(USART1);
USART_SendData(USART1, res);
}
//USART_SendData(USART1,(uint16_t)0xAC); }

五、程序源码

  1. usart1.c文件
/***************************************
* 文件名 :usart1.c
* 描述 :配置USART1
* 实验平台:MINI STM32开发板 基于STM32F103C8T6
* 硬件连接:------------------------
* | PA9 - USART1(Tx) |
* | PA10 - USART1(Rx) |
* ------------------------ **********************************************************************************/ #include "usart1.h"
#include <stdarg.h>
#include "misc.h" void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 设置NVIC中断分组2:2位抢占优先级,2位响应优先级 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // 配置USART为中断源
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 抢断优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; // 子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断
NVIC_Init(&NVIC_InitStructure); // 初始化配置NVIC
} void USART1_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure; /* 使能 USART1 时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); /* USART1 使用IO端口配置 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA /* USART1 工作模式配置 */
USART_InitStructure.USART_BaudRate = 115200; //波特率设置:115200
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位数设置:8位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位设置:1位
USART_InitStructure.USART_Parity = USART_Parity_No ; //是否奇偶校验:无
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制模式设置:没有使能
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//接收与发送都使能 USART_Init(USART1, &USART_InitStructure); //初始化USART1
USART_Cmd(USART1, ENABLE);// USART1使能 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 开启串口接受中断
NVIC_Configuration();// 串口中断优先级配置 } void USART1_IRQHandler(void)
{
uint16_t res;
/* 判断是否收到中断信号 */
if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
{
res = USART_ReceiveData(USART1);
USART_SendData(USART1, res);
}
//USART_SendData(USART1,(uint16_t)0xAC); }
  1. main.c文件
#include "stm32f10x.h"
#include "usart1.h" int main(void)
{ SystemInit(); //配置系统时钟为 72M USART1_Config(); //USART1 配置 while (1)
{ }
}

五、编译运行

  1. 编译

  2. 运行

六、常见问题

程序下载后运行后发送数据无反馈。

解决办法:

  1. 检查中断函数名是否正确。
  2. 将STM32的引脚设置为运行模式,有不知道的怎么设置为运行模式的小伙伴可以参考STM32零基础入门教程

STM32 USART串口通信的更多相关文章

  1. 单片机stm32 USART串口实际应用解析

    stm32作为现在嵌入式物联网单片机行业中经常要用多的技术,相信大家都有所接触,今天这篇就给大家详细的分析下有关于stm32的出口,还不是很清楚的朋友要注意看看了哦,在最后还会为大家分享有些关于stm ...

  2. stm32 usart 串口

    比特率是每秒钟传输二进制代码的位数,单位是:位/秒(bps).如每秒钟传送240个字符, 而每个字符格式包含10位(1个起始位.1个停止位.8个数据位),这时的比特率为: 10位 × 240个/秒 = ...

  3. STM32学习笔记:【004】USART串口通信

    版本:STM32F429 Hal库v1.10 串口通信能够实现两块电路之间不同的通信,在开发中作为打印调试也是一门利器(printf重定向). 补充一点小知识: 1. weak修饰符修饰的函数,说明这 ...

  4. (三)stm32之串口通信DMA传输完成中断

    一.DMA功能简介 首先唠叨一下DMA的基本概念,DMA的出现大大减轻了CPU的工作量.在硬件系统中,主要由CPU(内核).外设.内存(SRAM).总线等结构组成,数据经常要在内存和外设之间,外设和外 ...

  5. STM32的串口通信

    本篇文章主要讲解一个在开发过程中经常使用到的一个外设---串口. 串口是绝大多数 MCU 中不可或缺的一个外设,同时也是我们开发中经常使用的一种调试手段,所以在STM32的学习中,串口的配置使用也是必 ...

  6. (stm32f103学习总结)—USART串口通信

    一. USART简介 USART即通用同步异步收发器,它能够灵活地与外部设备进行全双工 数据交换,满足外部设备对工业标准 NRZ 异步串行数据格式的要求. UART即通用异步收发器,它是在USART基 ...

  7. STM32之串口通信

    一.RS232通信协议 1.概念 个人计算机上的通讯接口之一,由电子工业协会(Electronic Industries Association,EIA) 所制定的异步传输标准接口. 2.电气特性 逻 ...

  8. STM32 在串口通信时运用MODBUS协议

    最近一个项目用到了MODBUS协议,就学习了一下,这里做一下记录以免后续忘记. 要用到MODBUS肯定要先知道是MOBUS协议,这里呢我们就又要先理解协议的含义了. 所谓的协议是什么?就是互相之间的约 ...

  9. stm32中的串口通信你了解多少

    在基础实验成功的基础上,对串口的调试方法进行实践.硬件代码顺利完成之后,对日后调试需要用到的printf重定义进行调试,固定在自己的库函数中. b) 初始化函数定义: void USART_Confi ...

  10. stm32学习笔记之串口通信

    在基础实验成功的基础上,对串口的调试方法进行实践.硬件代码顺利完成之后,对日后调试需要用到的printf重定义进行调试,固定在自己的库函数中. b) 初始化函数定义: void USART_Confi ...

随机推荐

  1. 《Go程序设计语言》学习笔记之defer

    <Go程序设计语言>学习笔记之defer 一. 环境 Centos8.5, go1.17.5 linux/amd64 二. 概念 语法上,一个 defer 语句就是一个普通的函数或方法调用 ...

  2. Could not create connection to database server.Attempted reconnect 3 times .Giving up 解决

    错误信息 Could not create connection to database server.Attempted reconnect 3 times .Giving up. message ...

  3. PS-AXI-GPIO-流水灯设计

    PS-AXI-GPIO-流水灯设计 1.实验目的 在了解了AXI协议的基本内容后,通过已经设计好的AXI的IP核来了解实际设计中AXI的工作原理和设计原理是必要的.这个实验以前实际上按照教程做过,但是 ...

  4. exist和left join 性能对比

    今天遇到一个性能问题,再调优过程中发现耗时最久的计划是exist 部分涉及的三个表. 然后计划用left join 来替换exist,然后查询了很多资料,大部分都说exist和left join 性能 ...

  5. 配置腾讯云轻量级linux服务器用到的资源和步骤

    pasv_address=82.157.112.34 #请修改为您的 Linux 云服务器公网 IPsftp://82.157.112.34:21 ①下载系统可视化https://cloud.tenc ...

  6. #莫比乌斯反演,杜教筛#洛谷 6055 [RC-02] GCD

    题目 分析 如果令 \(u=pj,v=qj\) ,那么本质上就是让 \(gcd(i,u,v)==1\) 那就是 \(\sum_{i=1}^n\sum_{u=1}^n\sum_{v=1}^n[gcd(i ...

  7. #dp,矩阵乘法#洛谷 5371 [SNOI2019]纸牌

    题目 一副纸牌有 \(n\) 种,每种有 \(m\) 张, 现在有 \(k\) 个限制条件形如第 \(k_i\) 种牌至少选 \(a_i\) 张, 一个三元组合法当且仅当其为 \((i,i+1,i+2 ...

  8. Spring内存马分析

    环境搭建 踩了很多坑....,不过还好最后还是成功了 IDEA直接新建javaEE项目,然后记得把index.jsp删了,不然DispatcherServlet会失效 导入依赖: <depend ...

  9. 基于istio实现单集群地域故障转移

    本文分享自华为云社区<基于istio实现单集群地域故障转移>,作者:可以交个朋友. 一 背景 随着应用程序的增长并变得更加复杂,微服务的数量也会增加,失败的可能性也会增加.微服务的故障可能 ...

  10. 限时招募高校学生,带你沉浸式体验HDC.Together 2023