求单片机 扫描法和反线法简介描述!急!!!

如题所述

第1个回答  2011-01-07
#include <reg52.h>//包含头文件
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e,0xff};

uchar keyscan(void),num;
void delay(uint i);

void main()
{
uchar key;
P2=0x00;//8数码管亮 按相应的按键,会显示按键上的字符
num=16;
while(1)
{
key=keyscan();//调用键盘扫描,

switch(key)
{
case 0x7e:num=0;break;//0 按下相应的键显示相对应的码值
case 0x7d:num=1;break;//1
case 0x7b:num=2;break;//2
case 0x77:num=3;break;//3
case 0xbe:num=4;break;//4
case 0xbd:num=5;break;//5
case 0xbb:num=6;break;//6
case 0xb7:num=7;break;//7
case 0xde:num=8;break;//8
case 0xdd:num=9;break;//9
case 0xdb:num=10;break;//a
case 0xd7:num=11;break;//b
case 0xee:num=12;break;//c
case 0xed:num=13;break;//d
case 0xeb:num=14;break;//e
case 0xe7:num=15;break;//f
}

P0=table[num];
}
}
uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法
{
uchar cord1,cord2;//行列值
P3=0x0f;
cord1=P3&0x0f;
if(cord1!=0x0f)
{
delay(100);
if(cord1!=0x0f)
{
cord1=P3&0x0f;
P3= cord1|0xf0;
cord2=P3&0xf0;
return(cord1+cord2);
}

}
return(0xff);
}

void delay(uint i)//延时函数
{
while(i--);
}
第2个回答  推荐于2016-01-02
  扫描法:
  以4*4矩阵按键为例,将全部行线置低电平,然后检测列线的状态。只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。若所有列线均为高电平,则键盘中无键按下。
  判断闭合键所在的位置: 在确认有键按下后,即可进入确定具体闭合键的过程。其方法是:依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。
  #include "reg52.h"
  #define uchar unsigned char
  #define uint unsigned int

  void Delay_1ms(uint i);
  uchar keyScan(void);
  void Main(void)
  {
  uchar keyValue; //存放键值,第一行的第一个为1第二行第一个为5,依次排列
  while(1)
  {
  P1 = 0xf0;
  if(P1 != 0xf0) //判断是否有键按下
  {
  Delay_1ms(20); //消除键抖动
  if(P1 != 0xf0) //在此判断是否有键按下
  {
  keyValue = keyScan(); //逐行扫描,判断是哪个按键按下
  }
  }

  //此处用于对不同键值做出不同反应
  }
  }
  uchar keyScan(void)
  {
  uchar temp,i,j,lineSelect[4]={0xef, 0xdf, 0xbf, 0x7f}; //数组用于线选
  for(j=0;j<4;j++) //循环四次用于四个行线依次拉低
  {
  P1=lineSelect[j]; //每根行线依次拉低
  temp=1;
  for(i=0;i<4;i++) //循环四次用于判断哪列有键按下
  {
  if(!(P1&temp)) //判断此列是否有键按下
  return (i+j*4); //返回键值,行*4+列,行和列的交叉处
  temp<<=1; //将目标移为下一列
  }
  }
  }
  void Delay_1ms(uint i) //延时函数
  {
  uchar x,j;
  for(j=0;j<i;j++)
  for(x=0;x<=148;x++);
  }

  线翻转法:
  Step 1:将列线作为输出线,行线作为输入线。置输出线全部为0,此时行线中呈低电平0的为按键所在行,如果全部都不是0,则没有按键按下。
  Step 2:将第一步反过来,即将行线作为输出线,列线作为输入线。置输出线全部为0,此时列线呈低电平的为按键所在的列。这样,就可以确定了按键的位置(X,Y)。
  试例程序:
  while(1)
  {
  P0=0x0F;\\读行线状态
  if((P0&0x0F)!=0x0F)
  {
  switch(P0)
  {
  case 0x07: i=3; break;
  case 0x0b: i=2; break;
  case 0x0d: i=1; break;
  case 0x0e: i=0; break;
  default: break;
  }
  }
  delay10ms();//软件去抖动
  P0=0xF0;//反转行和列上的电平
  if((P0&0xF0)!=0xF0)
  {
  switch(P0)
  {
  case 0x70: j=3; break;
  case 0xb0: j=2; break;
  case 0xd0: j=1; break;
  case 0xe0: j=0; break;
  default: break;
  }
  P1=num[j][i];//P1输出对应的按键值
  }
  }本回答被提问者和网友采纳
相似回答
大家正在搜