eva 发表于 2012-8-21 14:34:19

采用B口电平变化中断查键方式识别键盘 转

/* ****************************************************************
** 功能描述: 采用B口电平变化中断查键方式识别键盘,按下K1键时第一个数码管数码管显示1,按下K2键时显示2,按下K3键时显示3,按下K4键时显示4
*************************************************************** */
#include "pic18.h"/* PIC18系列的头文件 */
const char table={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90, 0x88,0x83,0xc6,0xa1,0x86,0x8e};
      /* 不带小数点的显示段码表,依顺序为0-F共16个 */
const char table0={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10};
      /* 带小数点的0-9显示段码表 */
unsigned char key=0;// 按键键值,=1表示1号键按下,…,=4表4号键按下
unsigned char PORTB_keyflag=0;//=1有键按下,=0无按按下
/* ****************************************************************
** 函 数 名: initial()
** 功能描述: 系统初始化子程序,放在程序首部
*************************************************************** */
void initial()
{
INTCON=0x00;    /* bit7-bit0:关总中断 */
ADCON1=0X07;    /* 设置数字输入输出口 */
PIE1=0;   /* PIE1 的中断不使能 */   
PIE2=0;   /* PIE2 的中断不使能 */
PIE3=0;   /* PIE3 的中断不使能 */
}
/* ****************************************************************
** 函 数 名: SPIinitial()
** 功能描述: SPI输出初始化子程序
*************************************************************** */
void SPIinitial()
{
TRISA=TRISA&0xdf;/* 设置RA5输出74HC595锁存信号的引脚为输出 */
TRISC=TRISC&0xd7;// SDO(RC5)引脚为输出,SCK(RC3)引脚为输出
SSPCON1=0x30;   // SSPEN=1;CKP=1,FOSC/4
SSPSTAT=0xC0;   // 时钟下降沿发送数据
SSPIF=0;   // 清除SSPIF标志
}
/* ****************************************************************
** 函 数 名: SPILED()
** 功能描述: SPI传输数据(发送数据)子程序
*************************************************************** */
void   SPILED(char data)
{
SSPBUF=data;    /* 启动 SPI 发送 */
do
{
   ;
}while(SSPIF==0);/* 等待SPI 发送完成 */
SSPIF=0;   /* 清SPI 发送完成标志 */
}
/* ****************************************************************
** 函 数 名: display(unsignedchardata)
** 功能描述: 在第8个数码管显示数据,其余7个不显示(全暗)
*************************************************************** */
void display(unsignedchardata)
{
unsignedchark;
RA5=0;   /* 准备锁存显示数据 */
data=table;/* 查与显示数据对应的段码 */
SPILED(data);   /* 发送显示段码 */
for(k=1;k<8;k++)
{
SPILED(0Xff);/* 发送当前数码管不显示段码 */
}
RA5=1;   /* 给锁存信号,显示数字 */
}
/* ****************************************************************
** 函 数 名: PORTB_Interrupt_Initial()
** 功能描述: PORTB口电平变化中断初始化
*************************************************************** */
void PORTB_Interrupt_Initial()
{
TRISB=TRISB|0xf0; // PORTB工作在电平变化中断方式,bit7-bit4设置为输入
INTCON=INTCON|0x08;// RBIE=1,使能RB电平变化中断
INTCON=INTCON&0xfe;// RBIF=0,清RB电平变化中断标志
INTCON2=INTCON2&0x7f; // 在电平变化中断方式下,B口电平弱上拉,RBPU=0
RBIP=0;   // RB电平变化中断为低优先级中断
TRISB1=0;    // 设置K1为输出
TRISA3=0;    // 设置K2为输出
TRISE0=0;    // 设置K3为输出
TRISE1=0;    // 设置K4为输出
RB1=0;   /* 设置K1-K4平时为低电平,4个键的另一端均接到
RB4上,平时RB4为高电平(上拉),有键
按下后,被K1-K4下拉为低电平,产生中断 */
RA3=0;
RE0=0;
RE1=0;
PORTB=PORTB;    // 设置PORTB口电平变化初始条件
}
/* ****************************************************************
** 函 数 名: DELAY_PORTB_Interrupt()
** 功能描述: PORTB口电平变化中断查键延时防抖子程序
*************************************************************** */
voidDELAY_PORTB_Interrupt()
{
unsignedinti;
for(i = 553; i>0;i--)
i=i;
}
/* ****************************************************************
** 函 数 名: KEYSCAN_PORTB_Interrupt()
** 功能描述: PORTB口电平变化中断查键键扫描子程序
*************************************************************** */
void KEYSCAN_PORTB_Interrupt()
{
if(RB4==0)   // 有键按下
{
DELAY_PORTB_Interrupt();// 若有键按下,则软件延时防抖
if (RB4==1) return;// 防抖后无键按下,是抖动,不做按键处理,返回
//以下为防抖后仍有键按下的查键值
RB1=0;   // 设置K1为低电平
RA3=0;   // 设置K2为低电平
RE0=1;   // 设置K3为高电平
RE1=1;   // 设置K4为高电平,判断按键是否在K1、K2之间
if(RB4==0)    // 按键是k1k2中的一个
{
   RA3=1;   // (只有)K1为低电平
   if(RB4==0)key=1; // 仅K1为低电平时RB4被下拉,K1键按下
   else key=2;// K1k2为低电平RB4被下拉,K1没按下,是K2按下
   PORTB_keyflag=1; //新键按下标志,=1表示有新键按下
   RB1=0;   //设置电平变化产生中断的初始条件
   RA3=0;
   RE0=0;
   RE1=0;
   PORTB=PORTB;
   return;
}
RB1=1;// 不是在K1k2间按下,查K3k4,设K1K2为高电平,不查K1k2
RA3=1;
RE0=0;    // 设置K3为低电平
RE1=0;    // 设置K4为低电平
if(RB4==0)   // 若有键按下(无键按下可视为防抖)
{
   RE1=1;   // 仅设置K3为低电平
   if(RB4==0)key=3; // 仅K3为低电平时RB4被下拉,K3键按下
   else key=4;// K3k4为低电平RB4被下拉,K3没按下,是K4按下
}
PORTB_keyflag=1;//新键按下标志,=1表示有新键按下
}
RB1=0;   //设置电平变化产生中断的初始条件
RA3=0;
RE0=0;
RE1=0;
PORTB=PORTB;
}
/* ****************************************************************
** 函 数 名: interrupt low_priority LOW_ISR()
** 功能描述: 低优先级中断子程序:PORTB口RB电平变化中断
*************************************************************** */
void interrupt low_priority LOW_ISR()
{
if(RBIF==1)      //PORTB口RB电平变化中断
{
KEYSCAN_PORTB_Interrupt(); //查键子程序
RBIF=0;      //清中断标志
}
}
main()
{
initial();
SPIinitial();   /* spi显示初始化 */
PORTB_Interrupt_Initial();// PORTB口电平变化中断初始化
IPEN=1;       // 使能中断高低优先级
INTCON=INTCON|0xc0;    //打开总中断和外围接口中断
display(0XFF);   /* 清数码管当前显示即清屏 */
while(1)
{
if(PORTB_keyflag==1)   // 若有按键按下
{
   display(key);   //显示按键键值(1-4)
   PORTB_keyflag=0;//清按键按下标志
}
}
}

页: [1]
查看完整版本: 采用B口电平变化中断查键方式识别键盘 转