//=========================================================================
// 工程名稱: 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函數
}
}