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 = 0x4080;
如果没有BSRR的高16位,则要分2次操作,结果造成位7和位6的变化不同步!
GPIOE->BSRR = 0x80;
GPIOE->BRR = 0x40;
关键字:BSRR BRR寄存器 STM32
引用地址:
使用BSRR和BRR寄存器直接操作STM32的I/O端口
推荐阅读最新更新时间:2024-03-16 13:58
STM32通过I2C与BMP280通信
BMP280气压传感器(Digital Pressure sensor) 测试流程图: 项目中使用的是I2C通信,BMP280的作为slave的地址要确认好,它的地址根据硬件电路SDO接什么脚来决定: 1.BMP280的测试启动流程(注意它的datasheet中的status寄存器): (1)读取BMP280的id,其值等于0x58。 (2)把补偿寄存器的值都读出来。 (3)对BMP280进行reset。 (4)对BMP280的数据采集精度,模式。。。等进行配置。 (5)给点延时,等待数据采集完毕放入寄存器中。 (6)读取寄存器中的采集数据。 注意:BMP280对温度和气压的测量是通过一堆补偿数据然后根据自己的算法算
[单片机]
stm32利用oled显示屏与按键进行PID参数调节实现人机交互
上一个学期在学校做四轮车利用PID实现直线走,在调试过程中,我之前是每改一个参数就下载程序进控制板进行调试,观察车是否偏移来确定pid参数,但是后来我发现这样的效率很慢,经别人提醒后,我自己做了一个小小的人机交互界面,来显示pid的参数以及对pid参数进行调整。 以下是显示效果: 接着我在附上主要代码: // 功能描述 : OLED 7针SPI接口演示例程(STM32F103系列) // 说明: // ---------------------------------------------------------------- // GND 电源地 // VCC 3.
[单片机]
STM32——按键输入之static
Static申明的局部变量,存储在静态存储区。 它在函数调用结束之后,不会被释放。它的值会一直保留下来。 所以可以说static申明的局部变量,具有记忆功能。 按键扫描(支持连续按)的一般思路 u8 KEY_Scan(void) { if(KEY按下) { delay_ms(10);//延时10-20ms,防抖。 if(KEY确实按下) { return KEY_Value; } return;// 无效值 } } 按键扫描(不支持连续按)的一般思路 u8 KEY_Scan(void) { static u8 ke
[单片机]
STM32之独立看门狗实验
实验现象: 开始LED1亮,LED2熄灭,若不隔时间按KEY1则发现LED2因独立看门狗的作用使系统复位而不断闪烁,若间断的按KEY1则发现LED2不会闪烁,表明没有复位。 实验平台: 基于STM32F103C8T6的彩屏开发板 操作步骤: 1)向IWDG_KR 写入0X5555。 通过这步,我们取消IWDG_PR 和IWDG_RLR 的写保护,使后面可以操作这两个寄存器。 设置 IWDG_PR 和IWDG_RLR 的值。 这两步设置看门狗的分频系数,和重装载的值。由此,就可以知道看门狗的喂狗时间(也 就是看门狗溢出时间),该时间的计算方式为: Tout=((4×2^prer) ×rlr) /40 其中Tout 为看门狗溢
[单片机]
stm32单片机红外遥控超声波避障小车
和同学一起在学校参加院电子设计大赛做的项目,看起来时间很长,但实际上我们拢共做的时间差不多是3天的样子。 板子是正点的,所以很多地方我们就直接扒的正点的例程,比如红外遥控的部分完整拿过来了,能直接用。 我们在完成学校的要求后又多加了测距显示和差速调节(让小车可以从完全停止到最高速度),后面我会分块尽量详细叙述小车的功能原理及代码介绍。 视频演示 https://www.bilibili.com/video/av85501350/ 电源 我们采用的是三节18650供电,三节电池就有12v,用来驱动小车绰绰有余,为了获得更稳定符合小车需求的电压,我们又采用了一个LM2596S降压模块,把12V的电压给降到3v给单片
[单片机]
意法半导体和Sensory 开展合作,赋能大众市场嵌入式声控技术应用
意法半导体和Sensory 开展合作,通过STM32Cube 软件生态系统赋能大众市场嵌入式声控技术应用 STM32 MCU搭配 Sensory 的 VoiceHub 技术,简化穿戴设备、物联网和智能家居产品声控用户界面开发 2022 年 6 月 20 日,中国——服务多重电子应用领域、全球排名前列的半导体公司意法半导体(STMicroelectronics,简称ST),与世界排名前列的嵌入式语音识别技术供应商、意法半导体授权合作伙伴 Sensory Inc公司 宣布了一项合作协议,赋能STM32 微控制器 (MCU)用户社区为各种智能嵌入式产品开发直观的语音识别用户界面及产品原型。 该合作项目整合了意法半导体S
[模拟电子]
STM32学习日志——定时器中断实验
今天学习的是通用定时器及其中断,首先是内部时钟的选择,定时器的时钟Tclk是由APB1时钟乘以1或2决定的,至于是1还是2,要看APB1的分频系数(AHB/APB1),如果为1,则乘以1,否则乘以2。接着就可以根据我们想设定的时间Tout,去配置ARR跟PSC,这两个数是存在16位的寄存器,所以他们的范围为(0-65535),在这个范围内任意取值,满足公式即可。如果我么要配置500ms,可将ARR配置为2499,PSC配置为14399。也就是定时器计数的一个周期为500ms。(ARR为自动重装载值,PSC为Tclk的预分频系数) 根据步骤去写程序就很简单了。 实现功能:通过定时器的中断控制一个绿灯翻转,时间为500ms
[单片机]
为什么学习STM32时还要学习汇编
不同的平台的汇编代码是不一样的,最早的汇编在50年代就发明了,比很多人的父母的年龄都大,老掉牙,不用学习怎么写汇编。一个公司有一个人知道怎么写汇编就够了。但要学习读汇编,为什么学习汇编? 1、性能 直接翻译为机器语言,性能最高。优秀的C语言效率只能达到汇编的80%左右。其他高级语言跟汇编一比差得更远。语言越高级性能越差。很多bootloader和BIOS用汇编写,汇编操作的是电脑,手机刚刚上电时,硬件和初始化的那些命令,它们的性能的要求比较高,效率高开机速度更快。 分析问题 个人认为,编程人与机器对话,我们写C,写JAVA,但是电脑并不认识这些语言,电脑只认识0和1;所以需要一个人来翻译这些语言,这个翻译官就是编译器,但是
[单片机]