微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 74HC 164键盘扫描程序问题

74HC 164键盘扫描程序问题

时间:10-02 整理:3721RD 点击:


#include "REG52.H"

#include  "stdio.h"

#include "intrins.h"

?

#define uchar unsigned char

#define uint unsigned int


sbit LCD_RS=P2^4;

sbit LCD_RW=P2^5;

sbit LCD_EN=P2^6;

sbit LCD_BG=P2^3; //当LCD_BG=0时LCD1602屏幕不亮,当LCD_BG=1时LCD1602屏幕亮

uchar code table[]="0123456789 ";


void LCD_init();

void display_xy(uchar x,uchar y);

void display_int(uchar x,uchar y,int num);


sbit key_clk=P3^4;

sbit key_dat=P3^5;

sbit key_row1=P3^6;

sbit key_row2=P3^7;


uchar row,key=0;

uchar buffer;


void  key_sendbyte(uchar byte);

uchar  key_value();

void  key_scan();


void Delayms(uint z)

{

  uint i,j;

  for(i=z;i>0;i--)

  for(j=135;j>0;j--);

}

/*****LCD1602初始化********/

void Busy()

{  

  uchar temp=0x80;  //初始化temp最高位为1,使得能够进入下面的while循环

  P0=0xff;          //(P0就是8个数据口)

  LCD_RS=0;             //设置命令操作

  LCD_RW=1;             //设置读操作

  LCD_EN=1;             //使能

  Delayms(5);       //(这是设的延时函数,不用解释)

while(temp & 0x80)  //判忙,一旦表达式为假,即temp最高位为0,则表示1602不忙,跳出while.

{

  temp=P0;

  Delayms(10);          //把p0的的高位读入temp,延时

}

  LCD_EN=0;    //关闭使能信号

}

/*写指令数据到LCD */

void LCD_wcmd(uchar cmd)

{

Busy();         //忙闲信号的判断

LCD_RS = 0;

LCD_RW = 0;

LCD_EN = 0;

P0 = cmd;

Delayms(5);

LCD_EN = 1;

Delayms(5);

LCD_EN = 0;

}


/*写显示数据到LCD */

void LCD_wdat(uchar dat)

{

Busy();

LCD_RS = 1;

LCD_RW = 0;

LCD_EN = 0;

P0 = dat;

Delayms(5);

LCD_EN = 1;

Delayms(10);

LCD_EN = 0;

}


/*LCD初始化*/

void LCD_init()

{

LCD_wcmd(0x38);        //16*2显示,5*7点阵,8位数据

Delayms(5);

LCD_wcmd(0x38);        //16*2显示,5*7点阵,8位数据

Delayms(5);

LCD_wcmd(0x38);

Delayms(5);         //三次初始化,确保完成

LCD_wcmd(0x0c); //显示开,关光标

Delayms(5);

LCD_wcmd(0x06); //移动光标

Delayms(5);

LCD_wcmd(0x01); //清除LCD的显示内容

Delayms(5);

}


/*设置光标位置, x是列号,y是行号*/

void display_xy(uchar x,uchar y)

{   

   //     LCD_wcmd(0x01); //清楚光屏

   if(y==1)

           x+=0xc0;        //0xc0第二行首地址

   else

           x+=0x80; //0x80第一行首地址

           LCD_wcmd(x);

}  

/*在具体位置显示一个整数*/

void display_int(uchar x,uchar y,long num)

{

uint a,b,c,d,e;

a=num/10000;                         // 万位

b=num%10000/1000;         // 千位

c=num%10000%1000/100;         // 百位

d=num%10000%1000%100/10;         // 十位

e=num%10;         // 个位

display_xy(x,y);

if(num<0)

{

   LCD_wdat(0xb0);

   a=-a;

   b=-b;

   c=-c;

d=-d;

e=-e;

}

if(a!=0)

   LCD_wdat(table[a]);

if(a!=0|b!=0)

           LCD_wdat(table);

if(a!=0|b!=0|c!=0)

          LCD_wdat(table[c]);

if(a!=0|b!=0|c!=0|d!=0)

       LCD_wdat(table[d]);

LCD_wdat(table[e]);

}         


//2*8键盘


void key_sendbyte(uchar byte)   //串行输出子程序

{

       uint i;                  //局部变量i

for(i=0;i<8;i++)         //循环8次

{

   key_clk=0;          //将时钟信号设为低电平

key_dat=byte&0x80; //(0x80即十进制的128, 二进制的10000000 按位发送)

key_clk=1;         //再将时钟信号设置为高电平,将输出一个时钟信号的上升沿

byte<<= 1;        //byte变量左移一位

     }

}

uchar key_value()

{

    uchar key_bit,i;

buffer=0xff;

key_sendbyte(0x00);

if(!(key_row1&key_row2))

  {

    Delayms(10);           //消除按键抖动

if(!(key_row1&key_row2))         //有键按下

{

if(!key_row1)         //第一行有键按下

  {

    row=0;

key_bit=0xfe;

for(i=0;i<8;i++)

{

  key_sendbyte(key_bit);  //查看是否是这个数值的键按下

  if(!key_row1)

  {

  buffer=key_bit;          //如果是,把键值存入buffer

break;

  }

  key_bit = _crol_(key_bit,1);        //如果不是,进行是否是下一个键按下的断定

}

return buffer;              //返回键值

}


if(!key_row2)              //第二行有键按下

{

  row=1;

  key_bit=0xfe;

  for(i=0;i<8;i++)

{

  key_sendbyte(key_bit);        //查看是否是这个数值的键按下

  if(!key_row2)

  {

  buffer=key_bit;           //如果是,把键值存入buffer

break;

  }

  key_bit = _crol_(key_bit,1);        //如果不是,进行是否是下一个键按下的断定

}

return buffer;          //返回键值

}

  }

}

}

void key_scan()

{

  uchar temp=0;

  temp=key_value();

if(row==0)

{

switch(temp)

{

case 0xfe:key=1;break;

case 0xfd:key=2;break;

case 0xfb:key=3;break;

case 0xf7:key=4;break;

case 0xef:key=5;break;

case 0xdf:key=6;break;

case 0xbf:key=7;break;

case 0x7f:key=8;break;

   default:break;

}

}

else

{

switch(temp)

           {

case 0xfe:key=9;break;

case 0xfd:key=10;break;

case 0xfb:key=11;break;

case 0xf7:key=12;break;

case 0xef:key=13;break;

case 0xdf:key=14;break;

case 0xbf:key=15;break;

case 0x7f:key=16;break;

   default:break;

           }

  }

}


void main ()

{

     LCD_init();  // 初始化LCD

     LCD_BG=1;

          while(1)

  {

    key_scan();

display_int(0,0,key);

display_int(0,1,buffer);

  }

  }

程序扫描不大键盘,不知为什么?


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top