01. 汇编LED驱动实验

01. 汇编LED驱动实验

汇编原理分析

为什么要学习Cortex---A汇编

  1. 需要用汇编初始化一些SOC外设
  2. 使用汇编初始化DDR,I.MX6U不需要
  3. 设置SP指针,一般指向DDR,设置好C语言运行环境

ALPHA开发板LED原理图

而LED0是接在GPIO1_3,下面一个LED灯是电源指示灯

STM32IO初始化流程

  1. 使能GPIO时钟
  2. 设置IO复用,将其复用为GPIO
  3. 配置GPIO电气属性
  4. 使用GPIO输出高低电平

IMX6UL初始化流程

  1. 使能时钟,CCGR0-CCGR6这七个寄存器控制着6ULL所有外设时钟的使能。为了简单,将这七个寄存器全部设置为0xffffffff,相当于使能所有外设时钟
  2. IO复用,寄存器IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03。这个寄存器的0-3位是复用位,将这4位设置为0101,这样就是复用为GPIO
  3. 配置电气属性,寄存器IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03是设置电气属性,包括压摆率、速度、驱动能力、开漏、上下拉等。

  4. 配置GPIO功能,设置输入输出。设置GPIO1_GDIR寄存器,设置GPIO1_IO03为输出,也就是为1;设置GPIO1_DR数据寄存器的bit3,为1表示输出高电平。

汇编基础

处理器内部数据传输指令

  1. mov指令
    用于将数据从一个寄存器拷贝到另一个寄存器,或者将一个立即数传递到寄存器里面
r 复制代码
mov R0, R1 @将寄存器R1中的数据传递给R0
mov R0, #0x12 @将立即数0x12传递给R0寄存器
  1. mrs指令
    用于将特殊寄存器(如CPSR和SPSR)中的数据传递给通用寄存器
r 复制代码
mrs R0, CPSR
  1. msr指令
    将普通寄存器的数据传递给特殊寄存器
r 复制代码
msr CPSR, R0

存储器访问指令

ARM不能直接访问存储器,比如RAM中的数据。I.MX6UL中的寄存器就是RAM类型的,我们用汇编来配置时许哟啊借助寄存器访问指令,一般先要将要配置的值写入到Rx(x=0~12)寄存器中,然后借助存储器访问指令将Rx中的数据写入到I.MX6UL寄存器中,读取也是一样的。

  1. LDR指令
    用于从存储器加载数据到寄存器Rx中,也可以将一个立即数加载到寄存器中,加载立即数时需要用=,而不是#。

    上述代码的offset是0
  2. STR指令
    将数据写入到存储器中

编写驱动

r 复制代码
.global _start @全局标号,_start是程序的入口

_start:
	/* 使能所有外设时钟 */
	ldr r0, =0x020c4068 @CCGR0的地址
	ldr r1, =0xffffffff @要向CCGR0写入的数据
	str r1, [r0]		@将r1写入到r0中

	ldr r0, =0x020c406c
	str r1, [r0]
	
	ldr r0, =0x020c4070
	str r1, [r0]
	
	ldr r0, =0x020c4074
	str r1, [r0]

	ldr r0, =0x020c4078
	str r1, [r0]

	ldr r0, =0x020c407c
	str r1, [r0]

	ldr r0, =0x020c4080
	str r1, [r0]
    
    ldr r0, =0x020c4084
	str r1, [r0]

	/* 配置GPIO1_IO03的复用为GPIO,也就是设置为5 */
	ldr r0, =0x020e0068 @地址
	ldr r1, =0x05
	str r1, [r0] 

	/* 配置GPIO1_IO03的电器属性,地址是0x020e02f4
	*bit0:    0低速率
	*bit5:3:  110 R0/6驱动能力
	*bit7:6:  10 100MHz速度
	*bit11:   0关闭开路输出
	*bit12:   1 使能pull/kepper
	*bit13:   0 kepper
	*bit15:14: 00 100k下拉
	*bit16:   0 关闭hys
	*/

	ldr r0, =0x020e02f4 @地址
	ldr r1, =0x10b0
	str r1, [r0] 
	
	/* 设置GPIO1_GDIR寄存器,设置GPIO_GPIO03为输出 */
	ldr r0, =0x0209c004
	ldr r1, =0x08
	str r1, [r0] 

	/* 打开LED,也就是设置GPIO_IO03为低电平
	 *GPIO_DR的地址为0x0209c000
	 */
	ldr r0, =0x0209c000
	ldr r1, =0x00
	str r1, [r0]

loop:
	b loop @死循环,防止程序结束

编译程序

  1. 使用arm-linux-gnueabihf-gcc -g -c led.s led.o将.c 和.s 文件变为.o
  2. 使用arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf将.o文件链接为elf格式的可执行文件,链接时需要指定链接的起始地址。对于6ULL,链接其实地址应该指向RAM地址,而不是存在内部flash。RAM分为内部0x900000~0x91ffff,也可以是外部DDR,对于ALPHA,选择0x87800000。要使用DDR,必须要初始化DDR。对于IMX,bin文件不能直接烧写到SD卡、EMMC、NAND等外置存储中,然后从这些外置存储中启动运行,需要添加一个头部,这个头部包含了DDR的初始化参数
  3. 使用arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin将elf文件转为bin文件
  4. 使用arm-linux-gnueabihf-objdump -D led.elf > led.dis将elf文件转为汇编、反汇编文件

烧写bin文件

烧写不是将bin文件拷贝到SD卡中,而是将bin文件烧写到SD卡的绝对路径下。而且对于IMX,不能直接烧写bin问价,需要使用imxdownload软件。使用方法:确定要烧写的SD卡文件,给予imxdownload可执行权限chmod 777 imxdownload。然后就./imxdownload led.bin /dev/sdf。会向led.bin添加一个头部,并且生成一个新的imx文件,将新的文件烧写到SD卡中

相关推荐
VirtuousLiu30 分钟前
LM74912-Q1用作电源开关
单片机·嵌入式硬件·ti·电源设计·lm74912·电源开关
打地基的小白31 分钟前
软件I2C-基于江科大源码进行的原理解析和改造升级
stm32·单片机·嵌入式硬件·通信模式·i2c
Echo_cy_43 分钟前
STM32 DMA+AD多通道
stm32·单片机·嵌入式硬件
朴人1 小时前
【从零开始实现stm32无刷电机FOC】【实践】【7.2/7 完整代码编写】
stm32·单片机·嵌入式硬件·foc
追梦少年时1 小时前
STM32中断——外部中断
stm32·单片机·嵌入式硬件
bai_lan_ya1 小时前
stm32定时器中断和外部中断
stm32·单片机·嵌入式硬件
夜间去看海2 小时前
基于单片机的温度和烟雾检测
单片机·嵌入式硬件·温度烟雾
星汇极客2 小时前
【星汇极客】单片机竞赛之2024睿抗机器人大赛-火线速递赛道(持续更新)
stm32·单片机·嵌入式硬件·机器人
Daemon.Chen3 小时前
【STM32开发之寄存器版】(五)-窗口看门狗WWDG
stm32·单片机·嵌入式硬件
嵌入式杂谈5 小时前
STM32中断编程详解:配置外部中断和中断服务例程
stm32·单片机·嵌入式硬件