什么叫做外设数据化呢?在我们这里,外设数据化就是将寄存器地址用结构体来表示。现在不懂没关系我们会有实例。
一.外设数据化实例
我们在前面的章节中用到了很多的寄存器都是直接定义宏。很麻烦,每次都要自己定义每个寄存器地址。NXP提供了外设数据化表,我们先自己写一个外设数据化实例,然后就明白了这个表怎么用了。
#ifndef IMX6ULL_h
/*设置CCM基址*/
#define CCM_base 0x020C4068
/*定义CCM_type类型的结构体*/
/*注意地址是否连续,本例中地址连续所以没有保留项*/
typedef struct
{
volatile unsigned int CCM_CCGR0;
volatile unsigned int CCM_CCGR1;
volatile unsigned int CCM_CCGR2;
volatile unsigned int CCM_CCGR3;
volatile unsigned int CCM_CCGR4;
volatile unsigned int CCM_CCGR5;
volatile unsigned int CCM_CCGR6;
}CCM_type;
/*定义访问指针*/
/*CCM是CCM_type结构体的指针*/
#define CCM ((CCM_type*)CCM_base)
#endif // !IMX6ULL_h
/*外设数据化表的使用*/
#include "imx6ull.h"
int main(){
/*直接使用结构体成员赋值即可*/
CCM->CCM_CCGR0 = 0XFFFFffff;
CCM->CCM_CCGR1 = 0XFFFFffff;
CCM->CCM_CCGR2 = 0XFFFFffff;
CCM->CCM_CCGR3 = 0XFFFFffff;
CCM->CCM_CCGR4 = 0XFFFFffff;
CCM->CCM_CCGR5 = 0XFFFFffff;
CCM->CCM_CCGR6 = 0XFFFFffff;
return 0;
}
二.使用外设数据化表优化led驱动程序
#include "imx6ull.h"
//使能时钟
int enable_clock(){
CCM->CCGR0 = 0xffffffff;
CCM->CCGR1 = 0xffffffff;
CCM->CCGR2 = 0xffffffff;
CCM->CCGR3 = 0xffffffff;
CCM->CCGR4 = 0xffffffff;
CCM->CCGR5 = 0xffffffff;
CCM->CCGR6 = 0xffffffff;
return 0;
}
//设置复用功能和电器属性和输入输出
int led_init(){
IOMUX_SW_MUX->GPIO1_IO03 = 0x5;
IOMUX_SW_PAD->GPIO1_IO03 = 0x000010B0;
GPIO1->GDIR = 0x8;
GPIO1->DR &= ~(1<<3);
return 0;
}
void led_on(){
GPIO1->DR &= ~(1<<3);
}
void led_off(){
GPIO1->DR |= 1<<3;
}
//一个短的延时
void delay_short(volatile unsigned int n){
while (n--) {}
}
//大约n ms的延时
void delay(int n){
while (n--){
delay_short(0x7ff);
}
}
int main(void){
//使能时钟
enable_clock();
//设置复用功能和电器属性和输入输出
led_init();
while (1)
{
led_on();
delay(500);
led_off();
delay(500);
}
return 0;
}
总结
本节我们借助 C 语言里面的结构体成员地址递增的特点来将某个外设的所有寄存器写入到一个结构体里面,然后定义一个结构体指针指向这个外设的寄存器基地址,通过这个结构体指针来访问这个外设的所有寄存器。