STM32使用BSRR和BRR寄存器快速操作
高手带你解析STM32 BSRR BRR ODR 寄存器

出取反输出,当前输出为高则输出低,当前输出低则输出高),官方的库函数 就是直接对 ODR 寄存器进行操作的。代码如下: void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) { /* Check the parameters */ assert_param(IS_GPIO_PIN(GPIO_Pin)[标签:内容]
一样的。也就是说,输出低电平的宏语句,可以有如下两种写法。 #define SET_BL_LOW() GPIOA->BRR=GPIO_Pin_0 等价于 #define SET_BL_LOW() GPIOA->BSRR=GPIO_Pin_0 这幺来看的话,其实 BRR 寄存器是比较多余的。而实际上,在最新的 STM32F4 系列 MCU 的 GPIO 寄存器中,已经找不到 BRR 寄存器了,仅保留了 BSRR 寄存器用 于实现端口输出高低电平。因此,在 STM32F4 系列 MCU 的库函数中,对 GPIO 口输出高低电平的函数为如下形式: void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState) { /* Check the parameters */ assert_param(IS_GPIO_PIN(GPIO_Pin)); assert_param(IS_GPIO_PIN_ACTION(PinState)); if(PinState != GPIO_PIN_RESET)
高手带你解析 STM32 BSRR BRR ODR 寄存器
一、用法 经常会看到类似如下的宏定义语句,用于对已经初始化后的 IO 口输出 高、低电平。 #define SET_BL_HIGH() GPIOA->BSRR=GPIO_Pin_0 #define SET_BL_LOW() GPIOA->BRR=GPIO_Pin_012 其作用类似于如下两个库函数, void GPIO_SetBits(GPIO_Typedef* GPIOx, uint16_t GPIO_Pin) void GPIO_ResetBits(GPIO_Typedef* GPIOx, uint16_t GPIO_Pin) 12 而且实际上这两个库函数就是通过修改 BSRR,BRR 寄存器的值来实现对 IO 口设置的。如下便是输出高电平的函数体: void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_arameters */ assert_param(IS_GPIO_ALL_PERIPH(GPIOx)); assert_param(IS_GPIO_PIN(GPIO_Pin)); GPIOx->BSRR = GPIO_Pin; }12345678 因此,使用宏或者库函数本质上都是一样的。区别在于使用宏更快,而使 用函数更灵活。 二、解释 BSRR 和 BRR 都是 STM32 系列 MCU 中 GPIO 的寄存器。 BSRR 称 为端口位设置/清楚寄存器,BRR 称为端口位清除寄存器。 BSRR 低 16 位用于设置 GPIO 口对应位输出高电平,高 16 位用于设置 GPIO 口对应位输出低电平。 BRR 低 16 位用于设置 GPIO 口对应位输出低电平。高 16 位为保留地 址,读写无效。 所以理论上来讲,BRR 寄存器的功能和 BSRR 寄存器高 16 位的功能是
STM32F103串口通信寄存器设置

9.PS为校验位选择。0:偶校验;1:奇校验。
8.PE中断使能。0:禁止产生中断;1:当USART_SR中PE为1时产生串口中断。默认0
7.TXIE为发送缓冲区空中断使能位。1:当USART_SR中的TXE位为1时将产生串口中断。
6.TCIE为发送完成中断使能位。1:当USART_SR中的TC位为1时将产生串口中断。
USART1->BRR=0x0ea6;//主频36M时,波特率为9600
//USART1->BRR=0x0139;//主频36M时,波特率为115200
//USART1->CR1|=0x200c;//串口开,发送长度8字节,无校验,发送开,接收开;
USART1->CR1|=0x340c;//串口开,发送长度9字节,偶校验,发送开,接收开;
//字节0x0a,则存入数表
else{if(shubiao[len-1]==0x0d){enddd=1;len--;};};};
//如果是0x0a,则判断前一个字符是不是0x0d,(回车符ASCII码为0x0a0d)//是的话则标记接受完成标志eddd并删掉已接受到的前一个字节的数据
if(enddd==1)//如果接受完成了
它是由两个寄存器组成的,一个给发送用(TDR),一个给接收用(RDR),该寄存器兼具读和写的功能。TDR寄存器提供了内部总线和输出移位寄存器之间的并行接口。RDR寄存器提供了输入移位寄存器和内部总线之间的并行接口。
当使能校验位(USART_CR1中PCE位被置位)进行发送时,写到MSB的值(根据数据的长度不同,MSB是第7位或者第8位)会被后来的校验位取代。当使能校验位进行接收时,读到的MSB位是接收到的校验位。
STM32的IO端口高8位或低8位单独操作方法

举例说下怎幺对IO端口赋值:
1.对高8位/低8位/全部清零
很明显,这个只需要操作BRR寄存器即可:
对高8位清零:GPIOA->BRR=0xFF00
对低8位清零:GPIOA->BRR=0x00FF
全部清零:GPIOA->BRR=0xFFFF或GPIOA->ODR=0x0000
1,置0的位不影响原来的值
高16位应该置为0000000010101010,这个就等于~0x55(即取反)的结
果,置1使某位为ห้องสมุดไป่ตู้,置0不影响原来的值
这样,BSRR寄存器的值就是00000000101010100000000001010101,
两部分的高8位均为0,所以不会影响到IO口的高8位
总结,以下的宏实现对某端口的低8位置数,不影响高8位:
STM32的IO端口高8位或低8位单独操作方法
几天前刚接触stm32的时候,被单独操作IO口给弄糊涂了,现记录下,现
在发现其实蛮简单的,只是刚开始的时候~~~
stm32的IO端口都是16位的,如果要单独操作某高8位或低8位,则不
是那幺简单,先看两张BSRR/BRR寄存器的图:
据官方数据手册上面说,这两个寄存器用于专门对ODR进行原子操作的
#defineGPIO_WriteLow(GPIOx,a)GPIOx-
>BSRR=(((uint32_t)(uint8_t)~(a))BSRR=(((uint8_t)(uint8_t)~(a))BSRR=value的
形式,所以担心是多余的
当然了,使用下面2,3的两个宏也可以完全该清零操作~stm32固件库是不
是应该加上这两个宏/函数?
stm32串口调参数

stm32串口调参数串口调参数是指在使用STM32单片机进行串口通信时,需要通过设置一系列参数来控制串口的工作方式。
下面将详细介绍调整这些参数的方法:1. 总线速率(Baud Rate):通过修改USART_CR1寄存器的USART_CR1_BR位来设置串口的波特率。
BR通常是一个由APB1总线频率和所需波特率计算得出的值。
例如,如果APB1总线频率为72MHz,希望设置波特率为9600,那么BR的计算公式为:BR=APB1总线频率/所需波特率BR=72MHz/9600=7500通过设置USART_BRR寄存器的USART_BRR_DIV位为BR来实现调整。
2. 数据位长度(Data Bits):STM32单片机的USART_CR1寄存器的USART_CR1_M位用于设置数据位长度。
有两个选项可供选择:8位和9位。
3. 校验位(Parity Bits):STM32单片机的USART_CR1寄存器的USART_CR1_PCE位用于启用或禁用校验位。
如果启用校验位,还需要根据实际情况选择奇校验还是偶校验。
4. 停止位长度(Stop Bits):STM32单片机的USART_CR2寄存器的USART_CR2_STOP位用于设置停止位长度。
有两个选项可供选择:1位和2位。
5. 硬件流控制(Hardware Flow Control):如果需要使用硬件流控制,可以设置STM32单片机的USART_CR3寄存器的USART_CR3_RTSE、USART_CR3_CTSE和USART_CR3_CTSIE位。
6.中断控制:STM32单片机的USART_CR1寄存器的USART_CR1_TXEIE和USART_CR1_RXNEIE位可用于使能或禁用发送和接收中断。
7.DMA控制:STM32单片机的USART_CR3寄存器的USART_CR3_DMAT和USART_CR3_DMAR位可用于使能或禁用DMA传输。
调整这些参数的步骤如下:1.初始化串口:配置引脚,设置GPIO模式为复用模式,选择对应的复用功能映射,然后初始化USART控制器。
STM32寄存器操作举例

那么很明显,只可能是 GPIOx_CRL GPIOx_CRH , GPIOx_ODR 三个寄存器会有想要 仔细阅读这几个寄存器的介绍后知道,GPIOx_CRL 是控制 PIN 0-7 的属性的,GPIOx_CRH 控制 PIN 8-15, ODR 寄存器 当然就是输出数据了,将数据送到这里就行了。
然后,这几个寄存器的地址是多少?首先看 stm32f103ve.pdf 这个是官方的 datasheet、,看第四章, Mmeory Mapping 为什么看这章?会英文都能猜到吧?,看 PORTB 的地址是 0x40010C00 - 0x40010FFF ,这个就是基地 址了。基地址 加上偏移量就能找到具体的寄存器。
typedef struct {
__IO uint32_t CRL; __IO uint32_t CRH; __IO uint32_t IDR; __IO uint32_t ODR; __IO uint32_t BSRR; __IO uint32_t BRR; __IO uint32_t LCKR; } GPIO_TypeDef;
以结构体指针的形式传递 IO 口 GPIO_TypeDef* GPIOx
访问 CRL 寄存器则用成员的形式 GPIOx->CRL;
不需要担心这样做的效率,因为都是地址,也就是指针,最终的效率是直接寄存器操作,效率是非常高的。
看不懂库函数,归根究底就是 C 语言功底不行。不要以为写过几行 51 就懂 C 语言了,远的很呢。
} } 如果将寄存器做一个定义,则程序变成如下
#define RCC_APB2ENR *(volatile unsigned long *)0x40021018 #define GPIOB_CRL *(volatile unsigned long *)0x40010C00 #define GPIOB_ODR *(volatile unsigned long *)0x40010C0C
STM32GPIO相关寄存器

STM32 GPIO 相关寄存器每个GPIO端口有两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH)分别控制每个端口的高八位和低八位,如果IO口是0-7号的话,则写CRL寄存器,如果IO口是8-15号的话,则写CRH寄存器,两个32位数据寄存器(GPIOx_IDR,GPIOx_ODR)一个是只读作输入数据寄存器,一个是只写作输出寄存器,一个32位置位/复位寄存器(GPIOx_BSRR),一个16位复位寄存器(GPIOx_BRR)和一个32位锁定寄存器(GPIOx_LCKR)。
常用的IO端口寄存器只有四个:CRH,CRL,IDR,ODR.数据手册中列出的每个I/O端口的特定硬件特征, GPIO端口的每个位可以由软件分别配置成多种模式。
每个I/O端口位可以自由编程,然而I/0端口寄存器必须按32位字被访问(不允许半字或字节访问)。
另外,STM32的每个端口使用前都要将其时钟使能,STM32的GPIO的时钟统一挂接在APB2上,具体的使能寄存器为RCC_APB2ENR,该寄存器的第2位到第8位分别控制GPIOx(x=A,B,C,D,E,F,G)端口的时钟使能,当外设时钟没有启用时,程序不能读出外设寄存器的数值,如打开PORTA 时钟:RCC—>APB2ENR|=1〈<2; //使能PORTA时钟使能外设时钟后,GPIOA的十六位就可以按照设定的状态工作了,之后就是具体设置哪一位了以第八位为例即高位的首位,在GPIOx_CRH寄存器中进行设置,GPIOA的每一位都有该寄存器的四位来设定相应的参数,这四位中的高两位(CNF0,CNF1)设置GPIO的输入输出模式,低两位(MODE0,MODE1)是设置GPIO的输出频率,具体可以参考STM32参考手册。
GPIOA->CRH&=0XFFFFFFF0; //清掉PA8原来的设置,同时屏蔽其它端口,不影响其它端口的设置GPIOA—〉CRH|=0X00000003;//PA8 推挽输出十六进制中的3 换成二进制 00 11 前两位00表示推挽输出,11代表输出频率50Mhz,若CRH|=0x4,表示模拟输入模式(ADC用),0x3表示推挽输出模式(作输出口用,50M速率),0x8表示上/下拉输入模式(做输入口用),0xB表示复用输出(使用IO口的第二功能,50M速率). 这是对一位的操作,当然也可以多位操作,因为STM32对GPIO操作必须是32位全字操作,设置完成后GPIOA的第8位就可以使用了之后给GPIOA—>ODR=0x xxxx xxxx送数据就行了。
STM32 GPIO教程

系统外设
GPIO特性
最大封装(64引脚)上多达55个多功能双向GPIO(GPIO 引脚占有率相比STM32F1系列的80%更增加到86%) 几乎所有GPIO都是5V容忍(ADC引脚除外) GPIO分布在5个端口上:GPIOA[0~15]、GPIOB[0~15]、 GPIOC[0~15]、GPIOD[0~2]、GPIOF[4~7] 使用BSRR和BRR寄存器可以完成对引脚的原子置位和 复位操作 GPIO连在AHB总线,使得最高翻转速度高达12MHz 输出斜率可配置,高达50MHz 端口A和B上的引脚配置可通过LCKR寄存器锁定 55个引脚都可以配置成外部中断(可同时使能16个) 来把MCU从停止模式唤醒
I2C1端口支持1MHz超快速总线【FTf】
PB6/7 (I2C1_SCL/SDA) PB8/9 (I2C1_SCL/SDA)
其余端口都是5V容忍【FT】
10
Quiz
How many I/Os and ports there are in the STM32F0xx microcontroller ? ____________
可编程复用开关使得任意时刻只有一个外设连到 某个具体的GPIO。只有GPIOA和GPIOB有复用开关 某些外设功能还可以重映射到其他引脚,从而使 得能同时使用的外设数量更多
AF0 (SPI1_MISO) AF1 (TIM3_CH1) AF2 (TIM1_BKIN) Pin x (0…7)
AF7 (COMP1_OUT)
Output Driver
VSS
Push-Pull Open Drain
* In output mode, the I/O speed is configurable through OSPEEDR register: 2MHz, 10MHz or 50MHz
stm32 io速度寄存器调节原理

一、STM32 IO速度寄存器调节原理1.1 STM32 IO口的速度控制在STM32单片机中,IO口的速度可以通过设置速度寄存器来进行调节,这个寄存器就是GPIOx_OSPEEDR,其中GPIOx代表GPIO的端口号。
每个IO口都有一个相对应的速度寄存器来控制其输出速度。
1.2 寄存器的结构GPIOx_OSPEEDR寄存器的结构如下:```Bit 1:0 MODE0[1:0]: port x mode bits (y = 0..15)These bits are written by software to configure the I/O driving capability.00: Low speed01: Medium speed10: High speed11: Very high speed```可以看到,这个寄存器有16位,每两位用来控制一个IO口的速度,可以选择低速、中速、高速和超高速四种速度之一。
1.3 寄存器的设置方法在使用STM32单片机时,可以通过设置这个寄存器来控制每个IO口的输出速度。
如果需要配置GPIOA的第5个引脚为高速输出,可以按照下面的方法来设置:```GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR5; //设置为高速输出```1.4 寄存器的作用速度寄存器的主要作用是为了调节IO口的输出速度,通过设置不同的速度模式,可以满足不同的外设对IO口输出速度的要求。
在实际应用中,可以根据外设的要求来调节IO口的速度,以达到最佳的性能和稳定性。
1.5 寄存器的注意事项在使用速度寄存器时,需要注意以下几点:- 不同的外设对IO口的速度要求不同,需要根据具体外设的要求来设置速度寄存器。
- 不同的引脚设置可能影响整个外设的工作速度,需要综合考虑整个外设的速度要求来设置速度寄存器。
二、总结通过设置速度寄存器,可以灵活地控制STM32单片机的IO口输出速度,满足不同外设对IO口速度的要求,提高系统的稳定性和性能。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
STM32使用BSRR和BRR寄存器快速操作
GPI0端口STM32的每个GPIO端口都有两个特别的寄存器,GPIOx_BSR和GPIOx_BRF寄存器,通过这两个寄存器可以直接对对应的GPIOx端口置“或置“ 0。
“
GPIOx_BSRR勺高16位中每一位对应端口x的每个位,对高16位中的某位置“狈『端口x的对应位被清“0;“寄存器中的位置“0, “则对它对应的位不起作
用。
GPIOx_BSRR的氐16位中每一位也对应端口x的每个位,对低16位中的某位置“1则“它对应的端口位被置“1;“寄存器中的位置“0,“则对它对应的端口不起作用。
简单地说GPIOx_BSR的高16位称作清除寄存器,而GPIOx_BSR的低氐16 位称作设置寄存器。
另一个寄存器GPIOx_BRfl只有低16位有用,与GPIOx_BSR 的高16位具有相同功能。
举个例子说明如何使用这两个寄存器和所体现的优势。
例如GPIOE的16个IO都被设置成输出,而每次操作仅需要改变低8位的数据而保持高8位不变,假设新的8 位数据在变量Newdata 中,
这个要求可以通过操作这两个寄存器实现,STM32的固件库中有两个函数GPIO_SetBits和GPIO_ResetBits使用了这两个寄存器操作端口。
上述要求可以这样实现:
GPI0_SetBits(GPI0E, Newdata & 0xff);
GPI0_ResetBits(GPI0E, (~Newdata & 0xff));
也可以直接操作这两个寄存器:
GPI0E->BSRR = Newdata & 0xff;
GPI0E->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 | 0x8(置/ “1 “
GPIOE->ODR = GPIOE->ODR & 0xFF7置〃'0 “
有人问是否BSRR的高16位是多余的,请看下面这个例子:
假如你想在一个操作中对GPIOE的位7置“ 1, “位6置“0, “则使用BSRF 非常便当:GPIOE->BSRR = 0x4080;
如果没有BSRR的高16位,则要分2次操作,结果造成位7和位6的变化不同步!GPIOE->BSRR = 0x80;
GPIOE->BRR = 0x40;。