引言
在上次笔记使用 C 语言编写 LED 灯驱动的时候,每个寄存器的地址我们都需要写宏定义,使用起来非常的不方便。我们在学习 STM32 的时候,可以使用“ GPIOB->ODR ”这种方式来给 GPIOB 的寄存器 ODR 赋值,因为在 STM32 中同属于一个外设的所有寄存器地址基本是相邻的(有些会有保留寄存器)。因此我们可以借助 C 语言里面的结构体成员地址递增的特点来将某个外设的所有寄存器写入到一个结构体里面,然后定义一个结构体指针指向这个外设的寄存器基地址,这样我们就可以通过这个结构体指针来访问这个外设的所有寄存器。同理,I.MX6U 也可以使用这种方法来定义外设寄存器。
4.1.2 I.MX6U 寄存器定义
参考
STM32
的官方文件来编写
I.MX6U
的寄存器定义,比如
IO
复用寄存器组
“IOMUX_SW_MUX_CTL_PAD_
XX
”,步骤如下:
1
、编写外设结构体
先将同属于一个外设的所有寄存器编写到一个结构体里面,如 IO
复用寄存器组的结构体如下:
/*
* IOMUX
寄存器组
*/
1
typedef
struct
2
{
3
volatile unsigned int
BOOT_MODE0
;
4
volatile unsigned int
BOOT_MODE1
;
5
volatile unsigned int
SNVS_TAMPER0
;
6
volatile unsigned int
SNVS_TAMPER1
;
………
107
volatile unsigned int
CSI_DATA00
;
108
volatile unsigned int
CSI_DATA01
;
109
volatile unsigned int
CSI_DATA02
;
110
volatile unsigned int
CSI_DATA03
;
111
volatile unsigned int
CSI_DATA04
;
112
volatile unsigned int
CSI_DATA05
;
113
volatile unsigned int
CSI_DATA06
;
114
volatile unsigned int
CSI_DATA07
;
/*
为了缩短代码,其余
IO
复用寄存器省略
*/
115
}
IOMUX_SW_MUX_Tpye
;
上述结构体
IOMUX_SW_MUX_Type
就是
IO
复用寄存器组,成员变量是每个
IO
对应的复用寄存器,每个寄存器的地址是 32
位,每个成员都使用“
volatile
”进行了修饰,目的是防止编译器优化。
2
、定义
IO
复用寄存器组的基地址
根据结构体 IOMUX_SW_MUX_Type
的定义,其第一个成员变量为
BOOT_MODE0
,也就是 BOOT_MODE0
这个
IO
的
IO
复用寄存器,查找
I.MX6U
的参考手册可以得知其地址为0X020E0014,所以
IO
复用寄存器组的基地址就是
0X020E0014
,定义如下:
#define IOMUX_SW_MUX_BASE (0X020E0014)
3
、定义访问指针
访问指针定义如下:
#define IOMUX_SW_MUX ((IOMUX_SW_MUX_Type *)IOMUX_SW_MUX_BASE)
通过上面三步我们就可以通过“IOMUX_SW_MUX->GPIO1_IO03
”来访问
GPIO1_IO03
的IO 复用寄存器了。同样的,其他的外设寄存器都可以通过这三步来定义。下次笔记将详细介绍代码内容。