你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32 GPIO 配置之ODR, BSRR, BRR 详解

[复制链接]
STMCU小助手 发布时间:2022-1-14 22:42
用stm32 的配置GPIO 来控制LED 显示状态,可用ODR,BSRR,BRR 直接来控制引脚输出状态.
ODR寄存器可读可写:既能控制管脚为高电平,也能控制管脚为低电平。
管脚对于位写1 gpio 管脚为高电平,写 0 为低电平
BSRR 只写寄存器:既能控制管脚为高电平,也能控制管脚为低电平。4 y/ b$ |  h+ V' [- F) W
对寄存器高 16bit 写1 对应管脚为低电平,对寄存器低16bit写1对应管脚为高电平。写 0 ,无动作
BRR 只写寄存器:只能改变管脚状态为低电平,对寄存器 管脚对于位写 1 相应管脚会为低电平。写 0 无动作。* j4 `& e+ \& O" s0 f8 `
5 r6 V! ?' Z  B( v
刚开始或许你跟我一样有以下疑惑:
1.既然ODR 能控制管脚高低电平为什么还需要BSRR和SRR寄存器?5 f/ K) P2 q2 I, t9 N2 }7 A6 {
2.既然BSRR能实现BRR的全部功能,为什么还需要SRR寄存器?' t+ }, q5 V1 ]( N% b: I
8 o9 {2 w& u6 w1 K7 e) M
对于问题 1 ------ 意法半导体给的答案是---
“This way, there is no risk that an IRQ occurs between the read and the modify access.”- h5 K, g4 Z- `5 H! z  v
什么意思呢?就就是你用BSRR和BRR去改变管脚状态的时候,没有被中断打断的风险。也就不需要关闭中断。
用ODR操作GPIO的伪代码如下:
disable_irq()6 k1 l5 S. G! o1 p
save_gpio_pin_sate = read_gpio_pin_state();
9 u3 e: q! v9 ~3 o2 Psave_gpio_pin_sate = xxxx;
5 E, L: _/ |- a' @chang_gpio_pin_state(save_gpio_pin_sate);
! ]! n* u2 f( y! Q9 N, w% A2 ]enable_irq();
关闭中断明显会延迟或丢失一事件的捕获,所以控制GPIO的状态最好还是用SBRR和BRR
对于问题 2 ------- 个人经验判断意法半导体仅仅是为了程序员操作方便估计做么做的。
因为BSRR的 低 16bsts 恰好是set操作,而高16bit是 reset 操作 而BRR 低 16bits 是reset 操作。
简单地说GPIOx_BSRR的高16位称作清除寄存器,而GPIOx_BSRR的低16位称作设置寄存器。
另一个寄存器GPIOx_BRR只有低16位有效,与GPIOx_BSRR的高16位具有相同功能。
举个例子说明如何使用这两个寄存器和所体现的优势。
例如GPIOE的16个IO都被设置成输出,而每次操作仅需要
改变低8位的数据而保持高8位不变,假设新的8位数据在变量Newdata中,
这个要求可以通过操作这两个寄存器实现,STM32的固件库中有两个函数
GPIO_SetBits()和GPIO_ResetBits()使用了这两个寄存器操作端口。
& N$ t. G' K& |8 i* r: V0 V0 s9 ^8 @- q* y* b( T
上述要求可以这样实现:
4 v( I, j! i/ n+ P; V* B
+ k$ K$ K1 \( J+ u/ \1 `GPIO_SetBits(GPIOE, Newdata & 0xff);' f2 N5 K  b7 b) `6 u. d! E
GPIO_ResetBits(GPIOE, (~Newdata & 0xff));
/ }$ y8 W( `/ F. }
" ~% G+ F! N+ E+ K' g: s8 M3 p也可以直接操作这两个寄存器:/ y# [4 Q4 v" a

7 M! r* T. n- Y* G8 MGPIOE->BSRR = Newdata & 0xff;
& A: B0 K+ A8 {0 @9 C6 K+ g1 _( ~# q7 [GPIOE->BRR = ~Newdata & 0xff;1 i$ P% O: C% y" A5 W

7 [, W/ [: y+ v/ x! c; h5 E. c* M当然还可以一次完成对8位的操作:2 }. [6 C5 K7 K! [2 }

& D7 W8 e: E' o' @$ bGPIOE->BSRR = (Newdata & 0xff) | ( (~Newdata & 0xff)<<16 );0 F+ Q2 ~1 m& {

; h9 R% n( q0 `0 \/ A2 W当然还可以一次完成对16位的操作:$ D: k* X! o$ W" w) l) K
% P9 i$ J3 X6 L! G: w) t
GPIOE->BSRR = (Newdata & 0xffff) | ( (~Newdata )<<16 );. W) O: K, C# |; S4 p8 [  O

/ I) O+ d; N) D, T  Q! \从最后这个操作可以看出使用BSRR寄存器,可以实现8个端口位的同时修改操作。5 }/ v6 G: s( L1 O/ G

7 n. |' l' A0 v有人问是否BSRR的高16位是多余的,请看下面这个例子:
假如你想在一个操作中对GPIOE的位7置'1',位6置'0',则使用BSRR非常方便:
, {% d$ A. L8 f2 w. x6 f+ c: F1 \  GPIOE->BSRR = 0x400080;
如果没有BSRR的高16位,则要分2次操作,结果造成位7和位6的变化不同步!   n5 ~* v! l: s. y1 x2 U
  GPIOE->BSRR = 0x80;
3 |5 f8 _6 G# x' |2 M  GPIOE->BRR = 0x40;
121245215351684.png
BSRR还有一个特点,就是Set比Reset的级别高,
就是说同一个bit又做Set又做Reset,最后结果是Set
要同步变化只要简单的 GPIOx->BSRR = 0xFFFF0000 | PATTEN;
即可,不用考虑哪些需要置1,哪些需要清零
从最后这个操作可以看出使用BSRR寄存器,可以实现8个端口位的同时修改操作。

# c6 r$ d3 v" r, @
收藏 评论0 发布时间:2022-1-14 22:42

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版