• JZ2440裸机点亮LED【学习笔记】


    平台:jz2440

    作者:庄泽彬(欢迎转载,请注明作者)

    说明:韦东山一期视频学习笔记

    一、我们首先来做第一个实验,用汇编语言点亮板子上的LED。

    1.1 LED的原理图

    从下面的原理图可知LED1是连接到芯片的GPF4

                           

    1.2 相关的GPIO寄存器的配置

    我们要点亮LED,就要把相关的端口配置成输出口,并且输出低电平。看看芯片手册,要GPF4输出低电平要配置GPFCON寄存器设置相应的位位01即为输出状态,在配置GPFDAT相应的位为0即可输出低电平。

    1.3相关代码:

    led_on.S文件
     1 .text
     2 .global _start
     3 _start:
     4         LDR R0,=0x56000050  @ 设置R0为GPFCON寄存器
     5                             @ 用于配置端口的输入、输出状态
     6 
     7         mov R1,#0x00000100   
     8         str R1,[R0]         @ 设置GPF4端口为输出口
     9 
    10         ldr R0,=0x56000054  @ 设置R0为GPFDAT寄存器
    11                             @ 用于配置端口输出的高低电平
    12 
    13         mov R1,#0x00000100
    14         str R1,[R0]         @ 输出低电平
    15 
    16 MAIN_LOOP:
    17             B MAIN_LOOP

    Makefile文件

    1 led_on.bin:led_on.S
    2     arm-linux-gcc -g -c -o led_on.o led_on.S
    3     arm-linux-ld -Ttext 0x00000000 -g led_on.o -o led_on_elf
    4     arm-linux-objcopy -O binary -S led_on_elf led_on.bin
    5 clean:
    6     rm led_on.bin led_on_elf *.o

    1.4 执行结果

    看一下图片LED是点亮了啊。

    二、我们升级一下上一个程序,我们使用C语言的方式点亮LED灯.

    2.1 我们要设置好C语言的运行环境,要关闭看门狗以及设置栈,函数的参数都是存放在栈里的,因此要用C语言的方式点亮LED,把栈设置好是很重要的。

    查看芯片手册关闭看门狗的方法:

    往WTCON寄存器写入0即可关闭

     

    栈指针的设置:

    目前我们的开发板是设置nandflash启动的,启动的时候会拷贝nandflash的前4K的内容到芯片内部的ram中运行,因此栈指针的范围不要超过4K

    2.2相关代码

    crt0.S

     1 .text
     2 .global _start
     3 _start:
     4 
     5     ldr R0,=0x53000000   @ 设置为看门狗寄存器地址
     6 
     7     mov R1,#0x0
     8     str R1,[R0]
     9 
    10     ldr sp,=1024*4       @ 设置的sp范围不要超过4K
    11 
    12     bl main
    13 
    14 halt_loop:
    15     b halt_loop

    led_on_c.c

     1 #define GPFCON  (*(volatile unsigned long *)0x56000050)
     2 #define GPFDAT  (*(volatile unsigned long *)0x56000054)
     3 
     4 int main()
     5 {
     6     GPFCON = 0x00000100; //配置GPF4为输出口
     7     GPFDAT = 0x00000000; //输出低电平
     8 
     9     return 0;
    10 }

    Makefile

    led_on_c.bin:crt0.S led_on_c.c
        arm-linux-gcc -g -c -o crt0.o crt0.S
        arm-linux-gcc -g -c -o led_on_c.o led_on_c.c
        arm-linux-ld -Ttext 0x00000000 -g crt0.o led_on_c.o -o led_on_c_elf
        arm-linux-objcopy -O binary -S led_on_c_elf led_on_c.bin
        arm-linux-objdump -D -m arm led_on_c_elf > led_on_c.dis
    clean:
        rm -f led_on_c_elf led_on_c.dis led_on_c.bin *.o

    2.3 编译与执行结果

    执行make生成我们的目标文键led_on_c.bin,led_on_c.dis是反汇编文件

    现象跟上一次的实验一下,这里就不贴图了啊。

    3.1在修改一下上面的例子,改成流水灯

    其他的文件我们保持不变只修改led_on_c.c,这个只是应用编程,想怎么改都ok,

    led_on_c.c源码:

     1 #define GPFCON  (*(volatile unsigned long *)0x56000050)
     2 #define GPFDAT  (*(volatile unsigned long *)0x56000054)
     3 
     4 #define GPF4_OUT    (1<<(4*2))
     5 #define GPF5_OUT    (1<<(5*2))
     6 #define GPF6_OUT    (1<<(6*2))
     7 
     8 void delay(volatile unsigned long delay)
     9 {
    10     for (;delay > 0;delay --);
    11 }
    12 
    13 
    14 int main()
    15 {
    16     unsigned long i = 0;
    17 
    18     GPFCON = GPF4_OUT|GPF5_OUT|GPF6_OUT;  //配置为输出端口
    19 
    20     while(1){
    21         delay(30000);
    22         GPFDAT = (~(i<<4));
    23         if (++i == 8){
    24             i = 0;
    25         }
    26     }
    27 
    28     return 0;
    29 }

    效果图如下:

      

      

     三、我们在做另外一个实验用按键来控制LED灯的亮灭,

    3.1按键连线

     key0  --- GPF0

     key1  --- GPF1

        key3  --- GPG3

     GPG寄存器的地址如下图,需要注意的是,我们的按键是配置成输入引脚。

    3.2相关代码

    crt0.S

     1 .text
     2 .global _start
     3 _start:
     4 
     5     ldr R0,=0x53000000     @ 设置为看门狗寄存器
     6 
     7     mov R1,#0x0
     8     str R1,[R0]
     9 
    10     ldr SP,=1024*4         @ 设置栈指针
    11 
    12     bl main
    13 halt_loop:
    14     b halt_loop

    key_leds.c

     1 #define GPFCON    (*(volatile unsigned long *)0x56000050)
     2 #define GPFDAT    (*(volatile unsigned long *)0x56000054)
     3 
     4 #define GPGCON    (*(volatile unsigned long *)0x56000060)
     5 #define GPGDAT    (*(volatile unsigned long *)0x56000064)
     6 
     7 //LED1,LED2,LED3
     8 #define GPF4_OUT  (1<<(4*2))
     9 #define GPF5_OUT  (1<<(5*2))
    10 #define GPF6_OUT  (1<<(6*2))
    11 
    12 #define GPF4_MASK (3<<(4*2))
    13 #define GPF5_MASK (3<<(5*2))
    14 #define GPF6_MASK (3<<(6*2))
    15 
    16 //KEY1,KEY2,KEY3
    17 #define GPF0_IN   (0<<(0*4))
    18 #define GPF2_IN   (0<<(2*4))
    19 #define GPG3_IN   (0<<(3*4))
    20 
    21 #define GPF0_MAKS (3<<(0*2))
    22 #define GPF2_MAKS (3<<(2*2))
    23 #define GPG3_MAKS (3<<(3*2))
    24 
    25 int main()
    26 {
    27     unsigned long key_status;
    28 
    29     //LED设置为输出引脚
    30     GPFCON = GPFCON & ~(GPF4_MASK|GPF5_MASK|GPF6_MASK);
    31     GPFCON = GPFCON | (GPF4_OUT|GPF5_OUT|GPF6_OUT);
    32  //KEY设置为输入引脚
    33     GPFCON = GPFCON & ~(GPF0_MAKS|GPF2_MAKS);
    34     GPFCON = GPFCON | (GPF0_IN|GPF2_IN);
    35 
    36     GPGCON = GPGCON & ~(GPG3_MAKS);
    37     GPGCON = GPGCON | GPG3_IN;
    38 
    39     while(1){
    40         key_status = GPFDAT;
    41 
    42         if (key_status & (1<<0))
    43             GPFDAT |= (1<<4);
    44         else
    45             GPFDAT &= ~(1<<4);
    46 
    47         if (key_status & (1<<2))
    48             GPFDAT |= (1<<5);
    49         else
    50             GPFDAT &= ~(1<<5);
    51 
    52         key_status = GPGDAT;
    53 
    54         if (key_status & (1<<3))
    55             GPFDAT |= (1<<6);
    56         else
    57             GPFDAT &= ~(1<<6);
    58     }
    59     return 0;
    60 }

    Makefile

    1 key_leds.bin:crt0.S key_leds.c
    2     arm-linux-gcc -g -c -o crt0.o crt0.S
    3     arm-linux-gcc -g -c -o key_leds.o key_leds.c
    4     arm-linux-ld -Ttext 0x00000000 -g crt0.o key_leds.o -o key_leds_elf
    5     arm-linux-objcopy -O binary -S key_leds_elf key_leds.bin
    6     arm-linux-objdump -D -m arm key_leds_elf > key_leds.dis
    7 clean:
    8     rm *.o *.bin *.dis key_leds_elf

    实验现象:

      

     相关的代码大家可以从我的github账号上下载:

    https://github.com/zzb2760715357/100ask

    目录结构如下:

      

  • 相关阅读:
    misc子系统
    Spring boot+RabbitMQ环境
    Linux input
    lnmp环境的搭建
    DDD的.NET开发框架
    【踩坑记】从HybridApp到ReactNative
    Migrating from IntelliJ Projects
    Windows下Redis中RedisQFork位置调整
    远程仓库版本回退方法 good
    maven repository
  • 原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/9314314.html
Copyright © 2020-2023  润新知