这是凯文的学习记录和学习心得分享,欢迎大佬、大牛在线调教、指导。
——共同学习共同进步,知行合一
灵活好用的的结构体
结构体(Structure)映射寄存器
关键字:struct
在C语言的程序开发中,往往我们需要用到面向对象的编程思路,也学对于我们从事电子、嵌入式工作的新人来说,一些使用的方法应用的很少。我分享自己在对底层驱动BSP函数进行封装过程中的心得:
使用技巧,用如下方法可以简化结构体定义:
常用格式
Typedef Struct {
变量类型 结构体成员变量A;
变量类型 结构体成员变量B;
.......
变量类型 结构体成员变量N;
}name_typedef;
以ST官方提供的库函数对结构体的应用为例如下:
//example SysTick_struct define SysTick时钟相关结构体变量定义,并将寄存器映射到地址,过程如下:
Typedef struct {
__IO uint32_t CTRL;
__IO uint32_t LOAD;
__IO uint32_t VAL;
__I uint32_t CALIB;
}SysTick_Typedef;
通过以上结构体,便把SysTick时钟相关的寄存器关联了起来。
//System Control Space Base Address 系统控制空间基地址的值
#define SCS_BASE (0xE000E000UL)
//SysTick Base Address 滴答时钟基地址值,相对SCS地址偏移 0x0010UL
#define SysTick_BASE (SCS_BASE + 0x0010UL)
//SysTick configuration struct SysTick 结构体配置
#define SysTick ((SysTick_Type *) SysTick_BASE )
分析:
映射过程中,定义了 SysTick_Typedef 结构体类型、SCS_BASE 基地址值、SysTick_BASE 滴答时钟基地址值。
只要通过(((SysTick_Type *) SysTick_BASE ),便可把SysTick_BASE的值强制转换成 地址(即指针),并映射到SysTick_Type的结构体类型,由于结构体地址是顺序排列的,便将底层寄存器和库函数封装联系起来了。
((SysTick_Type *) SysTick_BASE ) 这句话,是把滴答时钟基地址强制转换为结构体指针,用 SysTick 宏以下,那么SysTick 就是SysTick_Typedef的结构体指针了,那么只要操作 SysTick 便可以直接操作 结构体成员变量了,并且SysTick地址为SCS_BASE + 0x0010UL。
思考:
首先,结构体变量地址是正常递增的,CTRL 是 0x00 ,那么LOAD便是0x04(为什么呢?仔细揣摩后发现,由于变量定义时是定义的int型32位,一个地址里面可以放8位数据,通过查数据手册,这几个寄存器也是32位哈哈),依次类推。
其次,通过((SysTick_Type *) SysTick_BASE ) 这句话是把SysTick_BASE强制转换为结构体指针变量,那么结构体里的结构体变量便和寄存器地址映射起来了!
即 SysTick_BASE 地址为 SCS_BASE + 0x0010UL
SysTick_CTRL; 地址为 SCS_BASE + 0x0010UL + 0x00
SysTick_LOAD; 地址为 SCS_BASE + 0x0010UL + 0x04
SysTick_VAL; 地址为 SCS_BASE + 0x0010UL + 0x08
SysTick_CALIB;地址为 SCS_BASE + 0x0010UL + 0x0C
那么对 SysTick 这个结构体指针的操作,就是我们熟悉的STM32寄存器操作了,相关寄存器进行配置操作便可以如下方法:
- SysTick