相对于C语言编写LED的优点在于不用每一个寄存器都要定义地址,用结构体成员地址递增的方式指向这个外设寄存器的基地址。
imx6ul.h文件(示例代码11.2.1 imx6ul.h文件代码)
/***************************************************************
Copyright © zuozhongkai Co., Ltd. 1998-2019. All rights reserved.
文件名 : imx6ul.h
作者 : 左忠凯
版本 : V1.0
描述 : IMX6UL相关寄存器定义,参考STM32寄存器定义方法
其他 : 无
日志 : 初版V1.0 2019/1/3 左忠凯创建
**************************************************************/
/* * 外设寄存器组的基地址 */
#define CCM_BASE (0X020C4000)
#define CCM_ANALOG_BASE (0X020C8000)
#define IOMUX_SW_MUX_BASE (0X020E0014)
#define IOMUX_SW_PAD_BASE (0X020E0204)
#define GPIO1_BASE (0x0209C000)
#define GPIO2_BASE (0x020A0000)
#define GPIO3_BASE (0x020A4000)
#define GPIO4_BASE (0x020A8000)
#define GPIO5_BASE (0x020AC000)
/*
* CCM寄存器结构体定义,分为CCM和CCM_ANALOG
*/
typedef struct
{
volatile unsigned int CCR;
volatile unsigned int CCDR;
volatile unsigned int CSR;
……
volatile unsigned int CCGR6;
volatile unsigned int RESERVED_3[1];
volatile unsigned int CMEOR;
} CCM_Type;
typedef struct
{
volatile unsigned int PLL_ARM;
volatile unsigned int PLL_ARM_SET;
volatile unsigned int PLL_ARM_CLR;
volatile unsigned int PLL_ARM_TOG;
……
volatile unsigned int MISC2;
volatile unsigned int MISC2_SET;
volatile unsigned int MISC2_CLR;
volatile unsigned int MISC2_TOG;
} CCM_ANALOG_Type;
/*
* IOMUX寄存器组
*/
typedef struct
{
volatile unsigned int BOOT_MODE0;
volatile unsigned int BOOT_MODE1;
volatile unsigned int SNVS_TAMPER0;
……
volatile unsigned int CSI_DATA04;
volatile unsigned int CSI_DATA05;
volatile unsigned int CSI_DATA06;
olatile unsigned int CSI_DATA07;
}IOMUX_SW_MUX_Type;
typedef struct
{
volatile unsigned int DRAM_ADDR00;
volatile unsigned int DRAM_ADDR01;
volatile unsigned int GRP_DDRPKE;
volatile unsigned int GRP_DDRMODE;
volatile unsigned int GRP_DDR_TYPE;
}IOMUX_SW_PAD_Type;
/*
* GPIO寄存器结构体
*/
typedef struct
{
volatile unsigned int DR;
volatile unsigned int GDIR;
volatile unsigned int PSR;
volatile unsigned int ICR1;
volatile unsigned int ICR2;
volatile unsigned int IMR;
volatile unsigned int ISR;
volatile unsigned int EDGE_SEL;
}GPIO_Type;
/*
* 外设指针
*/
#define CCM ((CCM_Type *)CCM_BASE)
#define CCM_ANALOG ((CCM_ANALOG_Type *)CCM_ANALOG_BASE)
#define IOMUX_SW_MUX ((IOMUX_SW_MUX_Type *)IOMUX_SW_MUX_BASE)
#define IOMUX_SW_PAD ((IOMUX_SW_PAD_Type *)IOMUX_SW_PAD_BASE)
#define GPIO1 ((GPIO_Type *)GPIO1_BASE)
#define GPIO2 ((GPIO_Type *)GPIO2_BASE)
#define GPIO3 ((GPIO_Type *)GPIO3_BASE)
#define GPIO4 ((GPIO_Type *)GPIO4_BASE)
#define GPIO5 ((GPIO_Type *)GPIO5_BASE)
...
源文件(示例代码11.3.2 main.c文件代码)
#include "imx6ul.h"
/*
* @description : 使能I.MX6U所有外设时钟
* @param : 无
* @return : 无
*/
void clk_enable(void)
{
CCM->CCGR0 = 0XFFFFFFFF;
CCM->CCGR1 = 0XFFFFFFFF;
CCM->CCGR2 = 0XFFFFFFFF;
CCM->CCGR3 = 0XFFFFFFFF;
CCM->CCGR4 = 0XFFFFFFFF;
CCM->CCGR5 = 0XFFFFFFFF;
CCM->CCGR6 = 0XFFFFFFFF;
}
/*
* @description : 初始化LED对应的GPIO
* @param : 无
* @return : 无
*/
void led_init(void)
{
/* 1、初始化IO复用 */
IOMUX_SW_MUX->GPIO1_IO03 = 0X5;
/* 复用为GPIO1_IO03 */
/* 2、配置GPIO1_IO03的IO属性
*bit 16:0 HYS关闭 32 *bit [15:14]: 00 默认下拉
*bit [13]: 0 kepper功能 34 *bit [12]: 1 pull/keeper使能
*bit [11]: 0 关闭开路输出 36 *bit [7:6]: 10 速度100Mhz
*bit [5:3]: 110 R0/6驱动能力 38 *bit [0]: 0 低转换率
*/
IOMUX_SW_PAD->GPIO1_IO03 = 0X10B0;
/* 3、初始化GPIO */
GPIO1->GDIR = 0X0000008;
/* GPIO1_IO03设置为输出 */
/* 4、设置GPIO1_IO03输出低电平,打开LED0 */
GPIO1->DR &= ~(1 << 3);
}
/*
* @description : 打开LED灯
* @param : 无
* @return : 无
*/
void led_on(void)
{
/* 将GPIO1_DR的bit3清零 */
GPIO1->DR &= ~(1<<3); 60
}
/*
* @description : 关闭LED灯
* @param : 无
* @return : 无
*/
void led_off(void)
{
/* 将GPIO1_DR的bit3置1 */
GPIO1->DR |= (1<<3);
}
/*
* @description : 短时间延时函数
* @param - n : 要延时循环次数(空操作循环次数,模式延时)
* @return : 无
*/
void delay_short(volatile unsigned int n)
{
while(n--){}
}
/*
* @description : 延时函数,在396Mhz的主频下延时时间大约为1ms
* @param - n : 要延时的ms数
* @return : 无
*/
void delay(volatile unsigned int n)
{
while(n--)
{
delay_short(0x7ff);
}
}
/*
* @description : main函数
* @param : 无
* @return : 无
*/
int main(void)
{
clk_enable();
/* 使能所有的时钟 */
led_init();
/* 初始化led */
while(1) /* 死循环 */
{
led_off(); /* 关闭LED */
delay(500); /* 延时500ms */
led_on(); /* 打开LED */
delay(500); /* 延时500ms */
}
return 0;
}
C语言LED控制优化
本文介绍了一种使用结构体成员地址递增方式指向外设寄存器基地址的方法,简化了C语言中LED控制的寄存器定义过程。通过具体示例代码展示了如何在IMX6UL平台上实现LED的初始化、开关控制及定时功能。

1039

被折叠的 条评论
为什么被折叠?



