//=========================================================================
// 工程名称: Demo2440_irq23
// 组成文件: key23_irq.c
// 功能描述: 2*3键盘,通过中断判断按键到来,通过扫描得出键值
// 硬件连接: GPF0~GPF1与行相连, GPF2~GPF4与列相连
//=========================================================================
#include "2440addr.h"
#include "2440lib.h"
#include "uart.h"
void __irq Eint2Handler(void);
void __irq Eint3Handler(void);
void __irq Eint4_7Handler(void);
void EXIT_IRQ_init(int num ,void __irq (* Exit_Handler)(void),int type);
int keyValue = 0;
void delay(int tim)
{
while(tim-- > 0);
}
// 初始化IO口
void key23_Init()
{
// GPF0,1输出0,GPF2,3,4中断
rGPFCON &= ~((0x03<<(0<<1))|(0x03<<(1<<1))|(0x03<<(2<<1))|(0x03<<(3<<1))|(0x03<<(4<<1)));
rGPFCON |= ((0x01<<(0<<1))|(0x01<<(1<<1))|(0x02<<(2<<1))|(0x02<<(3<<1))|(0x02<<(4<<1)));
rGPFUP &= ~((0x01<<2)|(0x01<<3)|(0x01<<4));
rGPFDAT &= ~((0x01<<0)|(0x01<<1));
}
// 行扫IO状态
void key23_ReverseIO()
{
rGPFCON &= ~((0x03<<0*2)|(0x03<<1*2)|(0x03<<2*2)|(0x03<<3*2)|(0x03<<4*2));// GPF0,1输入
rGPFCON |= ((0x01<<2*2)|(0x01<<3*2)|(0x01<<4*2)); //GPF2,3,4输出 0
rGPFUP &= ~((0x01<<0)|(0x01<<1)); //上拉必需使能,否则读出全0
rGPFDAT &= ~((0x01<<2)|(0x01<<3)|(0x01<<4));
delay(100);
}
// 将IO口的状态翻译成键值
int key23_TranslateKey(int row_key, int col_num)
{
int key = 0;
switch(row_key)
{
case 0x01:
key = (col_num + 2);
break;
case 0x02:
key = (col_num - 1);
break;
default:
key = 0;
break;
}
return key;
}
int key23_Scan(int irq_number)
{
unsigned int dat;
int key = 0;
key23_ReverseIO();// 翻转指定的列的IO口输出状态
dat = rGPFDAT & 0x03; // 读取行状态
if(dat != 0x03)
{
delay(100000); // 延时去抖动
if(dat == (rGPFDAT&0x03))
{
key = key23_TranslateKey(dat,irq_number); // 有效按键,计算键值
}
}
key23_Init();
return key;
}
int Main()
{
memcpy(0x0,(unsigned char *)0x30000000,0x1000); //拷贝程序到0地址(中断向量表)
ChangeMPllValue(0x5c,1,1);
ChangeClockDivider(14,12);
Uart_Select(0);
myUart_Init(50000000,115200);
Uart_Printf("\nEXIT INT test\n");
Uart_Printf("2*3键盘测试程序\n");
key23_Init();
EXIT_IRQ_init(2,Eint2Handler,2);
EXIT_IRQ_init(3,Eint3Handler,2);
EXIT_IRQ_init(4,Eint4_7Handler,2);
while(1)
{
if(keyValue != 0)
{
Uart_Printf("keyValue = %d\n", keyValue);
keyValue = 0;
}
}
}
//====================================================
// 语法格式:void EXIT_IRQ_init(int num)
// 功能描述: 外部中断1~3初始化
// 入口参数:
// num: 中断初始化序号
// Exit_Handler:
// 中断服务程序
// type: 0:低电平触发
// 1:高电平触发
// 2:下降沿触发
// 4:上升沿触发
// 6:双沿触发
// 出口参数: 无
//====================================================
void EXIT_IRQ_init(int num , void __irq ( *Exit_Handler)(void),int type)
{
switch(num)
{
case 0:
pISR_EINT0 = (unsigned)Exit_Handler; //中断函数的入口地址
rEXTINT0 &= ~(0x07);
rEXTINT0 |= (type); //设置中断触发类型
ClearPending(BIT_EINT0); //清除中断标志,防止勿中断
EnableIrq(BIT_EINT0); //使能中断
break;
case 1:
pISR_EINT1 = (unsigned)Exit_Handler; //中断函数的入口地址
rEXTINT0 &= ~(0x07<<4);
rEXTINT0 |= type<<4; //设置中断触发类型
ClearPending(BIT_EINT1); //清除中断标志,防止勿中断
EnableIrq(BIT_EINT1);
break;
case 2:
pISR_EINT2 = (unsigned)Exit_Handler; //中断函数的入口地址
rEXTINT0 &= ~(0x07<<8);
rEXTINT0 |= (type<<8); //设置中断触发类型
ClearPending(BIT_EINT2); //清除中断标志,防止勿中断
EnableIrq(BIT_EINT2);
break;
case 3:
pISR_EINT3 = (unsigned)Exit_Handler; //中断函数的入口地址
rEXTINT0 &= ~(0x07<<12);
rEXTINT0 |= (type<<12); //设置中断触发类型
ClearPending(BIT_EINT3); //清除中断标志,防止勿中断
EnableIrq(BIT_EINT3);
break;
case 4:
pISR_EINT4_7 = (unsigned)Exit_Handler; //中断函数的入口地址
rEXTINT0 &= ~(0x07<<16);
rEXTINT0 |= (type<<16); //设置中断触发类型
ClearPending(BIT_EINT4_7); //清除中断标志,防止勿中断
EnableIrq(BIT_EINT4_7);
rEINTMASK &= ~0x0010;
break;
default:
break;
}
}
void __irq Eint2Handler(void)
{
ClearPending(BIT_EINT2); //清除中断标志
//Uart_Printf("the irq2 test\n");
keyValue = key23_Scan(2); //键值返回给Main函数
}
void __irq Eint3Handler(void)
{
ClearPending(BIT_EINT3); //清除中断标志
//Uart_Printf("the irq3 test\n");
keyValue = key23_Scan(3); //键值返回给Main函数
}
void __irq Eint4_7Handler(void)
{
ClearPending(BIT_EINT4_7); //清除中断标志
if(rEINTPEND & 0x10)
{
//Uart_Printf("the irq4 test\n");
rEINTPEND |= 0x10;
keyValue = key23_Scan(4); //键值返回给Main函数
}
}