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

时间:2022-12-20 11:01:23

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

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

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

1.1 LED的原理图

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

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

                       

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

 

1.2 相关的GPIO寄存器的配置

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

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

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

 

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

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是点亮了啊。

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

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

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

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

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

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

 

栈指针的设置:

目前我们的开发板是设置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 }

效果图如下:

 

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

 


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

3.1按键连线

 key0  --- GPF0

 key1  --- GPF1

    key3  --- GPG3

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

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

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

实验现象:

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

  

 

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

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

目录结构如下:

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

 


觉得不错,就给我点小支持吧,蟹蟹