天天看点

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函数

    }

}