STM32单片机,UART的寄存器配置以及工作原理

2023-11-03

UART是重要的片上资源,主流单片机基本上都有该功能,通过UART可以扩展出很多的通信接口,如RS232、RS485、LIN,甚至WIFI、蓝牙模组等,可以说只要搞通讯就会涉及到UART。下面和大家分享STM32的UART配置。

1 UART是什么
USART全称universal synchronous asynchronous receiver transmitter通用同步异步接收发送器;速率最高可达4.5Mbits/s,波特率460800;
数据按位顺序发送的串行通信接口简称串口,USART模块是采用串行通信接口最常见的模块,为了方便,就把USART简称为串口;
USART接口通过RX,TX,GND同其他设备相连;当TX引脚被禁止时,该引脚恢复GPIO的配置;当TX引脚使能且未发送数据时,该引脚处于高电平(空闲态);
USART接口的数据字长度可编程,停止位长度可编程;可配置为DMA多缓冲通信;

2 USART的帧格式
串口数据应该遵循USART帧的格式,才能被串口识别;
首先总线需要持续至少一个空闲帧,然后连续发送数据帧,数据帧与数据帧之间有时会有断开帧,断开帧后需要接1-2bit停止位,连接下个数据帧;
断开帧只能为10bit或11bit低电平的帧(CR1_SBK[0]);然后接1或2bit的高电平作为停止位,然后接下一个数据帧;
数据帧的数据字有两种格式,(1)8 bit 数据位;(2)8bit 数据位 + 1 bit 奇偶校验位; 
在这里插入图片描述

3 USART的寄存器使用
每个USART都有7个自己的寄存器;用来配置该USART的所有功能;
有许多功能诸如硬件流控制,LIN模式,智能卡模式等,由于没用过或是用不上,实在晦涩难懂费时费力,故在此全部跳过;
以下给出了USART作为常用串口收发数据的工作框图,以及相关的寄存器配置;
3.1 工作框图
    在这里插入图片描述

在这里插入图片描述

3.2 相关寄存器配置
1)首先需要配置USART的6个参数:
波特率USART_BRR,字长M,停止位STOP,校验位PCE,PS,PEIE,USART的收发模式TE和RE和硬件流控制CTSIE,CTSE,RTSE;
2)USART提供了8个中断:TXEIE, TCIE, RXNEIE, PEIE, IDLEIE, CTSIE, LBDIE, EIE;8个中断使能均可以进入USART的中断函数,根据需要配置合适的中断使能位为1;通常为RXNEIE位;
3)然后使能接收器RE和发送器TE;
4)然后使能UE中断;
    在这里插入图片描述

4 USART的代码示例
4.1 标准库提供的常用USART接口
标准库为所有的外设都提供了封装寄存器的API接口函数,文件名为stm32f10x_peripheral.c;
以下为usart外设的常用函数;

//串口USARTx的参数配置初始化函数;
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
//使能串口,(主要是分频器和输出的设置)
void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
//使能串口中断,(就是那8个中断,均可以进入中断函数)
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);
//都是处理一个字节;
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
//读取SR寄存器的状态,SR的状态都是硬件设置的;
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
//读取SR寄存器和CRx控制寄存器的状态,和上面一个功能相同的;
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);

//修改SR寄存器的状态,单功能通讯用不上;
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);

4.2 USART1使用代码
#include “usartDemo.h”
u8 USART1_RX_BUF[256]; //接收缓存
u8 USART1_RX_CNT = 0; //接收字节计数
u8 USART1_REV_0D = 0; //收到\r
u8 USART1_REV_0A = 0; //收到\r和\n

//usart1初始化之后,便可以通过串口读写了;
void Usart1_Init(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);    //设置NVIC中断分组2:2位抢占优先级,2位响应优先级   0-3;

//USART1外设中断配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;    //抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;            //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                //IRQ通道使能
NVIC_Init(&NVIC_InitStructure);  

//GPIO初始化 USART1_TX    PA9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    //输出需要配置速率,输入不需要配置速率;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出,<中文..手册>8.1.11外设的GPIO配置
GPIO_Init(GPIOA, &GPIO_InitStructure);

//GPIO初始化    USART1_RX    PA10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;        //浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);

//USART1初始化
USART_InitStructure.USART_BaudRate = bound;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_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; //CR1中的TE,RE
USART_Init(USART1, &USART_InitStructure);

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//CR1中的RXNEIE中断
USART_Cmd(USART1, ENABLE);                    //CR1中的UE

}

void USART1_Send_Data(u8 *buf,u16 len)
{
u16 t;
for(t=0;t<len;t++)
{
USART_SendData(USART1,buf[t]);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
//发送字节完成后,TC硬件置1;
} //先读SR,后写DR清除TC位;
USART1_RX_CNT = 0;
USART1_REV_0D = 0;
USART1_REV_0A = 0;
}

void USART1_IRQHandler(void)
{
u8 Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
{
Res =USART_ReceiveData(USART1); //读DR,硬件清0 RXNE位;
USART1_RX_BUF[USART1_RX_CNT]=Res; //接收数据
USART1_RX_CNT++;
if(Res0x0d)
USART1_REV_0D = 1;
if(USART1_REV_0D&&(Res
0x0a))
USART1_REV_0A = 1;
}
//RXNE为1,读数据的同时又来了数据,那么新的数据丢失;产生溢出错误,读完数据后RXNE为0,但ORE标志还在;
//RXNE为1,又来了数据,产生接收溢出错误,置位ORE;
if(USART_GetFlagStatus(USART1,USART_FLAG_ORE) == SET)
{
USART_ReceiveData(USART1);
// USART_ClearFlag(USART1,USART_FLAG_ORE);//先读SR,后读DR,可以复位ORE位;应该不用软件清除了;
}
// USART_ClearFlag(USART1,USART_IT_RXNE); //读DR可以清除RXNE,应该不用软件清除了;
}

int main(void)
{
Usart1_Init(460800);
while(1)
{
if(USART1_REV_0A)
{
USART1_Send_Data(USART1_RX_BUF,USART1_RX_CNT);
}
}
}
4.2.1 在前面代码的基础上不使用串口中断,直接通过SR状态位来判断数据的收发;
将上面代码的usart1初始化代码中CR1的RXNEIE配置行注释掉,然后修改main函数如下即可;

int main(void)
{
Usart1_Init(460800);
while(1)
{
if ((USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==SET))
{
USART1_RX_BUF[USART1_RX_CNT] = USART_ReceiveData(USART1);
if(USART1_RX_BUF[USART1_RX_CNT]==0x0a)
USART1_REV_0A = 1;
USART1_RX_CNT++;
}
if(USART1_REV_0A)
{
USART1_REV_0A = 0;
for(int i=0;i<USART1_RX_CNT;i++)
{
USART_SendData(USART1, USART1_RX_BUF[i]);
while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
}
USART1_RX_CNT=0;
}
}
}

5 总结
USART的功能没想到还挺多的,寄存器看起来就有些费时了,很多概念都是新的,不好理解,直接拉低了效率;于是觉得这样不行,应该用什么看什么,用到再看,学海无涯,精力有限;
另外人家费心费力写好标准库不就是为了帮开发人员省时间吗?了解一下即可,以后没必要深入.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32单片机,UART的寄存器配置以及工作原理 的相关文章

  • WLAN配置

    SW1 sysname SW1 修改名称 undo info center enable 关闭提示 vlan batch 100 to 102 批量创建vlan 100 101 102 interface GigabitEthernet0
  • Ethereum geth 同步区块的三种模式

    Ethereum 以太坊 当前交易多 截止当前 2018 02 04 已经有5029238个区块 区块大小在150G左右 如果全部同步 并且严格逐个验证 需要太多的时间和计算 作者曾经用一台实体机 8核 16GB内存 2TB机械硬盘的del
  • leetcode1921.消灭怪物的最大数量(中等)

    解法 排序 贪心 具体 计算出每个怪物到达城市的时间 然后排序 class Solution public int eliminateMaximum vector
  • 深度学习论文笔记(可解释性)——CAM与Grad-CAM

    文章目录 主要工作 Global Average Pooling的工作机制 CAM Grad CAM 主要工作 CAM与Grad CAM用于解释CNN模型 这两个算法均可得出 c l a s s

随机推荐

  • 【JVM】Java垃圾回收机制(GC)详解

    Java垃圾回收机制 GC 详解 一 为什么需要垃圾回收 如果不进行垃圾回收 内存迟早都会被消耗空 因为我们在不断的分配内存空间而不进行回收 除非内存无限大 我们可以任性的分配不回收 但是事实并非如此 所以 垃圾回收是必须的 二 哪些内存需
  • 【kali】kali环境下安装dvwa

    STEP1 从github下载dvwa git clone https github com ethicalhack3r DVWA Q 我要自己安装git吗 A kali不用啦 一般都自带有 但是普通的ubuntu和debian上是没有的哦
  • Eclipse4.3 swt 插件在线安装

    到eclipse官网下载swt插件 1 点击该网站主菜单 Downloads gt Project 在出现的插件列表中找到 WindowBuilder 并点击 出现如下网页 复制该链接地址 当然该网页讲的就是如何安装swt designer
  • MATLAB地理数据处理 25:植被物候提取及分析模型优化(Savitzky-Golay)

    物候提取模型优化 1 前提 2 MATLAB代码 1 前提 之前我写过一篇使用Savitzky Golay处理遥感数据 获取地面物候信息的MATLAB代码 Python地理数据处理 十七 植被物候提取和分析 Savitzky Golay 但
  • MySQL数据表的约束

    数据表约束 对于某一列的值能添加哪些内容做了一定的限制 这种限制的手段就称为约束 一 约束的类型 NOT NULL 指示某列不能存储 NULL 值 UNIQUE 保证某列的每行必须有唯一的值 DEFAULT 规定没有给列赋值时的默认值 PR
  • Visual Studio 2022编译CMake工程

    用VS2022打开CMakeLists txt文件所在的文件夹 配置缓存 生成完毕 选择启动项 调试启动 运行输出 进入CMake项目视图 启动参数设置 增加args
  • Dll 编程入门指南

    我正在 学习 DLLs 谈不上对其有什么高屋建瓴的见解 本文只是 通过 编码让你看到并想知道代码是如何运行的 在本文中 我假定你知道如何使用你的编译器特性 比如设置目录路径等等 为了建立项目 请选择Win32 控制台项目 Win32 Con
  • 飞机游戏初步

    步骤 1 创建 hellogame项目 tools gt cocos2d console gt bin gt shift 右键 gt 在此处打开命令窗口 gt 路径pythoncocos py new hellogame p com gam
  • 一文说透 MySQL JSON 数据类型(收藏)

    JSON 数据类型是 MySQL 5 7 8 开始支持的 在此之前 只能通过字符类型 CHAR VARCHAR 或 TEXT 来保存 JSON 文档 相对字符类型 原生的 JSON 类型具有以下优势 在插入时能自动校验文档是否满足 JSON
  • 【日志脱敏】Springboot集成日志框架脱敏实战

    针对日志打印而不能泄露用户隐私需求 需要利用相应日志框架实现脱敏 本文基于log4j logback 重写相应方法 匹配出正则并转换为脱敏后的日志 效果展示如下 name 李 idNumber 110106 226X mobile 130
  • Scala编译器的安装

    1 Scala编译器安装 1 1 安装JDK 因为Scala是运行在JVM平台上的 所以安装Scala之前要安装JDK 1 2 安装Scala 1 2 1 Windows安装Scala编译器 访问Scala官网http www scala
  • 两个有序数组合并成一个有序数组——C++实现

    程序分析 这里做的是升序 C 代码 include
  • 如何监控Android模拟器的HTTP访问情况

    前几个月 在调试某个应用时 需要监控应用与服务器之间的HTTP通讯 从搜索引擎找到的方案几乎全错 要么是人云亦云 要么是只能满足旧的平台版本 要么根本就是臆测 不得其解之际 用比较复杂的方法解决了 昨天想起来 觉得太过窝囊 于是重整旗鼓 终
  • react-节点更新与销毁

    文章目录 更新与销毁 节点更新 对比更新 找到了对比目标 没有找到对比目标 更新与销毁 发生更新的场景 重新调用ReactDOM render 触发根节点更新 在类组件中调用setState 会导致该节点更新 节点更新 分为两种 如果调用的
  • Linux学习命令

    cd ls mkdir rmdir rm touch 创建文件 cat 显示文件内容 不适合查看内容较长的文件 n 显示行号 cat n etc issue tac 和cat类似 但是是倒过来显示 more 分页显示文件内容 空格 或f 翻
  • 【CLYZ集训】马可波罗【按位】【博弈论】

    题目大意 有两个人 n n n堆石子 每个人轮流取 每次可以取1 x x x个 最后没得取的人输 两人都采取最优策略 问对于 x
  • 双目视觉标定MATLAB

    双目标定 双目摄像机需要标定的参数 摄像机内参数矩阵 畸变系数 两相机之间的旋转矩阵 R 和平移矩阵 T 其中摄像机内参数矩阵和畸变系数矩阵可以通过单目标定的方法标定出来 双目摄像机标定和单目摄像机标定最主要的区别就是双目摄像机需要标定出左
  • oracle自定义函数function

    遇到的问题 遇到一个数据统计的需求 要求 统计身份证号码性别位填写错误的个数 首先普及身份证性别位 至今为止身份证有18位和15位两种 18位身份证号性别位是17位 第17位数字奇数为男性 偶数为女性 0也是女性 15位身份证号性别位是最后
  • springboot AOP日志

    引入项目依赖
  • STM32单片机,UART的寄存器配置以及工作原理

    UART是重要的片上资源 主流单片机基本上都有该功能 通过UART可以扩展出很多的通信接口 如RS232 RS485 LIN 甚至WIFI 蓝牙模组等 可以说只要搞通讯就会涉及到UART 下面和大家分享STM32的UART配置 1 UART