今天这个程序主要实现了通过mini2440上面的六个按键去控制那个4个LED,并且在按键的过程中蜂鸣器还会发出声音。
实现原理:
主要是通过GPIO端口去实现对于这个三种硬件的操作,通过查询S3C2440原理图就可发现他们所对应的GPIO端口,他们对应关系如下所示:
按键对应的GPIO:
Key1
àGPG0
Key2
àGPG3 Key3
àGPG5 Key4
àGPG6 Key5
àGPG7 Key6
àGPG11
蜂鸣器对应的GPIO:
Beep
àGPB0
LED
对应的GPIO:
LED1
àGPB5
LED2
àGPB6
LED3
àGPB7
LED4
àGPB8
在这里需要将按键设置为输入的模式,而且蜂鸣器和LED必须设置成输出的模式,注意:
对于LED的数据寄存器中0代表这个LED将被点亮,而且1表示熄灭
但是对应蜂鸣器来说1代表发出声音,而0则代表不出声音。
在此程序中并没有使用到按键的中断,而是使用了一个死循环去实现的。并且这个程序保护两个部分,一个是汇编程序编写的引导部分,因为这是一个裸机的程序,即没有操作系统的程序,因此想要在板子上运行C程序必须进行相应的初始化的工作,这个就是汇编程序的功能。汇编代码如下:
IMPORT Main
CODE32
AREA Init,CODE,READONLY
ENTRY
ldr r0, =0x53000000
mov r1, #0x0
str r1, [r0]
ldr sp, =1024 * 4
bl Main
main_loop
b main_loop
END
这是一个非常简单的汇编引导程序,我并没有使用那个自带的2440test中的引导程序,主要是为了让简化一点,在这个程序中只是初始化了一下堆栈并且关闭了WatchDog,因为C语言的运行环境必须要用到堆栈。
下面是C语言的部分,也是这个程序最核心的部分:
/*************************************************
Function name: 这是一个led、按键和蜂鸣器的实验
Parameter
: 无
Description : 按下按键1(key1)将会点亮led1,并且蜂鸣器将发出响声,按键1-4依次对应,按下按键5(key5)点亮所有的led,按下按键6(key6)关闭所有的led
Return
: 无
Argument
: 无
Autor & date : Hyfeng
**************************************************/
//I/O port
#define rGPBCON
(*(volatile unsigned *)0x56000010) //port B control
#define rGPBDAT
(*(volatile unsigned *)0x56000014) //port B data
#define rGPBUP
(*(volatile unsigned *)0x56000018) //pull-up port B
#define rGPGCON
(*(volatile unsigned *)0x56000060) //port G control
#define rGPGDAT
(*(volatile unsigned *)0x56000064) //port G data
#define rGPGUP
(*(volatile unsigned *)0x56000068) //pull-up port G
//上面的这个部分是通过查询手册得到的
//设置点亮LED
#define LED1_ON
~(1<<5)
#define LED2_ON
~(1<<6)
#define LED3_ON
~(1<<7)
#define LED4_ON
~(1<<8)
#define LEDS_ON
(LED1_ON & LED2_ON & LED3_ON & LED4_ON)
//设置关闭beep
#define BEEP_OFF
~(1<<0)
//设置熄灭LED
#define LED1_OFF (1<<5)
#define LED2_OFF (1<<6)
#define LED3_OFF (1<<7)
#define LED4_OFF (1<<8)
#define LEDS_OFF (LED1_OFF | LED2_OFF | LED3_OFF | LED4_OFF)
//设置开启beep
#define BEEP_ON (1<<0)
#define KEY1_ON
(1<<0)
#define KEY2_ON
(1<<3)
#define KEY3_ON
(1<<5)
#define KEY4_ON
(1<<6)
#define KEY5_ON
(1<<7)
#define KEY6_ON
(1<<11)
void delay(int times);
/*************************************************
Function name: key_init
Parameter
: void
Description : 初始化按键
Return
: void
Argument
: void
Autor & date : Hyfeng
**************************************************/
//将按键的状态设置为输入的状态
void key_init(void)
{
rGPGCON &= ~((3<<0)|(3<<6)|(3<<10)|(3<<12)|(3<<14)|(3<<22));}
/*************************************************
Function name: led_init
Parameter
: void
Description : 初始化led
Return
: void
Argument
: void
Autor & date : Hyfeng
**************************************************/
//将LED的状态设置为输出的状态
void led_init(void)
{
rGPBCON &= ~((3<<10)|(3<<12)|(3<<14)|(3<<16));
rGPBCON |= (1<<10)|(1<<12)|(1<<14)|(1<<16);
}
/*************************************************
Function name: beep_init
Parameter
: void
Description : 初始化beep
Return
: void
Argument
: void
Autor & date : Hyfeng
**************************************************/
//将蜂鸣器的状态设置为输出的状态
void beep_init(void)
{
rGPBCON &= ~((3<<0));
rGPBCON |= (1<<0);
}
/*************************************************
Function name: delay
Parameter
: times
Description : 实现程序延迟的功能
Return
: void
Argument
: void
Autor & date : Hyfeng
**************************************************/
void delay(int times)
{
int i;
for(;times>0;times--)
for(i=0;i<10000;i++);
}
/*************************************************
Function name: Main
Parameter
: void
Description : 主函数
Return
: void
Argument
: void
Autor & date : Hyfeng
**************************************************/
void Main(void)
{
led_init();
key_init();
beep_init();
rGPBDAT = rGPBDAT | LEDS_OFF;
while(1)
{
rGPBDAT = rGPBDAT & BEEP_OFF;
if(!(rGPGDAT & KEY1_ON))
{
rGPBDAT = rGPBDAT | LEDS_OFF | BEEP_ON;
rGPBDAT = rGPBDAT & LED1_ON;
delay(1);
}
if(!(rGPGDAT & KEY2_ON))
{
rGPBDAT = rGPBDAT | LEDS_OFF | BEEP_ON;
rGPBDAT = rGPBDAT & LED2_ON;
delay(1);
}
if(!(rGPGDAT & KEY3_ON))
{
rGPBDAT = rGPBDAT | LEDS_OFF | BEEP_ON;
rGPBDAT = rGPBDAT & LED3_ON;
delay(1);
}
if(!(rGPGDAT & KEY4_ON))
{
rGPBDAT = rGPBDAT | LEDS_OFF | BEEP_ON;
rGPBDAT = rGPBDAT & LED4_ON;
delay(1);
}
if(!(rGPGDAT & KEY5_ON))
{
rGPBDAT = rGPBDAT | LEDS_OFF | BEEP_ON;
rGPBDAT = rGPBDAT & LEDS_ON;
delay(1);
}
if(!(rGPGDAT & KEY6_ON))
{
rGPBDAT = rGPBDAT | LEDS_OFF | BEEP_ON;
delay(1);
}
}
}