STM32GPIO寄存器CRL、CRH、IDR、ODR、BSRR、BRR

2024-04-20 17:48

本文主要是介绍STM32GPIO寄存器CRL、CRH、IDR、ODR、BSRR、BRR,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

GPIO 寄存器描述

注意:本文以STM32F10XXX为参考,重在理解

CRL与CRH

CRL与CRH分别为端口配置低与端口配置高寄存器,为32位寄存器,其中每四位控制一个I/O口

在这里插入图片描述

对CNFy与MODEy(y=0,1,2…7)位写1或0控制I/O口的输入输出模式
在这里插入图片描述

STM32I/O口都是16位的,CRL与CRH分别控制低8位与高8位,两个寄存器的用法与功能完全一模一样,下面来几个例子就明白了

e.g.PD1配置为推挽输出,最大速度50MHz

GPIOD->CRL=3<<4

新手注释:上方代码是对GPIOD_CRL寄存器左移4位再(即从第5位开始从右往左,前4位补0)写0011(至于为何写0011看上表),换算成十六进制就是0x0000 0030,如果还不理解(我只能说:唉!)可以在换成二进制看看

e.g.PC10配置为复用推挽输出,最大速度2MHz

GPIOC->CRH=0xA<<8

新手注释:0x为十六进制格式,A表示十进制10,换成二进制就是1010,聪明的你肯定明白了

问:“GPIOC-CRH”是什么意思?

答:表示GPIOC_CRH这一寄存器

问:GPIOC->CRH|=0X00038000 中"|"是什么意思?

答:“|”表示算术“或”,“1|1=1”,“1|0=1”,“0|0=0”
上方代码中“|”的作用是:在不影响其他I\O口的情况下仅对PC11、PC12进行配置
比如PC8、PC9已经配置好了,但你可能不知道配置的具体模式或者是懒得搭理,只晓得他两已经在用了,这时你又要对PC11、PC12进行配置,假设GPIOC_CRH寄存器的值已经为0x4444 44yy,此时GPIOC->CRH|=0X00038000就表示将0x4444 44yy|0x0003 8000的值写入寄存器,也就是将0x4447 C4yy写入GPIOC_CRH寄存器

IDR与ODR

IDR与ODR分别为输入与输出数据寄存器,即下图中的玩意儿
在这里插入图片描述

从图中也可以看到IDR只能读,而ODR可读可写,这两个寄存器的0与1分别反映了I/O口的低与高电平状态,IDR十分简单,ODR对应位写0或1可以控制I/O的状态,后面会详说

BSRR与BRR

BSRR与BRR分别叫做端口置位/复位、端口复位寄存器(有点蒙!!不怕)

BSRR为端口置位/复位寄存器,置位就是高电平、复位也就是低电平,这玩意是个32位寄存器,低16位控制置位、高16位控制复位

在这里插入图片描述

BRR为端口复位寄存器,这玩意虽然也是个32位寄存器但只有低16位可操作

在这里插入图片描述

注意:这两个寄存器的对应位只能写1有效

聪明的你肯定已经想到了:BSRR高16位与BRR功能完全一致

纳尼!为什么会有这种鸡肋的操作?

其实意法设置这两个寄存器还是有一定道理的,比如:

要求PC3输出高电平,PC5输出低电平

方法一:

GPIOC->BRSS|=1<<3

GPIOC->BRR|=1<<5

方法二:

GPIOC->BRSS|=(1<<3)|(1<<21)

两种方法虽然殊途同归,但重要的是方法一会导致PC3、PC5的电平变化不同步,方法二则可避免这一问题

再如:PC3输出高电平,PC端口其余引脚输出低电平

GPIOC->BRSS|=(1<<3)|((~(1<<3)&0xff)<<16)

用一句代码就能解决,但貌似对不太熟悉位操作的朋友有点复杂,多练练就好(套路)

看到这的朋友就可能会问前面的ODR既然可以控制I/O的高低电平,为什么还要BSRR、BRR这两个玩意!

这个我还不太明白,后续弄懂了再来说

但意法给了以下比较懵懂的答案

在这里插入图片描述

他的意思就是说在使用BSRR与BRR寄存器操作时不会与中断产生冲突,也就不会丢失中断事件,而使用ODR则会存在这一风险

加油!拼命干才会百分百成功,下一篇再见!

下一篇:STM32I/O口配置上拉下拉输入寄存器版

这篇关于STM32GPIO寄存器CRL、CRH、IDR、ODR、BSRR、BRR的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/920929

相关文章

寄存器B

MCS-51单片机的中央处理器包含运算部件和控制部件两部分。         1. 运算部件         运算部件以算术逻辑运算单元ALU为核心,包含累加器ACC、B寄存器、暂存器、标志寄存器PSW等许多部件,它能实现算术运算、逻辑运算、位运算、数据传输等处理。         算术逻辑运算单元ALU是一个8位的运算器,它不仅可以完成8位二进制数据加、减、乘、除等基本的算

士兰微 SC32F5432 通过配置寄存器方式 将管脚配成开漏输出模式和TTL输入模式

目录 前言: 士兰微电子介绍 士兰微 SC32F5432介绍 士兰微 SC32F5432 通过配置寄存器方式 将管脚配成开漏输出模式和TTL输入模式 开漏输出模式 TTL输入模式 前言: 下面是对我在工作时公司所使用的一款国产芯片(士兰微 SC32F5432)开发过程所遇到的一些问题的记录与解决。 士兰微电子介绍 杭州士兰微电子股份有限公司(600460)坐落于杭州

笔记 14 : 彭老师课本第 8 章, UART : 寄存器介绍 ,

(99) 继续介绍 uart 的关于通道的 一整套 寄存器, UCON 等: ++ 接着介绍寄存器 UTRSTAT : ++ 接着介绍读写数据的寄存器: ++ 设置 uart 的波特率,有关的寄存器: ++ (100) (101) 谢谢

AUXR-特殊功能寄存器(只写)

AUXR : Auxiliary Register(只写) MnemonicAddbitB7B6B5B4B3B2B1B0Reset ValueAUXR8EHname -  -  - - - -EXTRAMALEOFFxxxx,xx00 禁止ALE信号输出(应用示例供参考,C语言):sfr AUXR = 0x8e; //声明AUXR寄存器的地址AUXR = 0x01;//ALEOFF位置1

FPGA编程基础(一)--参数传递与寄存器使用

一、参数映射 参数映射的功能就是实现参数化元件。所谓的”参数化元件“就是指元件的某些参数是可调的,通过调整这些参数从而可实现一类结构类似而功能不同的电路。在应用中,很多电路都可采用参数映射来达到统一设计,如计数器、分频器、不同位宽的加法器以及不同刷新频率的VGA视频接口驱动电路等。 参数传递 参数传递就是在编译时对参数重新赋值而改变其值。传递的参数是子模块中定义的parameter,其传递方

【软件逆向】第38课,软件逆向安全工程师之操作标志寄存器实例,每天5分钟学习逆向吧!

在这些实例学习中,我们使用汇编指令来操作标志寄存器,并根据标志寄存器的状态进行条件分支。这些操作对于编写高效的汇编程序以及理解程序的行为至关重要 实例 1:使用 PUSHF 和 POPF 保存和恢复标志寄存器状态 section .text global _start _start: ; 初始化 AL 寄存器 MOV AL, 0xFF ; 对 AL 寄存器进行加一操作,这将导致 AL 寄存器的

新路程------hi3516a 在应用层对寄存器的操作

由于在应用层没法用writel,所以参考himm.c写了一个设置,代码如下: void uart1_rtsn_high(void) {     void * pMem  = NULL;   pMem = memmap(0x201d0010, DEFAULT_MD_LEN);   *(U32*)pMem = 0xff; } 文件名是rs485.c,但是用arm-hisiv300-linux

【软件逆向】第30课,软件逆向安全工程师之(五)寄存器相对寻址,每天5分钟学习逆向吧!

寄存器相对寻址是汇编语言中的一种寻址方式,它结合了寄存器间接寻址和立即数偏移。在这种寻址方式中,操作数的有效地址是通过将一个寄存器的内容与一个固定的偏移量(立即数)相加来得到的。以下是关于寄存器相对寻址的详细信息: 寄存器相对寻址的特点: 操作数地址是寄存器内容与偏移量的和:有效地址是寄存器的内容加上一个固定的立即数偏移量。灵活且具体:提供了对特定内存位置的间接访问,同时允许通过改变寄存器的内

RTC(实时时钟)/BKP(备份寄存器

1 unix时间戳 2 时间戳转换函数 3  BKP(备份寄存器) 1 TAMPER引脚侵入事件  2  RTC校准时间 3 RST闹钟脉冲和秒脉冲         可以输出出来为其他信号提供  4 校准时钟,寄存器加输出RTC校准时钟   5 总结:3个功能只能同时使用一个 4 BKP基本结构 5  RTC框图   6  RTC硬件电路

【软件逆向】第27课,软件逆向安全工程师之(二)寄存器寻址,每天5分钟学习逆向吧!

寄存器寻址是汇编语言中的一种寻址方式,在这种方式中,操作数位于CPU的寄存器中。寄存器是CPU内部的高速存储位置,用于快速访问数据。以下是关于寄存器寻址的详细信息: 寄存器寻址的特点: 操作数在寄存器中:数据直接存储在寄存器中,而不是内存地址或立即数。快速访问:由于寄存器位于CPU内部,因此访问速度远快于内存。指令简短:使用寄存器寻址的指令通常较短,因为不需要指定内存地址。 识别寄存器寻址: