S3C2440,仍然从最简单的IO口开始,不过加上IO中断,用于按键控制,
不再使用库函数,而是直接调用寄存器,寄存器映射见我的另外一篇文章
https://blog.csdn.net/pxy198831/article/details/86025258 S3C2440寄存器映射表
/******************************
*文件名:key.c
*功能: 按键程序
*创建者: 潘星宇
*最后修改:2013.03.26
*备注:
*
*******************************/
#include "key.h"
#include "touch.h"
/**************************************************
*函数名: get_bit_port_g *
*功能: 获取I/O口G对应位的状态 *
*出口参数:对应位的状态 *
*入口参数:想要获取状态的位号 *
*备注: *
*
*************************************************/
int get_bit_port_f (char port_bit)
{
int temp_data; //临时变量
temp_data = rGPFDAT; //获取端口G的数据
temp_data = temp_data >> port_bit; //将需要获取状态的位右移至第0位
temp_data &= 0x0001; //将其余位清零
return (temp_data);
}
int get_bit_port_g (char port_bit)
{
int temp_data; //临时变量
temp_data = rGPGDAT; //获取端口G的数据
temp_data = temp_data >> port_bit; //将需要获取状态的位右移至第0位
temp_data &= 0x0001; //将其余位清零
return (temp_data);
}
/**************************************************************************
***** 函数名: EINT0_callback
***** 功能: 外部中断0回调函数
***** 参数: 无
***** 返回值: 无
***** 创建者: 潘星宇
***** 创建时间:2017-4-25
***** 最后更新: 2017-4-25
****************************************************************************/
void EINT0_callback(void) __irq
{
ClearPending(BIT_EINT0);
if (get_bit_port_f(0) == 0)
{
delay(200);
if (get_bit_port_f(0) == 0)
{
if(function_flag == 1)
{
function_flag = 4;
}
else
{
}
}
}
}
/**************************************************************************
***** 函数名: EINT1_callback
***** 功能: 外部中断1回调函数
***** 参数: 无
***** 返回值: 无
***** 创建者: 潘星宇
***** 创建时间:2017-4-25
***** 最后更新: 2017-4-25
****************************************************************************/
void EINT1_callback(void) __irq
{
ClearPending(BIT_EINT1);
if (get_bit_port_f(1) == 0)
{
delay(200);
if (get_bit_port_f(1) == 0)
{
if(function_flag == 1)
{
function_flag = 5;
}
else
{
}
}
}
}
/**************************************************************************
***** 函数名: EINT2_callback
***** 功能: 外部中断2回调函数
***** 参数: 无
***** 返回值: 无
***** 创建者: 潘星宇
***** 创建时间:2013-1-19
***** 最后更新: 2013-1-19
****************************************************************************/
void EINT2_callback(void) __irq
{
ClearPending(BIT_EINT2);
if (get_bit_port_f(2) == 0)
{
delay(200);
if (get_bit_port_f(2) == 0)
{
if(function_flag == 0)
{
function_flag = 1;
}
else if (function_flag == 1)
{
function_flag = 20;
}
else if ((function_flag == 3)||(function_flag == 4)||(function_flag == 5))
{
function_flag = 1;
}
else
{
}
}
}
}
/**************************************************************************
***** 函数名: EINT4_7_callback
***** 功能: 外部中断4回调函数
***** 参数: 无
***** 返回值: 无
***** 创建者: 潘星宇
***** 创建时间:2017-4-25
***** 最后更新: 2017-4-25
****************************************************************************/
void EINT4_7_callback(void) __irq
{
ClearPending(BIT_EINT4_7);
rEINTPEND=(1<<4); // 清中断挂起,否则将一直中断
if (get_bit_port_f(4) == 0)
{
delay(200);
if (get_bit_port_f(4) == 0)
{
if(function_flag == 1)
{
function_flag = 3;
}
else
{
}
}
}
}
void EINT8_23_callback(void) __irq
{
ClearPending(BIT_EINT8_23);
rEINTPEND=(1<<8); // 清中断挂起,否则将一直中断
if (get_bit_port_g(0) == 1)
{
delay(200);
if ((get_bit_port_g(0) == 1)&(red_bell_on == 1))
{
rGPBDAT &= ~0x1e0;
rGPBCON |=0x01;
rGPBDAT |= 0x1;
}
}
else if (get_bit_port_g(0) == 0)
{
delay(200);
if (get_bit_port_g(0) == 0)
{
rGPBDAT |= 0x1e0;
rGPBDAT &= 0x1e0;
}
}
// if (get_bit_port_g(14) == 0)
// {
// delay(200);
// if (get_bit_port_g(14) == 0)
// {
// }
// }
}
/**************************************************************************
***** 函数名: INT_initialize_key
***** 功能: 初始化按键中断
***** 参数: 无
***** 返回值: 无
***** 创建者: 潘星宇
***** 创建时间:2013-1-15
***** 最后更新: 2017-4-26
****************************************************************************/
void INT_initialize_key (void)
{ //第一步 配置I/O口特殊功能
rGPFCON &= ~((3<<0)|(3<<2)|(3<<4)|(3<<8)); //清零GPF0,1,2,4对应的控制位
rGPFCON |= (2<<0)|(2<<2)|(2<<4)|(2<<8); //设置GPF0,1,2,4为外部中断模式
rGPFUP |= (1|(1<<1)|(1<<2)|(1<<4)); //禁上拉
rGPGCON &= ~(3<<0); //清零GPG0对应的控制位
rGPGCON |= (2<<0); //设置GPG0为外部中断模式
rGPGUP |= 1; //禁止上拉
//第二步 配置其中断触发方式
rEXTINT0 &= ~((7<<0)|(7<<4)|(7<<8)|(7<<16)); //清零EIT0,1,2,4对应的控制位
rEXTINT0 |= (2<<0)|(2<<4)|(2<<8)|(2<<16); //设置EIT0,1,2,4为下降沿触发中断模式
rEXTINT1 &= ~(7<<0); //清零EIT8
rEXTINT1 |= (6<<0); //设置EIT8为双边沿触发中断模式
// //第三步 清子中断标志位,打开子屏蔽
rEINTPEND |= ((1<<4)|(1<<8)); //清子中断
rEINTMASK &= ~((1<<4)|(1<<8)); //打开子屏蔽
//第四步 清总中断:源挂起和中断挂起
ClearPending(BIT_EINT0); //清以下5个总中断和挂起标志
ClearPending(BIT_EINT1);
ClearPending(BIT_EINT2);
ClearPending(BIT_EINT4_7);
ClearPending(BIT_EINT8_23);
//第五步 设置中断服务函数入口
pISR_EINT0 = (unsigned int)EINT0_callback;
pISR_EINT1 = (unsigned int)EINT1_callback;
pISR_EINT2 = (unsigned int)EINT2_callback;
pISR_EINT4_7 = (unsigned int)EINT4_7_callback;
pISR_EINT8_23 = (unsigned int)EINT8_23_callback;
//开总中断
EnableIrq(BIT_EINT0);
EnableIrq(BIT_EINT1);
EnableIrq(BIT_EINT2);
EnableIrq(BIT_EINT4_7);
EnableIrq(BIT_EINT8_23);
rGPBDAT = 0x5e0; //关LED
rGPBCON =0x00115401; //设置GPB5、GPB6、GPB8、GPB10为输出
rGPBUP =0x7ff; //禁止上拉
}
请注意看程序注释,尤其是中断的步骤,很关键
头文件如下:
#ifndef KEY_H
#define KEY_H
#include "2440addr.h"
#include "common_functions.h"
#include "touch.h"
#include "global_value.h"
/**************************************************************************
***** 函数名: INT_initialize_key
***** 功能: 初始化按键中断
***** 参数: 无
***** 返回值: 无
***** 创建者: 潘星宇
***** 创建时间:2013-1-15
***** 最后更新: 2013-1-19
****************************************************************************/
extern void INT_initialize_key (void);
extern int get_bit_port_g (char port_bit);
#endif