C语言点灯
通过逐个定义寄存器地址的方法来编写外设驱动,非常的不方便。本文将介绍如何使用结构体来定义外设寄存器
1. IMX6U寄存器定义
模仿STM32的寄存器定义来编写IMX6U的寄存器定义,分三步:
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 GPIO1_BASE (0x0209C000)
#define GPIO1 ((GPIO_Type *)GPIO1_BASE)
2. 硬件设计
硬件设计与汇编点灯实例相同
3. 软件设计
3.1 汇编部分
- 创建汇编文件start.S,用来完成C语言环境搭建
.global _start
_start:
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0x13
msr cpsr, r0
ldr sp, = 0x80200000
b main
3.2 C语言部分
- 创建imx6ul.h文件,用来定义IMX6UL相关寄存器
#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)
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 BOOT_MODE0;
volatile unsigned int BOOT_MODE1;
volatile unsigned int SNVS_TAMPER0;
......
......
volatile unsigned int CSI_DATA06;
volatile unsigned int CSI_DATA07;
}IOMUX_SW_MUX_Type;
typedef struct{
volatile unsigned int DRAM_ADDR00;
volatile unsigned int DRAM_ADDR01;
volatile unsigned int DRAM_ADDR02;
......
......
volatile unsigned int GRP_DDRPKE;
volatile unsigned int GRP_DDRMODE;
volatile unsigned int GRP_DDR_TYPE;
}IOMUX_SW_PAD_Type;
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)
#include "imx6ul.h"
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;
}
void led_init(void){
IOMUX_SW_MUX->GPIO1_IO03 = 0x5;
IOMUX_SW_PAD->GPIO1_IO03 = 0X10B0;
GPIO1->GDIR = 0X0000008;
GPIO1->DR &= ~(1 << 3);
}
void led_on(void){
GPIO1->DR &= ~(1<<3);
}
void led_off(void){
GPIO1->DR |= (1<<3);
}
void delay_short(volatile unsigned int n){
while(n--){}
}
void delay(volatile unsigned int n){
while(n--){
delay_short(0x7ff);
}
}
int main(void){
clk_enable();
led_init();
while(1)
{
led_off();
delay(500);
led_on();
delay(500);
}
return 0;
}
4. 下载验证
4.1 编写Makefile和链接脚本
Makefile和链接脚本与C语言点灯(逐个定义寄存器地址)实例相同
4.2 代码验证
- 将imxdownload拷贝到工程根目录下
- 赋予imxdownload可执行权限
chmod 777 imxdownload
ls /dev/sd*
./imxdownload ledc.bin /dev/sdcard
- 烧写成功后,复位开发板,若代码正常,LED0会以500ms的时间间隔亮灭
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)