(转本文的目的是想说明配置GPIO的值如果用ODR寄存器,就会有读改写的过程,不利于任务间同步,即要考虑线程安全问题。如果BSRR可以直接设置某位,比ODR快)

基础知识
ORD,BSRR,BRR寄存器的作用是对已经初始化后的 IO 口输出高、低电平。

ODR寄存器可读可写,32位,既能控制管脚为高电平,也能控制管脚为低电平。GPIO管脚对于位写1为高电平,写 0 为低电平。(低 16 位用于设置 GPIO 口对应位输出高/低电平。高 16 位保留地址,读写无效。)

BSRR寄存器 称为端口位设置/清除寄存器,只写寄存器,32位, 既能控制管脚为高电平,也能控制管脚为低电平,对寄存器高 16位 写1 对应管脚为低电平,对寄存器低16位写1对应管脚为高电平。写 0 ,无动作

BRR寄存器称为端口位清除寄存器,只写寄存器,32位, 只能改变管脚状态为低电平,寄存器管脚对应位写 1 相应管脚会变为低电平。写 0 无动作。(BRR低 16 位用于设置 GPIO 口对应位输出低电平。高 16 位保留地址,读写无效。)

所以理论上来讲,BRR 寄存器的功能(低16位)和 BSRR 寄存器高 16 位的功能是一样的。

BSRR、BRR、 ODR 之间的关系
配置 BSRR , BRR 是为了对端口输出进行配置,而 ODR 寄存器也是用于输出数据的寄存器,一个 ODR 寄存器控制了一组(16位)的 GPIO 输出。因此,对 ODR 进行修改也可以到达对 IO 口输出进行配置。
由于对 ODR 寄存器的读写操作必须以 16 位的形式进行。因此,如果使用 ODR 改写数据以控制输出时,须采用“读-改-写”的形式进行。
BRR、BSRR都可以做到假如只想改变位0的值,则不论其他位为何值,用一个等号就可以完成。
而ODR改变时则是全部改变。
比如16位本来为1010101010101010,经过GPIOx->BSRR=0x01后变为1010101010101011,而经过GPIOx->ODR=0x01后变为0000000000000001。

实例分析
实例1
经常会看到类似如下的宏定义语句,用于对已经初始化后的 IO 口输出高、低电平。
#define SET_BL_HIGH() GPIOA->BSRR=GPIO_Pin_5
#define SET_BL_LOW() GPIOA->BRR=GPIO_Pin_010
其作用类似于如下两个库函数,
void GPIO_SetBits(GPIO_Typedef* GPIOx, uint16_t GPIO_Pin)
void GPIO_ResetBits(GPIO_Typedef* GPIOx, uint16_t GPIO_Pin)
而且实际上这两个库函数就是通过修改BSRR,BRR寄存器的值来实现对 IO 口设置的
因此,使用宏或者库函数本质上都是一样的。区别在于使用宏更快,而使用函数更灵活。

实例2
在使用寄存器BSRR 和寄存器BRR时,使用规则总结如下:
1、置GPIOD->BSRR低16位的某位为’1’,则对应的I/O端口置’1’;而置GPIOD->BSRR低16位的某位为’0’,则对应的I/O端口不变。
2、置GPIOD->BSRR高16位的某位为’1’,则对应的I/O端口置’0’;而置GPIOD->BSRR高16位的某位为’0’,则对应的I/O端口不变。
3、置GPIOD->BRR低16位的某位为’1’,则对应的I/O端口置’0’;而置GPIOD->BRR低16位的某位为’0’,则对应的I/O端口不变。

使用场合举例如下:
1)要设置D0、D5、D10、D11为高,而保持其它I/O口不变,只需一行语句:
GPIOD->BSRR = 0x0C21;// 使用规则1
2)要设置D1、D3、D14、D15为低,而保持其它I/O口不变,只需一行语句:
GPIOD->BRR = 0xC00A;// 使用规则三
3)要同时设置D0、D5、D10、D11为高,设置D1、D3、D14、D15为低,而保持其它I/O口不变,也只需一行语句:
GPIOD->BSRR = 0xC00A0C21;// 使用规则一和规则二

实例3
假设需要对 GPIOA_Pin_6 输出高电平。采用改写 ODR 寄存器的方式时,使用“读-改-写”操作,代码如下:
uint32_t temp;
temp = GPIOA->ODR;
temp = temp | GPIO_Pin_4;
GPIOA->ODR = temp;
而使用改写 BSRR 寄存器时,仅需要使用如下语句:
GPIOA->BSRR = GPIO_Pin_6;
在修改 ODR 时,为了确保对端口 6 的修改不会影响到其他端口的输出,需要对端口的原始数据进行保存,之后再对端口 6 的值进行修改,最后再写入寄存器(即读-改-写形式改变位的状态)。而对 BSRR 的操作,是写 1 有效,写 0 不改变原状态,因此可以对端口 6 置 1,其他位保持为 0。BSRR 为 1 的位,会修改相应的 ODR 位,从而控制输出电平。
因此,在设置单个 IO 口输出时,使用 BSRR 进行操作会更加方便。
————————————————
版权声明:本文为CSDN博主「爱学习的大喵喵」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44188050/article/details/104036639

STM32入门-区别ORD,BSRR,BRR寄存器相关推荐

  1. STM32 USART_Init() 初始化函数中BRR寄存器设置解析

    首先了解一下BRR寄存器的构造: 可以看到bit15:4设置USARTDIV的整数部分,bit 3:0设置USARTDIV的小数部分. 所以小数部分相当于把1分为16份,则DIV_Fraction = ...

  2. STM32 BSRR BRR ODR 寄存器解析(F4系列已经去掉BRR寄存器了)

    STM32 BSRR BRR ODR 寄存器解析(F4系列已经去掉BRR寄存器了) 一.用法 二.解释 三.BSRR.BRR. ODR 之间的关系 G0x0系列GPIO寄存器 F4系列GPIO寄存器( ...

  3. STM32 BSRR BRR ODR 寄存器解析

    一.用法 经常会看到类似如下的宏定义语句,用于对已经初始化后的 IO 口输出高.低电平. #define SET_BL_HIGH() GPIOA->BSRR=GPIO_Pin_0 #define ...

  4. STM32 GPIO 配置之ODR, BSRR, BRR 详解

    用stm32 的配置GPIO 来控制LED 显示状态,可用ODR,BSRR,BRR 直接来控制引脚输出状态. ODR寄存器可读可写:既能控制管脚为高电平,也能控制管脚为低电平.管脚对于位写1 gpio ...

  5. stm32 usart的BRR寄存器的配置,程序是CMSIS中的,分析它是怎么实现的?(自己设置好波特率,库文件会根据波特率计算BRR的值,和以前STM8不一样,需要自己根据波特率计算BRR值再设置)

    stm32 usart的BRR寄存器的配置 stm32 专栏收录该内容 23 篇文章0 订阅 订阅专栏 程序是CMSIS中的,分析它是怎么实现的? 波特率由整数和分数两部分组成. RCC_GetClo ...

  6. GPIO 配置之ODR, BSRR, BRR 详解

    STM32 GPIO 配置之ODR, BSRR, BRR 详解 用stm32 的配置GPIO 来控制LED 显示状态,可用ODR,BSRR,BRR 直接来控制引脚输出状态. ODR寄存器可读可写:既能 ...

  7. 【转载】如何学习STM32?STM32入门学习经验总结

    一.入门总结 1.1为什么要把时间花在"犹豫"上? 每当我们在入门之前(ARM是这样,DSP也一样),总会有很多疑问,会有很多顾虑.我们渴望知道学习STM32前景如何?需要啥基础? ...

  8. 基于Proteus无实物零基础STM32入门自学教程(七)--定时器点亮LED

    简介:本项目为基于STM32F103R6为核心定时器点亮LED工程.在第一个任务里我们点亮LED是使用延时点亮.从这一讲我们开始学习真正的定时器使用方法,而这种方法是最接近实际应用的.实际应用中几乎不 ...

  9. 【STM32入门100步--学习笔记】USART串口接收程序(含教学视频)

    STM32串口接收的程序和8051单片机一样,有2种接收方式:中断处理和查询方式. 试过两种方式之后发现,中断处理方式更方便,可以扩展多个数据的接收.推荐中断方式. 我已经将本资料内容整理后录制了视频 ...

最新文章

  1. linux线程堆分配,如何在Linux中的相同进程下为线程分配堆栈或内存
  2. 【Pandas】qcut和cut的区别
  3. 树莓派slam_SLAM+语音机器人DIY系列:(五)树莓派3开发环境搭建——6.树莓派USB与tty串口号绑定...
  4. Django学习记录
  5. Delphi的“动态窗体”技术实际应用[网络摘抄]
  6. C# 对象与JSON字符串互相转换的三种方式
  7. 【BZOJ1497】【codevs1789】最大获利,网络流之最大权闭合子图
  8. 超级计算机操作系统有什么不同,超级计算机功能强大吗?它与普通计算机不同,但也使用Windows系统...
  9. android 字母搜索栏,android仿微信通讯录搜索示例(匹配拼音,字母,索引位置)
  10. 在WinForm程序中嵌入ASP.NET[转]
  11. 手动配置gradle
  12. 【汇编语言与计算机系统结构笔记12】序格式与伪操作:简化段的定义、操作符等
  13. 1180魔方阵(每日学习)宁波大学OJ
  14. 随机游走问题的神奇应用(一)
  15. java自动化高频面试题
  16. 虚拟化服务器杀毒软件,虚拟机需要安装杀毒软件吗
  17. BitBake用户手册-3.语法和操作
  18. linux下多点电容触摸屏实验
  19. 又是白嫖Gitee的一天,PicGo+Gitee搭建图床,用过的都说真香!!!
  20. 匿名飞控STM32版代码整理之Ano_Imu.c

热门文章

  1. Win10无法访问网上邻居共享设备及共享文件夹错误代码(0x80004005)
  2. ubuntu下如何设置环境变量
  3. 防火墙设计和部署解析
  4. 打印机连接不上打印提示这个操作不受支持解决
  5. 05 【动静分离和URLRewrite】
  6. 什么是两化融合贯标?对企业有什么好处?
  7. css——三角形的实现
  8. 大英百科挂了,维基百科赢了
  9. 腾讯零反射全动态Android插件框架Shadow解析
  10. 独立钻石C语言Mac,C Code Develo‪p for Mac-C Code Develo‪p Mac版下载 V1.0-PC6苹果网