说明:这里以GPIO外设为例,介绍C语言对寄存器的封装。以此类推其他外设同样可以用这种方法来封装。本文有两部分构成:
1、介绍宏定义。
2、使用结构体封装寄存器列表。
1、宏定义
以封装STM32 GPIOH为例:
STM32总线基地址:
![2](https://img-blog.csdnimg.cn/20210307173400867.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2phY2tKcnVpdA==,size_16,color_FFFFFF,t_70)
STM32GPIO基地址:
![2](https://img-blog.csdnimg.cn/20210307173600374.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2phY2tKcnVpdA==,size_16,color_FFFFFF,t_70)
STM32 GPIOH端口寄存器列表:
![3](https://img-blog.csdnimg.cn/20210307173742147.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2phY2tKcnVpdA==,size_16,color_FFFFFF,t_70)
所以我们先定义总线基地址,但是总线基地址是相对外设基地址的偏移,外设基地址又是总线APB1的地址,故可以先定义外设基地址:
#define PERIPH_BASE ((unsigned int))0X40000000 )de
而APB1、APB2、APH1、APH2总线定义可以 相对基地址的偏移去定义;
如APB2: APB2相对外设基地址的偏移是0X0001 0000(0X4001 0000 - 0X4000 0000),故可定义为:PERIPH_BASE +0X0001 0000.
#define APB2PERIPH_BASE ((PERIPH_BASE) + 0X0001 0000)
其他类似:
![5](https://img-blog.csdnimg.cn/2021030717412177.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2phY2tKcnVpdA==,size_16,color_FFFFFF,t_70)
举例
让PH10输出低/高电平,要怎么实现?
根据参考手册我们知道PH10引脚是由寄存器GPIO_ODR的第10位进行控制。
# #define PERIPH_BASE ((unsigned int))0X40000000 )
#define AHB2PERIPH_BASE (PERIPH_BASE + 0X00020000)
#define GPIOH_BASE (AHB2PERIPH_BASE + 0X1C00 )
#define GPIO_ODR *(unsigned int*)(GPIOH_BASE + 0X14)
GPIO_ODR & =~(1 << 10);
GPIO_ODR | =(1 << 10);
2、使用结构体封装寄存器列表
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210307181040722.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2phY2tKcnVpdA==,size_16,color_FFFFFF,t_70)
如图GPIOH_OTYPER相对GPIOH_MODER 偏移4字节,GPIOH_OSPEEDR相对GPIOH_OTYPER偏移4字节等寄存器。故可以用结构体封装。
![6](https://img-blog.csdnimg.cn/20210307181647979.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2phY2tKcnVpdA==,size_16,color_FFFFFF,t_70)
所以可以使用结构体指针访问寄存器
![7](https://img-blog.csdnimg.cn/20210307181758402.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2phY2tKcnVpdA==,size_16,color_FFFFFF,t_70)
所以所有的GPIO端口基地址都可以封装成如上所示:
![8](https://img-blog.csdnimg.cn/20210307182045347.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2phY2tKcnVpdA==,size_16,color_FFFFFF,t_70)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)