(注:此为乐某学习记录,若有出错的地方欢迎各位指出!)
本人使用的开发板的芯片是STM32H743XIH6,所以也是根据此芯片来进行操作。
在STM32的学习过程里面,大部分人最开始应该都是学习标准库版本的,对于寄存器操作应该都不太了解。百度百科对于寄存器的介绍,寄存器是CPU内部用来存放数据的一些小型存储区域,用来暂时存放参与运算的数据和运算结果。
简单的理解为,一个存放了东西的东西。只不过,里面存放的是某些数据或者指令。就像你身份证号,代表了你的省份、城市、县区等等。如果想要找到你,对你做某件事或者获取一些东西,就会根据你的身份证号,找到你的所在地。这些操作,对于寄存器来说,称为读和写。
对于寄存器的读操作来说,就是你想要获取寄存器的数据,那么就需要找到这个寄存器,然后直接读数据多少即可,这也叫访问寄存器。
对于寄存器的写操作来说,就是你想要修改寄存器的数据,那么就需要找到这个寄存器,然后直接将数据写在寄存器里,这也叫写寄存器。
现在我们已经知道了读写操作,但是寄存器这么多,怎么找到我们想要的寄存器呢?怎么去区分它们呢?这就要引用C语言的一个操作,指针和&的使用,想在窗口控制台输入一个变量,是不是要用到scanf这个语句?那这个&符号的作用,就是取这个变量的地址!不同的寄存器,地址也就不一样,所以想要找到对应的寄存器,我们就找到对应的地址就行了!就像前面讲的身份证号,你可能四处旅游,想通过身份证号找到你可能有点困难,但是在STM32芯片里就不同,每一个寄存器的地址都在芯片出厂的时候就已经分配了!
我们打开参考手册,看到存储器和总线架构这一章,往下滑就可以看到寄存器的边界地址。
例如,我们想要打开GPIOB的时钟,我们就要找到RCC的这一栏。由下图可看出,只要是和RCC相关的,都在0x58024400-0x580247FF这一区间。
然后,我们就要打开芯片的数据手册,找到我们的GPIOB的时钟挂在哪一条总线上。由下图可看出,GPIOA~GPIOK都挂在AHB4总线上。
我们再回到参考手册的RCC寄存器说明,可以看到好几个和AHB4相关的寄存器。我们只需要看到RCC_AHB4ENR,实际上这里应该叫做时钟使能寄存器。
看到寄存器开头的介绍,里面是有两个偏移地址的,我两个都使用过,同样可行。我们找到了这个偏移地址后,RCC_AHB4ENR的地址就是0x58024400+0xE0;
这里我们需要掌握位操作,C语言有以下6个位操作符。
位操作符 |
名称 |
& |
按位与 |
| |
按位或 |
^ |
按位异或 |
~ |
按位取反 |
<< |
按位左移 |
>> |
按位右移 |
按位与(&):同一位上,同样为1,&的结果就为1,只要有一个0或者两个都是0,结果就为0;
按位或(|):同一位上,只要有一个为1,|的结果就为1,两个都是0,则结果就为0;
按位异或(^):同一位上,两个不相同则为1,相同则为0;
按位取反(~):将结果取反,1为0,0为1;
按位左移(<<):运算符左边的运算量全部向左边移动运算符右边的运算量,高位舍弃,低位补0;
按位右移(>>):运算符左边的运算量全部向右边移动运算符右边的运算量,高位补0,低位舍弃;
我们已经了解位操作,也会查找寄存器的地址后,看到寄存器的位说明,在这一位置位,即可使能GPIOB的时钟。
代码里我使用了宏定义来操作,但是,这些宏在我们看来是寄存器的地址,但是在编译器看来,这只是一个普通的变量,所以我们要让编译器也要让它认为是一个指针也就是地址,我们就得进行强制类型转换,把它转换成uint32_t类型的指针,然后对这个指针进行解引用操作也就是*操作。这样下来,我们就完成了GPIOB的时钟使能啦!
uint32_t *pAHB4_Addr = (uint32_t *)(RCC_START_ADDR + RCC_AHB4_OFFEST); //RCC->AHB4ENR
*pAHB4_Addr |= (0x01 << 1); //开启GPIOB时钟
直接访问的操作非常的麻烦,每操作一个寄存器就必须去查看数据手册,然后找找这个寄存器的地址。 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