历史上的今天
今天是:2024年12月18日(星期三)
2018年12月18日 | ARM裸机——FS2410按键控制LED灯(查询方式)
2018-12-18 来源:eefocus
一、开发环境
1、硬件平台:FS2410(s3c2410)
2、主机:Ubuntu 10.10
二、硬件的原理图(LED和按键)
1、LED灯的原理图:

2、按键的原理图:

按键的接线资源:
KSCAN0 -> GPE11 KSCAN1 -> GPG6 KSCAN2 -> GPE13 KSCAN3 -> GPG2
EINT0 -> GPF0 EINT2 -> GPF2 EINT11 -> GPG3 EINT19 -> GPG11

三、程序的主要原理:
主要涉及到K1,K2, K3, K4这四个按键,要用查询的方式进行判断哪个键被按下去了,因此将EINT11, EINT19设置为输入,用于读取,将KSCAN0,KSCAN1, KSACAN2,设置为输出,并分别设置为0,1,1或1,0,1或1,1,0这三种情况下,这样可用于区分K1、K2、K3中哪个键按下去,例如先让KSCAN0~2 = 011,那么K1被按下时,EINT19才会变为低电平,这时K2按下时,EINT19不会变低,这样就区分了按键K1和K2,区分其它按键原理一样。
四、寄存器的配置
1、有关LED的寄存器的配置:(设置GPF4-GPF7为输出)

2、按键方面涉及到寄存器配置(设置相关寄存器输入输出):






五、程序的详细代码:
led_key.c:(s3c2410.h头文件可在keil目录下找到,由s3c2440.h重命名得来)
#include "s3c2410.h"
void delay(long long max) //延迟函数
{
for(; max > 0; max--);
}
int main(void)
{
int read_value;
GPFCON = GPFCON & (~(0xff) << 8) | (0x55 << 8); //设置4个LED灯为输出(GPF4-GPF7输出)
GPFDAT |= (0xf << 4); //先将4个灯都熄灭掉
GPGCON = (0 << 7) | (1 << 12) | (0 << 23); //GPG3, GPG11 输入,GPG6, GPE11, GPE13输出
GPECON = (1 << 22) | (1 << 26);
while(1)
{
GPEDAT &= (0 << 11); //将GPE11置0,同时将GPE13和GPG6置1
GPEDAT |= (1 << 13);
GPGDAT |= (1 << 6);
read_value = GPGDAT & 0x808; //读取GPG11和GPG3的输入值
if((read_value & 0x800) == 0) //判断GPG11输入是否为0,以此判断K1键是否按下
{
read_value = 0x800;
delay(200000); //按键去抖
if((read_value &= GPGDAT) == 0)
{
if((GPFDAT & (1 << 4)) == 0) //判断D12是否亮着,如果亮着则熄灭,反之相反
GPFDAT |= (0x1 << 4);
else
GPFDAT &= (0xe << 4);
}
}
else
{
if((read_value & 0x8) == 0) //判断GPG3输入的值是否为0, 以此K4键是否按下
{
read_value = 0x8;
delay(200000); //按键去抖
if((read_value &= GPGDAT) == 0)
{
if((GPFDAT & (0x8 << 4)) == 0) //判断D9是都亮着,如果亮着则熄灭,反之相反
GPFDAT |= (0x8 << 4);
else
GPFDAT &= (0x7 << 4);
}
}
}
GPEDAT |= (1 << 11); //将GPE11和GPE13置1,同时将GPG6置0
GPEDAT |= (1 << 13);
GPGDAT &= (0 << 6);
read_value = GPGDAT & (0x8 << 8); //读取GPG11的值
if(read_value == 0) //判断GPG11是否输入0,以此判断K2键按下
{
read_value = 0x800;
delay(200000); //按键去抖
if((read_value &= GPGDAT) == 0)
{
if((GPFDAT & (0x2 << 4)) == 0) //判断D11是否亮着, 如果亮着则熄灭,反之相反
GPFDAT |= (0x2 << 4);
else
GPFDAT &= (0xd << 4);
}
}
GPEDAT &= (0 << 13); //将GPE13置0, 同时将GPE11和GPG6置1
GPEDAT |= (1 << 11);
GPGDAT |= (1 << 6);
read_value = GPGDAT & 0x800; //读取GPG11的值
if(read_value == 0) //判断GPG11是否为0,以此判断K3键是否按下
{
read_value = 0x800;
delay(200000); //按键去抖,延迟一段时间
if((read_value &= GPGDAT) == 0)
{
if((GPFDAT & (0x4 << 4)) == 0) //判断D10是否亮着,如果亮着则熄灭,反之相反
GPFDAT |= (0x4 << 4);
else
GPFDAT &= (0xb << 4);
}
}
}
return 0;
}
Makefile:
led.bin: start.S led_key.c
arm-none-linux-gnueabi-gcc -c start.S -o start.o
arm-none-linux-gnueabi-gcc -c led_key.c -o led_key.o
arm-none-linux-gnueabi-ld -Ttext 0x30008000 start.o led_key.o -o led_key
arm-none-linux-gnueabi-objcopy -O binary -S led_key led_key.bin
clean:
rm -f *.o led_key.bin
启动文件start.S:
.text
.global _start
_start:
#define WATCHDOG 0x53000000
ldr r0, =WATCHDOG
mov r1, #0
str r1, [r0]
ldr sp, =1024*4
bl main
loop:
b loop
然后在开发板的uboot上执行以下命令:
tftp 30008000 led_key.bin
go 30008000
史海拾趣
|
电动自行车充电器多采用开关型电源,型号虽多,但电路结构大同小异,主要区别在所选用的脉宽调制(PWM)芯片不同(如UC3845、UC3842、SG3524, TL494)。现以佳腾牌充电器为例,介绍其原理和故障检修方法。 电 ...… 查看全部问答> |
|
wince 5.0中能使用teechart for net吗? 用vs2005开发一个wince的应用程序,需要画三维图形,可不可以使用teechart for net,当装好后为什么找不到teechart 组件… 查看全部问答> |
|
看来用MAX+PLUS2的人不多啊~终于发现MAX+PLUS2就不支持单独的程序包的引用,必须把包文件和工程文件写在一块,感觉很麻烦,所以换成了QUARTUS2,不过从其中文手册上也没看到具体操作方法~ 问题是这样的: 建立元件库——根据文件名跟ENTITY名相同 ...… 查看全部问答> |
|
没有现成的接受管 看到老旧鼠标里有对管,不知道发射和接受的管子参数怎样?和一般电视机上用的有什么不同?能用在一定距离(例如两三米)的方式上么? 常见对管的参数都是多少?特别是接收管的静态电流一般是多大?主要是考虑到低功耗 [ 本帖最 ...… 查看全部问答> |
|
我画TMS320F2812的BGA封装 用IPC向导,请问如何把A1引脚从左上端改到左下端 还有如何把左下端的一个引脚去除而不影响后面的焊盘标号 就是如何去除图中画红圈的焊盘… 查看全部问答> |
|
坛友们在光荣榜活动中贡献了很多DLP相关的资料,活动已进行一段时间了,我把积累的资料搬过来,和大家共享。 PS:活动还在进行中,奖品包括:电脑双肩包、罗技鼠标、京东礼品卡、话费充值 传送门:https://bbs.eeworld.com.cn/thread-42750 ...… 查看全部问答> |
|
本帖最后由 啸风916636 于 2014-8-17 23:19 编辑 由于之前发的帖子时间长了,不能再次编辑了 已经好久没使用过CCS了,上次使用还是G2的时候,那是CCS才5.01,今天从官网下载了最新版本,已经到了6.0.1了。 在学校的 ...… 查看全部问答> |
|
本人参考了一些资料,包括TMS320VC33-DATASHEET,现在已经通过论坛方法完成FLASH烧写,现有如下疑问困扰本人很久,希望大神予以帮助! 1、打开CCS环境时,是否需要在启动CCS时通过GEL文件来配置总线控制器,因为本人直接在load program后直接通过v ...… 查看全部问答> |




