原创 使用BSRR和BRR寄存器直接操作STM32的I/O端口

2010-2-26 12:18 18404 15 21 分类: MCU/ 嵌入式

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;

PARTNER CONTENT

文章评论6条评论)

登录后参与讨论

用户441282 2013-9-1 19:15

假如你想在一个操作中对GPIOE的位7置'1',位6置'0',则使用BSRR非常方便: GPIOE->BSRR = 0x400080; 这句应该有问题,感觉应该是0x4080.

用户1156376 2012-9-20 17:04

分析的灰常好

用户1593097 2010-5-28 14:11

请问下,如果有时候对BSRR寄存器误操作,同时使某个位置位和清零,那个优先级更高啊? 如: “GPIOE->BSRR = 0x80008000;”。

用户547841 2009-12-23 10:55

i am confused and need your hlep.please tell me ,what's problem with my STM32F103ZE download program. IAR 5.30 + JTAG. I try to move download the hex to my STM32F103ZE ,Debugger starts downloading/verifying and at end reports fatal error : Wed Dec 23 10:48:14 2009: Loaded macro file: D:\Program Files\IAR Systems\Embedded Workbench 5.4 Evaluation\arm\config\flashloader\ST\FlashSTM32F10xxx.mac Wed Dec 23 10:48:15 2009: DLL version: V4.2 Wed Dec 23 10:48:15 2009: Firmware: J-Link ARM V7 compiled Apr 1 2009 12:02:10 Wed Dec 23 10:48:15 2009: JTAG speed is initially set to: 32 kHz Wed Dec 23 10:48:15 2009: TotalIRLen = 9, IRPrint = 0x0011 Wed Dec 23 10:48:15 2009: Found Cortex-M3 r1p1, Little endian. Wed Dec 23 10:48:15 2009: TPIU fitted. Wed Dec 23 10:48:15 2009: ETM fitted. Wed Dec 23 10:48:15 2009: FPUnit: 6 code (BP) slots and 2 literal slots Wed Dec 23 10:48:15 2009: Hardware reset with strategy 0 was performed Wed Dec 23 10:48:15 2009: Initial reset was performed Wed Dec 23 10:48:15 2009: J-Link found 2 JTAG device(s). ARM core Id: 3BA00477 Cortex M3 Wed Dec 23 10:48:15 2009: Device at TAP0 selected Wed Dec 23 10:48:15 2009: JLINK command: ProjectFile = F:\E_WorkReference\STM32\091204MyTest for SG5006G\settings\MainCrl_Debug.jlink, return = 0 Wed Dec 23 10:48:15 2009: JLINK command: device = STM32F10xxE, return = 0 Wed Dec 23 10:48:15 2009: TotalIRLen = 9, IRPrint = 0x0011 Wed Dec 23 10:48:15 2009: Found Cortex-M3 r1p1, Little endian. Wed Dec 23 10:48:15 2009: TPIU fitted. Wed Dec 23 10:48:15 2009: ETM fitted. Wed Dec 23 10:48:15 2009: FPUnit: 6 code (BP) slots and 2 literal slots Wed Dec 23 10:48:15 2009: -I- execUserFlashInit! Wed Dec 23 10:48:16 2009: 456 bytes downloaded and verified (0.98 Kbytes/sec) Wed Dec 23 10:48:16 2009: Loaded debugee: D:\Program Files\IAR Systems\Embedded Workbench 5.4 Evaluation\arm\config\flashloader\ST\FlashSTM32F10xxxRAM48K.out Wed Dec 23 10:48:16 2009: Target reset Wed Dec 23 10:48:19 2009: TotalIRLen = 9, IRPrint = 0x0011 Wed Dec 23 10:48:20 2009: Found Cortex-M3 r1p1, Little endian. Wed Dec 23 10:48:20 2009: TPIU fitted. Wed Dec 23 10:48:20 2009: ETM fitted. Wed Dec 23 10:48:20 2009: FPUnit: 6 code (BP) slots and 2 literal slots Wed Dec 23 10:48:20 2009: Hardware reset with strategy 0 was performed Wed Dec 23 10:48:22 2009: 30068 bytes downloaded into FLASH and verified (4.39 Kbytes/sec) Wed Dec 23 10:48:22 2009: Warning: Verify error at address 0x08000770, target byte: 0x08, byte in file: 0x16 Wed Dec 23 10:48:22 2009: Warning: Verify error at address 0x08000771, target byte: 0x07, byte in file: 0x00 Wed Dec 23 10:48:22 2009: Warning: Verify error at address 0x08000772, target byte: 0xFF, byte in file: 0x04 Wed Dec 23 10:48:22 2009: Warning: Verify error at address 0x08000773, target byte: 0x0F, byte in file: 0x2E Wed Dec 23 10:48:22 2009: Warning: There were warnings during download, see Log Window Wed Dec 23 10:48:24 2009: Loaded debugee: F:\E_WorkReference\STM32\091204MyTest for SG5006G\Debug\Exe\MainCrl.hex Wed Dec 23 10:48:24 2009: TotalIRLen = 9, IRPrint = 0x0011 Wed Dec 23 10:48:24 2009: Found Cortex-M3 r1p1, Little endian. Wed Dec 23 10:48:24 2009: TPIU fitted. Wed Dec 23 10:48:24 2009: ETM fitted. Wed Dec 23 10:48:24 2009: FPUnit: 6 code (BP) slots and 2 literal slots Wed Dec 23 10:48:24 2009: Software reset was performed Wed Dec 23 10:48:24 2009: Target reset Wed Dec 23 10:48:24 2009: Update all software breakpoints was performed Wed Dec 23 10:48:33 2009: Breakpoint hit: Code @ main.c:2351.34, type: default (auto) Wed Dec 23 10:48:41 2009: Breakpoint hit: Code @ main.c:337.2, type: default (auto) where is problem ? regards !

用户1090342 2009-11-24 10:49

ST网站下载。我的第一篇博客中有说明。

用户1158716 2009-11-23 14:31

你好,请问STM32的这些寄存器信息的详细说明文档在哪里可以下载?找了很久没有找到,谢谢!
相关推荐阅读
用户1090342 2010-08-05 12:33
使用STM32定时器输出任意相位差的方波
记得曾经有不少人问起这个问题,方法十分简单,不用说明,看图即知(这里画了2路输出,同样道理可以产生3路甚至4路输出)。此方法不但可以在STM32上实现,因为STM8定时器的多数功能与STM32一样,所...
用户1090342 2010-05-06 16:11
STM32的功能引脚重映射和复用功能
STM32中有很多内置外设的输入输出引脚都具有重映射(remap)的功能,本文对一些在使用引脚重映射时所遇到的有关问题加以说明。我们知道每个内置外设都有若干个输入输出引脚,一般这些引脚的输出脚位都是固...
用户1090342 2010-04-23 11:04
改正了每次只能发送一个字节的USB虚拟串口例程
目前发布的STM32_USB-FS-Device_Lib中有一个USB虚拟串口的例程,这个例程演示了把STM32配置为一个USB虚拟串口设备,STM32从它的USART接口接收数据并通过USB传送到上...
用户1090342 2010-03-06 12:30
STM32定时器的预装载寄存器与影子寄存器之间的关系
本文的说明依据STM32参考手册(RM0008)第10版:英文:http://www.st.com/stonline/products/literature/rm/13902.pdf中译文:http:...
用户1090342 2010-01-28 16:23
如何使用STM32的USB库支持延迟HID的GET_REPORT请求
首先,请参考我的另一篇博客:以HID的SET REPORT为例说明如何使用STM32的USB库支持控制端点0如果要支持HID的GET_REPORT请求,按照上一篇博客中的说明,只需要在STM32 US...
EE直播间
更多
我要评论
6
15
关闭 站长推荐上一条 /3 下一条