嵌入式Linux学习历程 — 汇编LED驱动及IO配置寄存器

汇编LED

Cortex-A汇编:
	1、需要用汇编初始化一些SOC外设
	2、使用汇编初始化DDR,I.MX6ULL不需要
	3、设置sp指针,一般指向DDR,设置好C语言运行环境

ALPHA开发板LED硬件原理分析

ALPHA开发板LED的GPIO为:GPIO1_IO03

STM32 IO初始化流程:

  1. 使能GPIO时钟
  2. 设置GPIO复用,将其复用为GPIO
  3. 配置GPIO的电气属性,如输出功能、上拉、速度等
  4. 使用GPIO,输出高低电平

I.MX6ULL IO初始化:

  1. 使能时钟,CCGR0 ~ 6 这7个寄存器,控制6ULL所有外设时钟的使能。简单设置,设置CCGR0 ~ 6 这7个寄存器全部为0XFFFFFFFF(将32位全部设置位1),相当于使能所有外设时钟。

  2. IO复用,将寄存器IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03的bit3 ~ bit0 (MUX_MODE 模式设置)设置为0101(5),这样GPIO1_IO03就复用为GPIO。

  3. 配置电气属性 寄存器IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 用于设置GPIO1_IO03的电气属性。包括压摆率、速度、驱动能力、开漏、上下拉等。

    IOMUXC_SW_ MUX _ CTL_PAD_XX_XX
    IOMUXC_SW_ PAD _ CTL_PAD_XX_XX
    这两种寄存器都用于配置IO,而不是GPIO,GPIO是IO众多复用功能的一种。比如,GPIO1_IO00这个IO可以复用为:I2C2_SCL、GPT1_CAPTURE1、ANATOP_OTG1_ID、ENET1_REF_CLK、GPIO1_IO00等9个功能。

  4. 配置GPIO功能,设置输入输出。设置GPIO1_GDIR寄存器的bit3(IO03)为1,即设置为输出模式。设置GPIO1_DR寄存器的bit(IO03),为1表示输出高电平,为0表示输出低电平。

汇编代码如下:

.global _start  /* 全局标量 */

/* 
 *  _start,程序从此函数开始执行 此函数完成时钟使能、
 *         GPIO初始化、最终控制GPIO输出低电平来点亮LED灯。
 *
 */

 _start:
    /* 使能所有外设时钟 */
    ldr r0, = 0X020C4068    /* CCGR0 */
    ldr r1, = 0XFFFFFFFF    /* 向CCGR0写入数据 */
    str r1, [r0]            /* 将0XFFFFFFFF写入到CCGR0中 */

    ldr r0, = 0X020C406C  	/* CCGR1 */
	str r1, [r0]

	ldr r0, = 0X020C4070  	/* CCGR2 */
	str r1, [r0]
	
	ldr r0, = 0X020C4074  	/* CCGR3 */
	str r1, [r0]
	
	ldr r0, = 0X020C4078  	/* CCGR4 */
	str r1, [r0]
	
	ldr r0, = 0X020C407C  	/* CCGR5 */
	str r1, [r0]
	
	ldr r0, = 0X020C4080  	/* CCGR6 */
	str r1, [r0]

    /* 设置GPIO1_IO03 复用为 GPIO1_IO03 */
    ldr r0, = 0X020E0068    /* 寄存器SW_MUX_CTL_PAD_GPIO1_IO03 */
    ldr r1, = 0X5           /* 设置寄存器SW_MUX_CTL_PAD_GPIO1_IO03的MUX_MODE为5 */
    str r1, [r0]

    /* 配置GPIO1_IO03的电气属性
     *bit 16:0 HYS关闭
	 *bit [15:14]: 00 默认下拉
     *bit [13]: 0 kepper功能
     *bit [12]: 1 pull/keeper使能
     *bit [11]: 0 关闭开路输出
     *bit [7:6]: 10 速度100Mhz
     *bit [5:3]: 110 R0/6驱动能力
     *bit [0]: 0 低压摆率
     */

     ldr r0, = 0X020E02F4   /* 寄存器SW_PAD_CTL_PAD_GPIO1_IO03 */
     ldr r1, = 0X10B0       /* 0X00001000010110000 = 0X10B0 */
     str r1, = [r0]

     /* 设置GPIO1_IO03为输出 */
     ldr r0, = 0X0209C004   /* 寄存器GPIO1_GDIR */
     ldr r1, = 0X8          /* 设置寄存器GPIO_GDIR bit3为1 */
     str r1, = [r0]

     /* 打开LED,即设置GPIO1_IO03为0 */
     ldr r0, = 0X0209C000   /* 寄存器GPIO1_DR */
     ldr r0, = 0            /* 寄存器值全为0 包括bit3 */
     ldr r1, = [r0]

/*
 * 描述: loop死循环
 */
loop:
    b loop

    

编译程序

①、使用arm-linux-gnueabihf-gcc,将.c .s文件变为.o

命令:	arm-linux-gnueabihf-gcc -g -c led.s -o led.o

②、将所有的.o文件连接为elf格式的可执行文件,链接地址为0x87800000

命令: arm-linux-gnueabihf-ld -Ttext 0x87800000 led.o -o led.elf

③、将elf文件转为bin文件。

命令: arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin

④、将elf文件转为汇编,反汇编。(可不执行)

命令: arm-linux-gnueabihf-objdump -D led.elf > led.dis

烧录

6ULL支持SD卡、EMMC、NAND、nor、SPI flash等等启动。裸机例程选择烧写到SD卡里面。
在ubuntu下向SD卡烧写裸机bin文件。烧写不是将bin文件拷贝到SD卡中,而是将bin文件烧写到SD卡绝对地址上。而且对于I.MX而言,不能直接烧写bin文件,必须先在bin文件前面添加头部。完成这个工作,需要使用正点原子提供的imxdownload软件。
Imxdownload使用方法,确定要烧写的SD卡文件,我的是/dev/sdb。
给予imxdownload可执行权限:
Chmod 777 imxdownload
烧写:
./imxdownload led.bin /dev/sdb
Imxdownlaod会向led.bin添加一个头部,生成新的load.imx文件,这个load.imx文件就是最终烧写到SD卡里面去的。

相关IO寄存器

GPIO时钟使能

CCGR0 ~ 6 这7个寄存器,控制I.M6ULL所有外设时钟的使能。
CCM_CCGRx是32位寄存器,每2位控制一个外设时钟。例如bit31~30控制着GPIO2的外设时钟。
CCGR0
两个位有四种操作方式:操作方式

IOMUXC_SW_MUX_CTL_PAD_XX_XX 详细介绍

IO复用
寄存器地址为 0X020E005C
这个寄存器是32位的,只用到了最低的5位,其中bit3~bit0(MUX_MODE)就是设置GPIO的复用功能的。

IOMUXC_SW_PAD_CTL_PAD_XX_XX 详细介绍

英文文档:
位功能

位功能
详细介绍:
功能图
SRE
DSE
SPEED
bit11 - 16

GPIO配置

GPIOx_GDIR寄存器

GPIOx_GDIR寄存器是方向寄存器,用于配置GPIO的输入/输出。
32位的GPIOx_GDIR寄存器每一位与每组GPIO的IO对应。如GPIO1_GDIR的bit3对应GPIO1_IO03。如果要设置GPIO为输入模式,就设置相应的位为0,设置为输出模式,就设置相应的位为1。
例如对GPIO1_IO03操作:
输出模式:GPIOx_GDIR(bit3) = 1
输入模式:GPIOx_GDIR(bit3) = 0

GPIOx_DR寄存器

GPIOx_DR寄存器用于存储数据,32位的GPIOx_DR寄存器每一位与每组GPIO的IO对应。如GPIO1_DR的bit3对应GPIO1_IO03。
当GPIO被配置成输出模式后,向DR寄存器写入数据那么相应IO就会输出相应的高低电平;当GPIO被配置成输入模式后,DR寄存器将保存对应IO的电平值。
例如对GPIO1_IO03操作:
高电平:GPIOx_DR(bit3) = 1
低电平:GPIOx_DR(bit3) = 0

GPIOx_PSR寄存器

PSR寄存器是GPIO状态寄存器,同样的PSR寄存器也是一个GPIO对应一个位。读取相应的位即可获取对应GPIO的状态,也就是GPIO的高低电平值。功能和输入状态下的DR寄存器相同。

GPIOx_ICR1 GPIOx_ICR2寄存器

ICR1和ICR2这两个寄存器都是中断控制寄存器,ICR1用于配置低16个GPIO,ICR2用于配置高16个GPIO。ICR1用于IO0 ~ 15的配置,ICR2用于IO16 ~ 31的配置。ICR1寄存器中一个GPIO用两个位,这两个位用来配置中断的触发方式。触发方式
如设置GPIO1_IO15为上升沿触发中断,那么GPIO1_ICR = 2 << 30。

GPIOx_IMR 寄存器

IMR寄存器是中断屏蔽寄存器,该32位寄存器也是一个GPIO对应一个位。IMR寄存器用来控制GPIO的中断静止和使能。
如使能某个GPIO的中断,那么设置相应位为1即可,反之,要禁止中断,那么就设置相应的位为0即可。

GPIOx_ISR 寄存器

ISR寄存器是32位寄存器,一个GPIO对应一个位,只要某个GPIO的中断发生,那么ISR寄存器中相应的位会被置1。所以,可以通过读取ISR寄存器判断GPIO中断是否发生,即ISR中这些位就是中断标志位。当处理完中断后,必须清除中断标志位,清除方法就是向ISR中相应的位写1,也就是 写1清零。

GPIOx_EDGE_SET 寄存器

EDGE_SET寄存器是边沿选择寄存器,用来设置边沿中断,一个GPIO对应一个位。EDGE_SET寄存器会覆盖ICR1和ICR2的设置。如果相应的位被置1,那就相当于设置对应的GPIO是上升沿和下降沿(双边沿)触发。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值