天天看點

2*3鍵盤中斷

//=========================================================================

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

    }

}