实验目的:使用三个按键控制三盏灯
1.led灯原理图
从原理图可以看出,按键是被硬件拉高电平的,如果按键按下,对应的IO口就会被拉成低电平。
2.按键原理图
3.编写c文件,配置三个led的IO口为输出,配置三个按键为输入
查看数据手册:
①:LED灯
配置输出电平寄存器:
②:按键
编写代码如下:
#include "s3c2440_soc.h"
void delay(volatile int s) //用于延时,需要传递一个参数
{
while(s--);
}
int main(void) //用于选择点亮哪个led灯,需要一个参数
{
int key1,key2;
/*配置GPF4/5/6为输出引脚*/
GPFCON &=~((3<<8)|(3<<10)|(3<<12));
GPFCON |= ((1<<8)|(1<<10)|(1<<12));
/*配置GPF0/2 以及GPG3为输入引脚*/
GPFCON &=~((3<<0)|(3<<4));
GPGCON &=~((3<<6));
/*初始化先熄灭三盏灯*/
GPFDAT |=(7<<4);
/*循环点亮三盏led灯*/
while(1)
{
key1=GPFDAT;
key2=GPGDAT;
if(key1 & (1<<0))
{
//松开
GPFDAT |=((1<<6));
}
else
{
//按下
GPFDAT &=~((1<<6));
}
if(key1 & (1<<2))
{
//松开
GPFDAT |=((1<<5));
}
else
{
//按下
GPFDAT &=~((1<<5));
}
if(key2 & (1<<3))
{
//松开
GPFDAT |=((1<<4));
}
else
{
//按下
GPFDAT &=~((1<<4));
}
}
return 0;
}
注意:s3c2440_soc.h文件必须和.c文件在同一个目录下。
代码解析:
①:配置IO的模式,led灯对应的为输出
②:key对应的IO口为输入
③:使用key1和key2变量获取GPFDAT以及GPGDAT寄存器的,对当前IO口的状态进行判断
④:编写按键功能语句,按下对应的位输出低电平,否则为高电平。
4.编写汇编,设置栈sp,如下:
.text
.global _start
_start:
/*关闭看门狗*/
ldr r0 ,=0x53000000
ldr r1 ,=0
str r1 ,[r0]
/*设置内存:sp 栈*/
/*自动分辨是nand/nor启动方式*/
/*思路:因为nand是支持直接读取的,不需要什么
格式,而nor可以任意写,但是读取需要特定的
格式,若一开始往0地址写入一个值,然后读出来
如果读取的值和写入的值是一致的,说明是nand启动
否则是nor启动*/
mov r1 ,#0 //r1赋值为0
ldr r0 ,[r1] //读取0地址的值,以便后面恢复
str r1 ,[r1] //把0写入0地址里面
ldr r2 ,[r1] //从0地址读取值到r2
cmp r1 ,r2 //判断r1和r2是否相等,相等为nand启动
ldr sp ,=0x40000000+4096 //假设为nor启动
moveq sp, #4096 //相当为nand启动,重新设置sp
streq r0,[r1] //恢复nand中0地址的值
bl main
halt:
b halt
5.编写Makefile文件:
all:
arm-linux-gcc -c -o led.o led.c
arm-linux-gcc -c -o start.o start.S
arm-linux-ld -Ttext 0 start.o led.o -o led.elf
arm-linux-objcopy -O binary -S led.elf led.bin
arm-linux-objdump -D led.elf > led.dis
clean:
rm *.bin *.o *.elf *.dis
6.上传到Linux编译
使用make命令进行编译:
7.把编译好的led.bin 文件传回window系统,使用oflash烧写入开发版
8.使用oflash烧写
9.重启开发版,看效果
效果:当按键按下时对应的LED亮,放开按键,灯灭。
源码下载:https://download.csdn.net/download/qq_36243942/10854081