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

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

[复制链接]
STMCU小助手 发布时间:2022-1-14 22:42
用stm32 的配置GPIO 来控制LED 显示状态,可用ODR,BSRR,BRR 直接来控制引脚输出状态.
ODR寄存器可读可写:既能控制管脚为高电平,也能控制管脚为低电平。
管脚对于位写1 gpio 管脚为高电平,写 0 为低电平
BSRR 只写寄存器:既能控制管脚为高电平,也能控制管脚为低电平。
: o1 J( R/ I; d7 b2 `  a对寄存器高 16bit 写1 对应管脚为低电平,对寄存器低16bit写1对应管脚为高电平。写 0 ,无动作
BRR 只写寄存器:只能改变管脚状态为低电平,对寄存器 管脚对于位写 1 相应管脚会为低电平。写 0 无动作。. V9 M$ I; L, e' Y# @( r

7 v& i. }  l; X, P刚开始或许你跟我一样有以下疑惑:
1.既然ODR 能控制管脚高低电平为什么还需要BSRR和SRR寄存器?+ w' h0 {" A  @5 T. _1 g
2.既然BSRR能实现BRR的全部功能,为什么还需要SRR寄存器?
9 g2 O% w8 M+ {$ J; A' m
8 }7 y$ {+ j# R& o! X5 ^" K: V+ [对于问题 1 ------ 意法半导体给的答案是---
“This way, there is no risk that an IRQ occurs between the read and the modify access.”
. E1 q! K6 Z. n5 R) o什么意思呢?就就是你用BSRR和BRR去改变管脚状态的时候,没有被中断打断的风险。也就不需要关闭中断。
用ODR操作GPIO的伪代码如下:
disable_irq()
$ C5 Q  v( W: n- G& X( osave_gpio_pin_sate = read_gpio_pin_state();
' I, X+ _4 Q9 {/ O$ Q* K" psave_gpio_pin_sate = xxxx;
: x) i5 d: f2 i, b% u0 O- Vchang_gpio_pin_state(save_gpio_pin_sate);" M" D& g0 ?% Z7 ?  y% i
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()使用了这两个寄存器操作端口。
$ v. H* r3 R( P3 _1 Y. N3 T2 [- z, E; J  G- A! u( U3 {
上述要求可以这样实现:6 t& b* Q% @. h3 v( k  H! |
2 H( E# |! V: w7 g' W/ R
GPIO_SetBits(GPIOE, Newdata & 0xff);
# H3 r% a/ {& q& tGPIO_ResetBits(GPIOE, (~Newdata & 0xff));
8 Y6 I3 k+ ]: @  R, ^' b0 P
2 n, K2 ~. |* Y' {  y  f- s, e0 n也可以直接操作这两个寄存器:( w2 B7 W0 Y" Y' v% o0 W

% b) K5 K! H1 S, L1 yGPIOE->BSRR = Newdata & 0xff;6 \2 f/ z0 f2 u+ M' P
GPIOE->BRR = ~Newdata & 0xff;
$ x: c5 S! i, r, Q1 @0 t4 V% K! A7 q
当然还可以一次完成对8位的操作:  B' a; T' O$ Q2 a+ q! u
' t* B- q6 y0 J
GPIOE->BSRR = (Newdata & 0xff) | ( (~Newdata & 0xff)<<16 );
- S  h7 i: j4 L" X% B1 C/ o
4 m# r( D% e) I, K% h! G当然还可以一次完成对16位的操作:( }7 m9 y- r* w  B) A

  h; `! g$ j  ?8 I# EGPIOE->BSRR = (Newdata & 0xffff) | ( (~Newdata )<<16 );
$ x+ y3 Y" }) e/ G7 \" [
2 @' f8 h, {9 ]2 \1 m1 [从最后这个操作可以看出使用BSRR寄存器,可以实现8个端口位的同时修改操作。! s3 B. D, j$ e* u

3 W/ u& _3 h7 y8 t: L& e有人问是否BSRR的高16位是多余的,请看下面这个例子:
假如你想在一个操作中对GPIOE的位7置'1',位6置'0',则使用BSRR非常方便:
/ j$ E& r( j% h6 G9 R( @  GPIOE->BSRR = 0x400080;
如果没有BSRR的高16位,则要分2次操作,结果造成位7和位6的变化不同步!
4 |' T8 t% n3 H7 ~( A" }0 B. u+ x* k  GPIOE->BSRR = 0x80;
: _4 t/ Y( j' }0 R- i9 V  GPIOE->BRR = 0x40;
121245215351684.png
BSRR还有一个特点,就是Set比Reset的级别高,
就是说同一个bit又做Set又做Reset,最后结果是Set
要同步变化只要简单的 GPIOx->BSRR = 0xFFFF0000 | PATTEN;
即可,不用考虑哪些需要置1,哪些需要清零
从最后这个操作可以看出使用BSRR寄存器,可以实现8个端口位的同时修改操作。
" h# `8 P4 t- j: N% d" @1 m1 @
赞 收藏 评论0 发布时间:2022-1-14 22:42

举报

0个回答

所属标签

相似技术帖

官网相关资源

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