• 一步步点亮LED之汇编点亮LED


    GPJ0CON端口一共有8个端口,分别记住:GPJ0_0~GPJ0_7;相关寄存器为GPJ0CON、GPJ0DAT

    GPJ0CON寄存器中设置8个引脚的工作模式(32/8=4,每个引脚分到4位,譬如GPJ0_0位bit0~bit3,我们就给=它写入0001得到输出模式)

    1、需要控制的引脚:GPJ0_3、GPJ0_4、GPJ0_5低电平亮,高电平灭。

    2、GPJ0CON(0xE0200240):控制模式      

      GPJ0DAT(0xE0200244):控制引脚数据

    注意:由于IO与内存统一编址,所以不能直接往寄存器写入值,我们应该用指针的方式访问对应的地址间接写入。

    将led灯全部点亮

    /*
    *文件名:led.S
    *作者:***
    *描述:这是我们一步步点亮led灯的第一个led程序
    *
    */
    
    _start:
        //第一步:把0x11111111写入0xE0200240(GPJOCON)位置
        ldr r0, =0x11111111        //从后面的=号可以看出来是伪指令,因为需要编译器来判
        ldr r1, =0xE0200240        //定是合法立即数还是非法立即数,一般都是ldr伪指令
        str r0, [r1]            //把r0中的数写入r1为地址的内存中去
    
        //第二步:把0x0写入0xE0200244(GPJ0DAT)
        ldr r0, =0x0
        ldr r1, =0xE0200244
        str r0, [r1]            //把0写入r1(0xE0200244)中

    b .
    //写了一个死循环。逐行运行裸机程序直到断电

    编译后得到led.bin烧录到裸机中,就可以点亮led。

    下面开始改进上述代码

    1、增加可读性

    由于上述代码可读性较差,过度依赖注释,下面需要改进代码,虽然可能增加代码复杂度,但是可读性增强

    (1)运用宏定义,把对应的内存地址和GPIO名字绑定

    (2)运用位操作,只亮中间一个灯(位操作便于直观看出哪位改动了)

    #define GPJ0C0N 0xE0200240
    #define GPJ0DAT 0xE0200244
    .global _start
    _start:
        //第一步:把0x11111111写入0xE0200240(GPJOCON)位置
        ldr r0, =0x11111111        //从后面的=号可以看出来是伪指令,因为需要编译器来判
        ldr r1, =GPJ0C0N         //定是合法立即数还是非法立即数,一般都是ldr伪指令
        str r0, [r1]            //把r0中的数写入r1为地址的内存中去
    
        //第二步:把0x0写入0xE0200244(GPJ0DAT)
        ldr r0, =(0x0)|(1<<3)|(0<<4)|(1<<5)  
        ldr r1, =GPJ0DAT
        str r0, [r1]            //把0写入r1(0xE0200244)中
        
    b .                            //写了一个死循环。逐行运行裸机程序直到断电

    2、led流水灯效果

    (1)加入延时代码

    (2)加入循环

    #define GPJ0C0N 0xE0200240
    #define GPJ0DAT 0xE0200244
    .global _start
    _start:
        //第一步:把0x11111111写入0xE0200240(GPJOCON)位置
        ldr r0, =0x11111111        //从后面的=号可以看出来是伪指令,因为需要编译器来判
        ldr r1, =GPJ0C0N         //定是合法立即数还是非法立即数,一般都是ldr伪指令
        str r0, [r1]            //把r0中的数写入r1为地址的内存中去
    flash:
        //第二步:闪烁效果
        //点亮第一个灯,延时
        ldr r0, =(0<<3)|(1<<4)|(1<<5)
        ldr r1, =GPJ0DAT
        str r0, [r1]            //把0写入r1(0xE0200244)中
        bl delay
        //熄灭,延时
        ldr r0, =(1<<3)|(1<<4)|(1<<5)
        ldr r1, =GPJ0DAT
        str r0, [r1]            //把0写入r1(0xE0200244)中
        bl delay
        
        //点亮第二个灯,延时
        ldr r0, =(1<<3)|(0<<4)|(1<<5)
        ldr r1, =GPJ0DAT
        str r0, [r1]            //把0写入r1(0xE0200244)中
        bl delay
        //熄灭,延时
        ldr r0, =(1<<3)|(1<<4)|(1<<5)
        ldr r1, =GPJ0DAT
        str r0, [r1]            //把0写入r1(0xE0200244)中
        bl delay
        
        //点亮第三个灯,延时
        ldr r0, =(1<<3)|(1<<4)|(0<<5)
        ldr r1, =GPJ0DAT
        str r0, [r1]            //把0写入r1(0xE0200244)中
        bl delay
        //熄灭,延时
        ldr r0, =(1<<3)|(1<<4)|(1<<5)
        ldr r1, =GPJ0DAT
        str r0, [r1]            //把0写入r1(0xE0200244)中
        bl delay
        b flash
        
    b .                        //写了一个死循环。逐行运行裸机程序直到断电(由于上一行有循环,这行根本不会执行,也可以删掉)
    

    delay: ldr r2, =900000 ldr r3, =0x0 delay_loop: sub r2, r2, #1 cmp r2, r3 //cmp会影响Z标志位,如果r2=r3则Z等于1,下一句eq就会成立 bne delay_loop mov pc, lr
  • 相关阅读:
    面试开发需要准备的
    多线程 多进程
    TCP/IP协议学习
    深信服算法岗实习面试经验
    TZOJ4777: 方格取数
    Python 基于 NLP 的文本分类
    mac os 使用记录
    字节跳动游戏开发岗题目
    mac进行acm(C/C++)编程
    常用的正则表达式(转)
  • 原文地址:https://www.cnblogs.com/jxjl/p/6958656.html
Copyright © 2020-2023  润新知