OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7313|回复: 6

STM32 Cortex m3内核的单片机I/O端口输出寄存器和端口位设置/清除寄存器的问题?

[复制链接]

20

主题

74

帖子

0

精华

初级会员

Rank: 2

积分
184
金钱
184
注册时间
2013-3-24
在线时间
6 小时
发表于 2013-3-24 09:18:34 | 显示全部楼层 |阅读模式
我在看ST32手册时端口有一个“端口数据输出寄存器GPI0_ODR”,可对完成对I/0的读写,即置1或置0,还有一个“端口位设置/清除寄存器GPI0_BSRR”也可完成对端口的置1或置0,
这两个寄存器功能上感觉有重复,如果不是这样,它这样做的目地是什么呢
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-3-24 10:07:46 | 显示全部楼层
转自百度:
STM32的每个GPIO端口都有两个特别的寄存器,GPIOx_BSRR和GPIOx_BRR寄存器,通过这两个寄存器可以直接对对应的GPIOx端口置'1'或置'0'。

GPIOx_BSRR的高16位中每一位对应端口x的每个位,对高16位中的某位置'1'则端口x的对应位被清'0';寄存器中的位置'0',则对它对应的位不起作用。

GPIOx_BSRR的低16位中每一位也对应端口x的每个位,对低16位中的某位置'1'则它对应的端口位被置'1';寄存器中的位置'0',则对它对应的端口不起作用。

简单地说GPIOx_BSRR的高16位称作清除寄存器,而GPIOx_BSRR的低16位称作设置寄存器。另一个寄存器GPIOx_BRR只有低16位有效,与GPIOx_BSRR的高16位具有相同功能。



--------------------------------------------------------------------------------


举个例子说明如何使用这两个寄存器和所体现的优势。例如GPIOE的16个IO都被设置成输出,而每次操作仅需要改变低8位的数据而保持高8位不变,假设新的8位数据在变量Newdata中,

这个要求可以通过操作这两个寄存器实现,STM32的固件库中有两个函数GPIO_SetBits()和GPIO_ResetBits()使用了这两个寄存器操作端口。

上述要求可以这样实现:

GPIO_SetBits(GPIOE, Newdata & 0xff);
GPIO_ResetBits(GPIOE, (~Newdata & 0xff));

也可以直接操作这两个寄存器:

GPIOE->BSRR = Newdata & 0xff;
GPIOE->BRR = ~Newdata & 0xff;

当然还可以一次完成对8位的操作:

GPIOE->BSRR = (Newdata & 0xff) | (~Newdata & 0xff)<<16;

从最后这个操作可以看出使用BSRR寄存器,可以实现8个端口位的同时修改操作。



--------------------------------------------------------------------------------


如果不是用BRR和BSRR寄存器,则上述要求就需要这样实现:

GPIOE->ODR = GPIOE->ODR & 0xff00 | Newdata;



--------------------------------------------------------------------------------


使用BRR和BSRR寄存器可以方便地快速地实现对端口某些特定位的操作,而不影响其它位的状态。

比如希望快速地对GPIOE的位7进行翻转,则可以:

GPIOE->BSRR = 0x80; // 置'1'
GPIOE->BRR = 0x80; // 置'0'

如果使用常规'读-改-写'的方法:

GPIOE->ODR = GPIOE->ODR | 0x80; // 置'1'
GPIOE->ODR = GPIOE->ODR & 0xFF7F; // 置'0'



--------------------------------------------------------------------------------


有人问是否BSRR的高16位是多余的,请看下面这个例子:

假如你想在一个操作中对GPIOE的位7置'1',位6置'0',则使用BSRR非常方便: 
  GPIOE->BSRR = 0x400080; 

如果没有BSRR的高16位,则要分2次操作,结果造成位7和位6的变化不同步! 
  GPIOE->BSRR = 0x80; 
  GPIOE->BRR = 0x40;
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 1 反对 0

使用道具 举报

2

主题

25

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
454
金钱
454
注册时间
2016-2-17
在线时间
82 小时
发表于 2016-6-13 17:14:02 | 显示全部楼层
正点原子 发表于 2013-3-24 17:05
回复【3楼】chenjiawei7:
---------------------------------
因为不需要高速处理...

请问怎么才算是高速??
回复 支持 1 反对 0

使用道具 举报

20

主题

74

帖子

0

精华

初级会员

Rank: 2

积分
184
金钱
184
注册时间
2013-3-24
在线时间
6 小时
 楼主| 发表于 2013-3-24 10:48:31 | 显示全部楼层
明白了,那原子的寄存器的例程  为什么都是操作ODR的呢?
回复 支持 反对

使用道具 举报

9

主题

51

帖子

0

精华

初级会员

Rank: 2

积分
108
金钱
108
注册时间
2013-3-16
在线时间
0 小时
发表于 2013-3-24 15:34:53 | 显示全部楼层
mark
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-3-24 17:05:05 | 显示全部楼层
回复【3楼】chenjiawei7:
---------------------------------
因为不需要高速处理...
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2013-3-24 20:10:58 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
牛逼。。。。。。。。。。。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-10 09:57

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表