通过结构体的方式来定义和使用寄存器地址

在上一篇文章《IMX6UL裸机实现C语言LED实验》中,我们通过给每个寄存器宏定义一个地址的方式来使用寄存器地址,但是这种给每个寄存器定义一个值的方式太繁琐了,所以今天我们就来把他改成结构体的形式。

1、编写外设结构体

先将同属于一个外设的所有寄存器编写到一个结构体里面,如IO复用寄存器组的结构体如下:

/**IOMUX寄存器组*/1typedefstruct2{3volatileunsignedintBOOT_MODE0;4volatileunsignedintBOOT_MODE1;5volatileunsignedintSNVS_TAMPER0;6volatileunsignedintSNVS_TAMPER1;………107volatileunsignedintCSI_DATA00;108volatileunsignedintCSI_DATA01;109volatileunsignedintCSI_DATA02;110volatileunsignedintCSI_DATA03;111volatileunsignedintCSI_DATA04;112volatileunsignedintCSI_DATA05;113volatileunsignedintCSI_DATA06;114volatileunsignedintCSI_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复用寄存器,查找的参考手册可以得知其地址为0X020E0014,所以IO复用寄存器组的基地址就是0X020E0014,定义如下:

defineIOMUX_SW_MUX((IOMUX_SW_MUX_Type*)IOMUX_SW_MUX_BASE)

通过上面三步我们就可以通过“IOMUX_SW_MUX-GPIO1_IO03”来访问GPIO1_IO03的IO复用寄存器了。同样的,其他的外设寄存器都可以通过这三步来定义。

新建文件用来存放外设寄存器定义,在中输入如下代码:

1defineCCM_ANALOG_BASE(0X020C8000)3defineIOMUX_SW_PAD_BASE(0X020E0204)5defineGPIO2_BASE(0x020A0000)7defineGPIO4_BASE(0x020A8000)9defineCCM((CCM_Type*)CCM_BASE)444defineIOMUX_SW_MUX((IOMUX_SW_MUX_Type*)IOMUX_SW_MUX_BASE)446defineGPIO1((GPIO_Type*)GPIO1_BASE)448defineGPIO3((GPIO_Type*)GPIO3_BASE)450defineGPIO5((GPIO_Type*)GPIO5_BASE)

文件中修改成如下所示内容:

1#include""23/*4*@description:使能所有外设时钟5*@param:无6*@return:无7*/8voidclk_enable(void)9{10CCM-CCGR0=0XFFFFFFFF;11CCM-CCGR1=0XFFFFFFFF;12CCM-CCGR2=0XFFFFFFFF;13CCM-CCGR3=0XFFFFFFFF;14CCM-CCGR4=0XFFFFFFFF;15CCM-CCGR5=0XFFFFFFFF;16CCM-CCGR6=0XFFFFFFFF;17}1819/*20*@description:初始化LED对应的GPIO21*@param:无22*@return:无23*/24voidled_init(void)25{26/*1、初始化IO复用*/27IOMUX_SW_MUX-GPIO1_IO03=0X5;/*复用为GPIO1_IO03*/282930/*2、配置GPIO1_IO03的IO属性31*bit16:0HYS关闭32*bit[15:14]:00默认下拉33*bit[13]:0kepper功能34*bit[12]:1pull/keeper使能35*bit[11]:0关闭开路输出36*bit[7:6]:10速度100Mhz37*bit[5:3]:110R0/6驱动能力38*bit[0]:0低转换率39*/40IOMUX_SW_PAD-GPIO1_IO03=0X10B0;414243/*3、初始化GPIO*/44GPIO1-GDIR=0X0000008;/*GPIO1_IO03设置为输出*/4546/*4、设置GPIO1_IO03输出低电平,打开LED0*/47GPIO1-DR=~(13);4849}5051/*52*@description:打开LED灯53*@param:无54*@return:无55*/56voidled_on(void)57{58/*将GPIO1_DR的bit3清零*/59GPIO1-DR=~(13);60}6162/*63*@description:关闭LED灯64*@param:无65*@return:无66*/67voidled_off(void)68{69/*将GPIO1_DR的bit3置1*/70GPIO1-DR|=(13);71}7273/*74*@description:短时间延时函数75*@param-n:要延时循环次数(空操作循环次数,模式延时)76*@return:无77*/78voiddelay_short(volatileunsignedintn)79{80while(n--){}81}8283/*84*@description:延时函数,在396Mhz的主频下85*延时时间大约为1ms86*@param-n:要延时的ms数87*@return:无88*/89voiddelay(volatileunsignedintn)90{91while(n--)92{93delay_short(0x7ff);94}95}9697/*98*@description:mian函数99*@param:无100*@return:无101*/102intmain(void)103{104clk_enable();/*使能所有的时钟*/105led_init();/*初始化led*/106107while(1)/*死循环*/108{109led_off();/*关闭LED*/110delay(500);/*延时500ms*/111112led_on();/*打开LED*/113delay(500);/*延时500ms*/114}115116return0;117}

中7个函数的函数体写法变了,寄存器的访问采用中定义的外设指针。比如第27行设置GPIO1_IO03的复用功能就可以通过“IOMUX_SW_MUX-GPIO1_IO03”来给寄存SW_MUX_CTL_PAD_GPIO1_IO03赋值。

编译链接下载的代码和验证过程与上一篇文章《IMX6UL裸机实现C语言LED实验》一样,此处不再重复,请自行查阅。

发布于 2024-11-23
152
目录

    推荐阅读