用单片机中断来扫描键盘的程序
    

/*
程序效果:用51单片机的中断来扫描键盘,按下按键,蜂鸣器响,数码管有相应的键值
    显示,按下E键继电器关,按下C键继电器开。
    这与上一程序的功能相同,比上一程序简洁
    但理解相对困难些。
开发设计:http://www.51hei.com/
*/

#include<reg52.h> //头文件
#include<intrins.h>
#define uchar unsigned char //宏定义
#define uint unsigned int
sbit jdq=P3^5; //位声明,驱动继电器管脚
sbit fmq=P3^4; //位声明,驱动蜂鸣器管脚
code uchar table[]={0x3f,0x06,0x5b,//数码管显示的数值
0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71};
code uchar key_tab[17]={ //此数组为键盘编码
0xed,0x7e,0x7d,0x7b, // 0,1,2,3,
0xbe,0xbd,0xbb,0xde, // 4,5,6,7,
0xdd,0xdb,0x77,0xb7, // 8,9,a, b,
0xee,0xeb,0xd7,0xe7,0xff}; // c,d,e,f,
uchar l_key=0x00; //定义变量,存放键值
uchar l_keyold=0xff; //作为按键放开否的凭证
void readkey(); //扫描键盘,获取键值
void display(uchar *lp,uchar lc); //显示子函数
void delay(); //延时子函数
void main() //主函数
{
  EA=1; //打开总中断
  EX0=1; //打开外部中断
  P0=0xf0; //键值高4位为高电平,低4位为低电平
  while(1)
  {
    display(&l_key,1); //调用显示子函数
    if(l_key==14) //是否按下E键,是则关闭继电器
     jdq=1;
    if(l_key==12) //是否按下C键,是则打开继电器
    jdq=0;
  }
}
void key_scan() interrupt 0//外部中断0,0的优先级最高
{
  EX0=0; //在读键盘时,关闭外部中断,防止干扰带来的多次中断
  TMOD&=0xf1; //设置定时器为工作方式1
  TH0=0x2e; //设置初值,为12毫秒,十进制值为11776
  TL0=0x00;
  ET0=1; //开启定时器中断0
  TR0=1; //启动定时器计数
}
void time0() interrupt 1 //定时器0的中断函数
{
  TR0=0; //关闭定时器0
  readkey(); //定时12ms后产生中断,调用此函数,读取键值
}
void readkey() //扫描键盘子函数
{
  uchar i,j,key; //定义局部变量
  j=0xfe; //设定初值
  key=0xff;
  for(i=0;i<4;i++) // 逐列扫描键盘
  {
    P0=j;
    if((P0&0xf0)!=0xf0) //有按键按下,高4位不可能全为1
    {
      key=P0; //读取P0口的值,推出循环,否则循环下次
      break;
    }
    j=_crol_(j,1); //此函数的功能是:左移循环
  }
  if(key==0xff) //如果读取不到P0口的值,如干扰,则返回
  {
    l_keyold=0xff;
    P0=0xf0; // 恢复P0口的值,等待按键按下
    fmq=1;
    EX0=1; //在返回前,打开外部中断
    return;
  }
  fmq=0; //有按键按下,打开蜂鸣器
  if(l_keyold==key) // 检查按键放开否,如果相等表明没有放开
  {
    TH0=0x2e; //设置初值
     TL0=0x00;
    TR0=1; //继续启动定时器,检查按键放开否
    return;
  }
  TH0=0x2e;
  TL0=0;
  TR0=1; //启动定时器
  l_keyold=key; //获取键值,作为放开否的凭证
  for(i=0;i<17;i++) //查表获得相应的16进制值存放到l_key中
  {
    if(key==key_tab[i])
    {
      l_key=i;
      break;
    }
}
//程序运行到此,就表明有键值存放到l_key中,主程序
//就可以检测键盘值并作相应的处理
}
void display(uchar *lp,uchar lc) //显示子函数
{
  uchar i; //定义局部变量
  P1=0xf8; //点亮第一个数码管
  P2=0; //P2口为输出值
  for(i=0;i<lc;i++) //循环显示
   {
    P2=table[lp[i]]; //查表获得相应的要显示的数字的数码段
    delay(); //延时
    P2=0; //清零,准备显示下一个数值
  }
}
void delay() //延时子函数
{
  _nop_();_nop_();_nop_();_nop_();_nop_();
}
如果程序无法编译,请删除所有前导空白.

相关阅读
  • C51单片机矩阵键盘扫描去抖程序-控
  • C51单片机矩阵键盘扫描去抖程序-控
  • 初学者拿来就可以用的程序四(中断
  • 51单片机定时、中断练习:用延时程
  • 【程序】矩阵式中断扫描键盘的设计
  • 【程序】用 STM32 来驱动ZLG7289多
  • 中断法键盘扫描c程序
  • STM32 8按键扫描程序(用ADC1扫描
  • 为什么不能用循环中断组织块OB35来
  • 用51单片机的外部中断来测频率
  • 用pcomm开发pc机与单片机的通信程
  • 键盘扫描程序
  • 用avr单片机模拟的串口程序
  • 单片机驱动标准PC机键盘的C51程序
  • AVR单片机采用USARTUART发送中断程
  • PIC 单片机中断程序
  • 【程序】节约单片机端口资源的键盘
  • 【程序】用8031单片机控制的数字钟
  • 【程序】51单片机计时中断与外部中
  • 矩阵键盘扫描程序
  • 单片机驱动4x4矩阵式键盘输入程序
  •  



     
     
         

    收录时间:2016年10月17日 16:22:27 来源:单片机教程网 作者:匿名
    上一篇:第2课 keil软件及工程文件的建立  (电脑版  手机版)
     
    创建分享人
    光影东头
    最新问题
     
    喜欢此文章的还喜欢
    Copyright by www.chinabaike.com;All rights reserved. 联系:QQ:469681782