正点原子学习笔记之汇编LED驱动实验

发布于:2024-10-18 ⋅ 阅读:(30) ⋅ 点赞:(0)

1 汇编LED原理分析

  为什么要写汇编
    需要用汇编初始化一些SOC外设
    使用汇编初始化DDR、I.MX6U不需要
    设置sp指针,一般指向DDR,设置好C语言运行环境

1.1 LED硬件分析

在这里插入图片描述
  可以看到LED灯一端接高电平,一端连接了GPIO_3上面,GPIO_3如果为低电平,LED灯亮,为高则LED灯灭。
  STM32的IO初始化流程
    使能GPIO时钟
    设置IO复用,将其复用为GPIO
    配置GPIO的电气属性
    使用GPIO,输出高低电平

  I.MX6U的IO初始化
    使能时钟CCGR0~CCGR6这七个寄存器控制着所有外设时钟,为了简单设置所有的寄存器全部为1,相当于使能所有外设时钟
    设置IO复用,将寄存器IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03的bit3~0设置为0101,即复用为GPIO模式
    将寄存器IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03是设置GPIO的电气属性。包括压摆率、速度、驱动能力、开漏、上下拉等。
    配置GPIO功能,设置输入输出。设置GPIO1_DR寄存器bit3,设置为输出模式。

2 编写驱动

2.1 手册解读

2.2 驱动代码

.global _start @全局标号

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

    ldr r0, =0x020c406c @CCGR1
    str r1, [r0]        @将0xffffffff写入CCGR1中 

    ldr r0, =0x020c4070 @CCGR2
    str r1, [r0]        @将0xffffffff写入CCGR2中 

    ldr r0, =0x020c4074 @CCGR3
    str r1, [r0]        @将0xffffffff写入CCGR3中 

    ldr r0, =0x020c4078 @CCGR4
    str r1, [r0]        @将0xffffffff写入CCGR4中 

    ldr r0, =0x020c407c @CCGR5
    str r1, [r0]        @将0xffffffff写入CCGR5中 

    ldr r0, =0x020c4080 @CCGR6
    str r1, [r0]        @将0xffffffff写入CCGR6中 

    ldr r0, =0x020c4084 @CCGR7
    str r1, [r0]        @将0xffffffff写入CCGR7中 

    /*配置GPIO1_IO03 PIN的复用为GPIO,也就是设置
     *IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03=5
     *IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03的寄存器地址为0x020E0068
     */
    ldr r0, =0x020E0068 @IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03
    ldr r1, =0x5        @写入的数据
    str r1, [r0]        @写入 

    /*配置GPIO1_IO03的电气属性 也就是寄存器
     *IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03
     *IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03的寄存器地址为0x020e02f4
     *
     *bit0:         0低速率
     *bit[5:3]:     110 R0/6驱动能力
     *bit[7:6]:     10  100MHz速度
     *bit11   :     0   关闭开路输出
     *bit12   :     1   使能pull/kepper
     *bit13   :    0   kepper
     *bit15:14:     00  默认100K下拉   
     *bit16   :     0   关闭hys  
     */    
    ldr r0, =0x020e02f4 @IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03
    ldr r1, =0x10b0     @写入的数据
    str r1, [r0]        @写入   

    /*设置GPIO功能
     *设置GPIO1_GDIR寄存器,设置GPIO1_GPIO03为输出
     *GPIO1_GDIR寄存器地址为0x0209c004,设置GPIO1_GDIR寄存器bit3为1,
     *也就是设置GPIO1_IO03为输出
     */   
     ldr r0, =0x0209c004
     ldr r1, =0x8
     str r1, [r0]

     /*打开LED 也就是设置GPIO1_IO03为0 
      *GPIO1_DR寄存器地址为0x0209c000  
      */

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

loop:
    b loop

2.3 编译程序

  将.c .s文件变为 .o

arm-linux-gnueabihf-gcc -c leds.s -o led.o

  arm-linux-gnueabihf-ld连接文件,用来将 众多的.o文件连接到一个指定的链接位置,就是将所有.o文件链接在一起,并且链接到指定地方。所以就要指定一个起始地址,本实验指定的链接起始地址就是代码开始运行的地址。对于6ULL来说,链接起始地址应该指向RAM地址。RAM分为外部RAM和内部RAM,外部RAM也就是DDR,内部RAM地址范围是0x900000~0x91FFFF,也可以放在外部DDR中,对于I.MX6U-ALPHA开发板,512MB字节DDR版本的核心板,DDR范围就是0x80000000到0xA0000000
  本系列视频,裸机代码的链接起始地址为0x87800000,因为后面uboot的链接起始地址也是0x87800000。要使用DDR,那么 必须要初始化DDR,这个头部信息包含了DDR的初始化参数,I.MX系列SOC内部boot rom会从SD卡、EMMC等外置存储中读取头部,然后初始化DDR,并且将bin文件拷贝到指定地方。
  Bin的运行地址一定要和链接地址一致。位置无关代码除外。

2.4 烧写bin文件

  STM32烧写到内部FLAHS
  6ULL支持SD卡、EMMC、NAND、nor、SPI flash等启动,裸机例程选择烧写到SD卡里面。
  在ubuntu下向SD卡烧写裸机bin文件。烧写不是将bin文件拷贝到SD卡中,而是将bin文件烧写到SD卡的指定绝对地址上,。而且对于I.MX而言,不能直接烧写bin文件,必须先在bin文件前面添加头部。完成这个工作,需要使用正点原子提供的imxdownload软件。
  6ULL支持JTAG,因为没有烧写算法,所以无法烧写
  但是可以通过JTAG将bin文件下载到内部ram
  6ULL的JTAG口竟然和SAI复用,SAI连接了WM8960音频DAC,为啥不用跳线帽,不懂
  在嵌入式Linux开发中基本不使用JLINK,普通开发者。
  调试代码一般点灯、串口来调试程序。


网站公告

今日签到

点亮在社区的每一天
去签到