关于STM32的寄存器操作学习

(注:此为乐某学习记录,若有出错的地方欢迎各位指出!)

前言

本人使用的开发板的芯片是STM32H743XIH6,所以也是根据此芯片来进行操作。

一、寄存器

在STM32的学习过程里面,大部分人最开始应该都是学习标准库版本的,对于寄存器操作应该都不太了解。百度百科对于寄存器的介绍,寄存器是CPU内部用来存放数据的一些小型存储区域,用来暂时存放参与运算的数据和运算结果。

简单的理解为,一个存放了东西的东西。只不过,里面存放的是某些数据或者指令。就像你身份证号,代表了你的省份、城市、县区等等。如果想要找到你,对你做某件事或者获取一些东西,就会根据你的身份证号,找到你的所在地。这些操作,对于寄存器来说,称为读和写。

对于寄存器的读操作来说,就是你想要获取寄存器的数据,那么就需要找到这个寄存器,然后直接读数据多少即可,这也叫访问寄存器。

对于寄存器的写操作来说,就是你想要修改寄存器的数据,那么就需要找到这个寄存器,然后直接将数据写在寄存器里,这也叫写寄存器。

现在我们已经知道了读写操作,但是寄存器这么多,怎么找到我们想要的寄存器呢?怎么去区分它们呢?这就要引用C语言的一个操作,指针和&的使用,想在窗口控制台输入一个变量,是不是要用到scanf这个语句?那这个&符号的作用,就是取这个变量的地址!不同的寄存器,地址也就不一样,所以想要找到对应的寄存器,我们就找到对应的地址就行了!就像前面讲的身份证号,你可能四处旅游,想通过身份证号找到你可能有点困难,但是在STM32芯片里就不同,每一个寄存器的地址都在芯片出厂的时候就已经分配了!

二、怎么找到寄存器的地址?

我们打开参考手册,看到存储器和总线架构这一章,往下滑就可以看到寄存器的边界地址。

关于STM32的寄存器操作学习_第1张图片

例如,我们想要打开GPIOB的时钟,我们就要找到RCC的这一栏。由下图可看出,只要是和RCC相关的,都在0x58024400-0x580247FF这一区间。

然后,我们就要打开芯片的数据手册,找到我们的GPIOB的时钟挂在哪一条总线上。由下图可看出,GPIOA~GPIOK都挂在AHB4总线上。

关于STM32的寄存器操作学习_第2张图片

我们再回到参考手册的RCC寄存器说明,可以看到好几个和AHB4相关的寄存器。我们只需要看到RCC_AHB4ENR,实际上这里应该叫做时钟使能寄存器。

关于STM32的寄存器操作学习_第3张图片

看到寄存器开头的介绍,里面是有两个偏移地址的,我两个都使用过,同样可行。我们找到了这个偏移地址后,RCC_AHB4ENR的地址就是0x58024400+0xE0;

关于STM32的寄存器操作学习_第4张图片

三、怎么对寄存器的位进行操作?

这里我们需要掌握位操作,C语言有以下6个位操作符。

位操作符

名称

&

按位与

|

按位或

^

按位异或

~

按位取反

<<

按位左移

>>

按位右移

按位与(&):同一位上,同样为1,&的结果就为1,只要有一个0或者两个都是0,结果就为0;

按位或(|):同一位上,只要有一个为1,|的结果就为1,两个都是0,则结果就为0;

按位异或(^):同一位上,两个不相同则为1,相同则为0;

按位取反(~):将结果取反,1为0,0为1;

按位左移(<<):运算符左边的运算量全部向左边移动运算符右边的运算量,高位舍弃,低位补0;

按位右移(>>):运算符左边的运算量全部向右边移动运算符右边的运算量,高位补0,低位舍弃;

我们已经了解位操作,也会查找寄存器的地址后,看到寄存器的位说明,在这一位置位,即可使能GPIOB的时钟。

关于STM32的寄存器操作学习_第5张图片

1、寄存器的直接操作

代码里我使用了宏定义来操作,但是,这些宏在我们看来是寄存器的地址,但是在编译器看来,这只是一个普通的变量,所以我们要让编译器也要让它认为是一个指针也就是地址,我们就得进行强制类型转换,把它转换成uint32_t类型的指针,然后对这个指针进行解引用操作也就是*操作。这样下来,我们就完成了GPIOB的时钟使能啦!

uint32_t *pAHB4_Addr = (uint32_t *)(RCC_START_ADDR + RCC_AHB4_OFFEST);    //RCC->AHB4ENR
*pAHB4_Addr |= (0x01 << 1);    //开启GPIOB时钟

2、寄存器地址映射

直接访问的操作非常的麻烦,每操作一个寄存器就必须去查看数据手册,然后找找这个寄存器的地址。 ST官方专门在一个.h文件里面,做好了寄存器的地址映射,我的是stm32h743xx.h。下面就是使用映射的地址进行的GPIOB的时钟开启操作。

RCC->AHB4ENR |= (0x01 << 1);

总结

寄存器的操作,相对于标准库或者HAL库来说,会麻烦很多,但是操作是直接式的。在使用库的操作,需要知道函数的作用,然后知道要往里面填入什么变量即可,剩下的内容函数里已经帮你写好了。所以相对寄存器来说是非常省事的,而且填入不同的参数,也会去执行不同的操作,兼容性也很强。使用寄存器的话,可能当前的函数只能够符合当前的功能,如果要换其他的,可能又要重新写,重新去看寄存器的说明等等,要做成兼容其他功能的,又要重新写一个函数,相对库函数来说就非常费事了!

但是,如果在学习阶段,我还是非常建议学习寄存器操作的,这样对于芯片的外设会理解的比较深。库函数的话,也是可能会存在一些bug的,在学习过寄存器后再去学习库函数,就可以发现那些bug,并做出修复!

参考文章

yummy说电子:STM32寄存器的简介、地址查找,与直接操作寄存器

https://blog.csdn.net/geek_monkey/article/details/86291377?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167715960316800225526095%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=167715960316800225526095&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-10-86291377-null-null.blog_rank_default&utm_term=stm32%E5%AF%84%E5%AD%98%E5%99%A8%E7%BC%96%E7%A8%8B&spm=1018.2226.3001.4450

你可能感兴趣的:(stm32,单片机,学习)