英锐恩单片机论坛,Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流

 找回密码
 立即注册
搜索
电子烟方案单片机单片机开发深圳单片机开发
单片机方案国产单片机8位单片机电子烟方案开发
查看: 4546|回复: 0
打印 上一主题 下一主题

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

[复制链接]
跳转到指定楼层
1#
发表于 2012-8-21 14:34:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/* ****************************************************************
** 功能描述: 采用B口电平变化中断查键方式识别键盘,按下K1键时第一个数码管数码管显示1,按下K2键时显示2,按下K3键时显示3,按下K4键时显示4
*************************************************************** */
#include "pic18.h"  /* PIC18系列的头文件 */
const char table[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90, 0x88,0x83,0xc6,0xa1,0x86,0x8e};
      /* 不带小数点的显示段码表,依顺序为0-F共16个 */
const char table0[10]={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(unsigned  char  data)
** 功能描述: 在第8个数码管显示数据,其余7个不显示(全暗)
*************************************************************** */
void display(unsigned  char  data)
{
unsigned  char  k;

RA5=0;     /* 准备锁存显示数据 */
data=table[data];  /* 查与显示数据对应的段码 */
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口电平变化中断查键延时防抖子程序
*************************************************************** */
void  DELAY_PORTB_Interrupt()
{
unsigned  int  i;

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 下一条

小黑屋|公司首页|Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流 ( 粤ICP备09008620号 )

GMT+8, 2024-11-24 04:38 , Processed in 0.051167 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表