GPIO实验:ARM汇编代码实现LED灯亮灭控制
一、 汇编工程模板Makefile分析
NAME=asm-led #指定编译的源文件名字
CROSS_COMPILE = arm-linux-gnueabihf- #指定交叉编译工具链前缀
CC = $(CROSS_COMPILE)gcc #指定gcc名字
LD = $(CROSS_COMPILE)ld #指定链接器名字
OBJCOPY = $(CROSS_COMPILE)objcopy #用于将二进制文件编译生成一个bin后缀的二进制文件
OBJDUMP = $(CROSS_COMPILE)objdump #用于生成我们工程的反汇编文件
all:
#编译生成二进制.o文件
$(CC) -O0 -g -c $(NAME).S -o $(NAME).o
#编译生成二进制elf文件
#-Ttext=0xC0008000用于指定将程序下载到内存的0XC0008000位置
$(LD) -Ttext=0xC0008000 $(NAME).o -o $(NAME).elf
#转换二进制文件为bin后缀文件
$(OBJCOPY) -O binary $(NAME).elf $(NAME).bin
#生成可执行文件的反汇编
$(OBJDUMP) -D $(NAME).elf > $(NAME).dis
clean:#删除编译时生成的一些文件
rm -rf *.elf *.bin *.o *.dis
install:
sudo cp $(NAME).bin /mnt/hgfs/share1/
二、 编写LED1亮灭控制的汇编文件
.text
.global _start
_start:
@1.RCC时钟使能GPIOE RCC_MP_AHB4ENSETR[4]->1
@ 间接寻址取值
LDR R0,=0x50000a28
LDR R1,[R0]
@ 改值
ORR R1,R1,#(0x1<<4)
@ 写回
STR R1,[R0]
@2.设置PE10为输出模式 GPIOE_MODER[21:20]->01
@ 间接寻址取值
LDR R0,=0x50006000
LDR R1,[R0]
@ 改值
BIC R1,R1,#(0x3<<20)
ORR R1,R1,#(0x1<<20)
@ 写回
STR R1,[R0]
@ 间接寻址取值
LDR R0,=0x50006000
LDR R1,[R0]
@ 改值
BIC R1,R1,#(0x3<<16)
ORR R1,R1,#(0x1<<16)
@ 写回
STR R1,[R0]
@3.设置PE10为推挽输出 GPIOE_OTYPER[10]->0
@ 间接寻址取值
LDR R0,=0x50006004
LDR R1,[R0]
@ 改值
BIC R1,R1,#(0x1<<10)
@ 写回
STR R1,[R0]
@ 间接寻址取值
LDR R0,=0x50006004
LDR R1,[R0]
@ 改值
BIC R1,R1,#(0x1<<8)
@ 写回
STR R1,[R0]
@4.设置PE10为低速输出 GPIOE_OSPEEDR[21:20]->00
@ 间接寻址取值
LDR R0,=0x50006008
LDR R1,[R0]
@ 改值
BIC R1,R1,#(0x3<<20)
@ 写回
STR R1,[R0]
@ 间接寻址取值
LDR R0,=0x50006008
LDR R1,[R0]
@ 改值
BIC R1,R1,#(0x3<<16)
@ 写回
STR R1,[R0]
@5.设置PE10输出无上拉下拉 GPIOE_PUPDR[21:20]->00
@ 间接寻址取值
LDR R0,=0x5000600c
LDR R1,[R0]
@ 改值
BIC R1,R1,#(0x3<<20)
@ 写回
STR R1,[R0]
@ 间接寻址取值
LDR R0,=0x5000600c
LDR R1,[R0]
@ 改值
BIC R1,R1,#(0x3<<16)
@ 写回
STR R1,[R0]
@1.RCC时钟使能GPIOF RCC_MP_AHB4ENSETR[5]->1
@ 间接寻址取值
LDR R0,=0x50000a28
LDR R1,[R0]
@ 改值
ORR R1,R1,#(0x1<<5)
@ 写回
STR R1,[R0]
@2.设置PF10为输出模式 GPIOE_MODER[21:20]->01
@ 间接寻址取值
LDR R0,=0x50007000
LDR R1,[R0]
@ 改值
BIC R1,R1,#(0x3<<20)
ORR R1,R1,#(0x1<<20)
@ 写回
STR R1,[R0]
@3.设置PF10为推挽输出 GPIOE_OTYPER[10]->0
@ 间接寻址取值
LDR R0,=0x50007004
LDR R1,[R0]
@ 改值
BIC R1,R1,#(0x1<<10)
@ 写回
STR R1,[R0]
@4.设置PF10为低速输出 GPIOE_OSPEEDR[21:20]->00
@ 间接寻址取值
LDR R0,=0x50007008
LDR R1,[R0]
@ 改值
BIC R1,R1,#(0x3<<20)
@ 写回
STR R1,[R0]
@5.设置PF10输出无上拉下拉 GPIOE_PUPDR[21:20]->00
@ 间接寻址取值
LDR R0,=0x5000700c
LDR R1,[R0]
@ 改值
BIC R1,R1,#(0x3<<20)
@ 写回
STR R1,[R0]
@6.控制PE10管脚输出高低电平 GPIOE_ODR[10]
@ LED1闪烁
LOOP:
BL LED1_ON
BL delay
BL LED1_OFF
BL delay
BL LED2_ON
BL delay
BL LED2_OFF
BL delay
BL LED3_ON
BL delay
BL LED3_OFF
BL delay
B LOOP
LED1_ON:
@ 间接寻址取值
LDR R0,=0x50006014
LDR R1,[R0]
@ 改值
ORR R1,R1,#(0x1<<10)
@ 写回
STR R1,[R0]
MOV PC,LR
LED1_OFF:
@ 间接寻址取值
LDR R0,=0x50006014
LDR R1,[R0]
@ 改值
BIC R1,R1,#(0x1<<10)
@ 写回
STR R1,[R0]
MOV PC,LR
LED2_ON:
@ 间接寻址取值
LDR R0,=0x50007014
LDR R1,[R0]
@ 改值
ORR R1,R1,#(0x1<<10)
@ 写回
STR R1,[R0]
MOV PC,LR
LED2_OFF:
@ 间接寻址取值
LDR R0,=0x50007014
LDR R1,[R0]
@ 改值
BIC R1,R1,#(0x1<<10)
@ 写回
STR R1,[R0]
MOV PC,LR
LED3_ON:
@ 间接寻址取值
LDR R0,=0x50006014
LDR R1,[R0]
@ 改值
ORR R1,R1,#(0x1<<8)
@ 写回
STR R1,[R0]
MOV PC,LR
LED3_OFF:
@ 间接寻址取值
LDR R0,=0x50006014
LDR R1,[R0]
@ 改值
BIC R1,R1,#(0x1<<8)
@ 写回
STR R1,[R0]
MOV PC,LR
@封装汇编的延时函数
delay:
LDR R1,=0X10000000
mm:
cmp R1,#0
SUBNE R1,R1,#1
BNE mm
mov pc,lr
.end
三、串口工具加载bin文件步骤
- 连接开发板之后,打开设备管理器查看设备端口
- 打开串口工具进行连接
- 点击开发板上的复位键,在倒计时结束前按下任意键,然后输入命令: loadb 0xC0008000 回车
- 加载生成的 bin 文件
- 输入命令:go 0xC0008000 回车,执行代码
四、开发板现象