微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 如何用4x4矩阵键盘在1602上显示

如何用4x4矩阵键盘在1602上显示

时间:10-02 整理:3721RD 点击:
51单片机如何用4x4矩阵键盘在1602上输入两位三位等多位数,我只会1位。
程序如下:
#include<reg51.h>    //包含单片机寄存器的头文件
#include<intrins.h>  //包含_nop_()函数定义的头文件
unsigned char code digit[]={"0123456789ABCDEF"};     //定义字符数组显示数字
unsigned char code key_code[]={
              0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,
              0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77};
unsigned char code Str[]={"Input Temp"};    //说明显示的是温度
unsigned char code Temp[]={"Temp:"};             //说明显示的是温度
unsigned char code Cent[]={"Cent"};              //温度单位
unsigned char key;
/*******************************************************************************
以下是对液晶模块的操作程序
*******************************************************************************/
sbit RS=P2^0;           //寄存器选择位,将RS位定义为P2.0引脚
sbit RW=P2^1;           //读写选择位,将RW位定义为P2.1引脚
sbit E=P2^2;            //使能信号位,将E位定义为P2.2引脚
sbit BF=P0^7;           //忙碌标志位,,将BF位定义为P0.7引脚
/*****************************************************
函数功能:延时1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
void delay1ms()
{
   unsigned char i,j;
  for(i=0;i<4;i++)
   for(j=0;j<33;j++)
    ;   
}
/*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
void delaynms(unsigned char n)
{
   unsigned char i;
for(i=0;i<n;i++)
    delay1ms();
}
/*****************************************************
函数功能:判断液晶模块的忙碌状态
返回值:result。result=1,忙碌;result=0,不忙
***************************************************/
bit BusyTest(void)
  {
    bit result;
RS=0;       //根据规定,RS为低电平,RW为高电平时,可以读状态
    RW=1;
    E=1;        //E=1,才允许读写
    _nop_();   //空操作
    _nop_();
    _nop_();
    _nop_();   //空操作四个机器周期,给硬件反应时间
    result=BF;  //将忙碌标志电平赋给result
   E=0;         //将E恢复低电平
   return result;
  }
/*****************************************************
函数功能:将模式设置指令或显示地址写入液晶模块
入口参数:dictate
***************************************************/
void WriteInstruction (unsigned char dictate)
{   
    while(BusyTest()==1);   //如果忙就等待
  RS=0;                  //根据规定,RS和R/W同时为低电平时,可以写入指令
  RW=0;   
  E=0;                   //E置低电平(根据表8-6,写指令时,E为高脉冲,
                           // 就是让E从0到1发生正跳变,所以应先置"0"
  _nop_();
  _nop_();               //空操作两个机器周期,给硬件反应时间
  P0=dictate;            //将数据送入P0口,即写入指令或地址
  _nop_();
  _nop_();
  _nop_();
  _nop_();               //空操作四个机器周期,给硬件反应时间
  E=1;                   //E置高电平
  _nop_();
  _nop_();
  _nop_();
  _nop_();               //空操作四个机器周期,给硬件反应时间
   E=0;                  //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:指定字符显示的实际地址
入口参数:x
***************************************************/
void WriteAddress(unsigned char x)
{
     WriteInstruction(x|0x80); //显示位置的确定方法规定为"80H+地址码x"
}
/*****************************************************
函数功能:将数据(字符的标准ASCII码)写入液晶模块
入口参数:y(为字符常量)
***************************************************/
void WriteData(unsigned char y)
{
    while(BusyTest()==1);  
   RS=1;           //RS为高电平,RW为低电平时,可以写入数据
   RW=0;
   E=0;            //E置低电平(根据表8-6,写指令时,E为高脉冲,
                     // 就是让E从0到1发生正跳变,所以应先置"0"
   P0=y;           //将数据送入P0口,即将数据写入液晶模块
   _nop_();
   _nop_();
    _nop_();
     _nop_();       //空操作四个机器周期,给硬件反应时间
   E=1;           //E置高电平
   _nop_();
   _nop_();
   _nop_();
  _nop_();        //空操作四个机器周期,给硬件反应时间
  E=0;            //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:对LCD的显示模式进行初始化设置
***************************************************/
void LcdInitiate(void)
{
    delaynms(15);               //延时15ms,首次写指令时应给LCD一段较长的反应时间
    WriteInstruction(0x38);     //显示模式设置:16×2显示,5×7点阵,8位数据接口
delaynms(5);                //延时5ms ,给硬件一点反应时间
    WriteInstruction(0x38);
delaynms(5);               //延时5ms ,给硬件一点反应时间
WriteInstruction(0x38);     //连续三次,确保初始化成功
delaynms(5);               //延时5ms ,给硬件一点反应时间
WriteInstruction(0x0c);     //显示模式设置:显示开,无光标,光标不闪烁
delaynms(5);               //延时5ms ,给硬件一点反应时间
WriteInstruction(0x06);     //显示模式设置:光标右移,字符不移
delaynms(5);                //延时5ms ,给硬件一点反应时间
WriteInstruction(0x01);     //清屏幕指令,将以前的显示内容清除
delaynms(5);             //延时5ms ,给硬件一点反应时间
}
/**********************************************************
键盘扫描子函数
**********************************************************/
unsigned char  keyscan()  
{
  unsigned char  scan1,scan2,keycode,j;
   P1=0xf0;
   scan1=P1;
   if((scan1&0xf0)!=0xf0)           //判键是否按下
   {
     delaynms(30);                   //延时30ms
     scan1=P1;
     if((scan1&0xf0)!=0xf0)         //二次判键是否按下
     {
        P1=0x0f;
        scan2=P1;
        keycode=scan1|scan2;         //组合成键编码
        for(j=0;j<=15;j++)
        {
           if(keycode== key_code[j])  //查表得键值
           {
              key=j;
              return(key);
           }
        }
     }
   }
   else  P1=0xff;
   return (16);
}
/******************************************************************************
以下是与温度有关的显示设置
******************************************************************************/
/*****************************************************
函数功能:显示说明信息
***************************************************/   
void display_explain(void)
{
       unsigned char i;
        WriteAddress(0x00);    //写显示地址,将在第1行第1列开始显示
      i = 0;                //从第一个字符开始显示
    while(Str[i] != '\0')  //只要没有写到结束标志,就继续写
    {      
     WriteData(Str[i]);   //将字符常量写入LCD
     i++;                 //指向下一个字符
     delaynms(100);        //延时100ms较长时间,以看清关于显示的说明
    }
}
/*****************************************************
函数功能:显示温度符号
***************************************************/   
void display_symbol(void)
{
       unsigned char i;
        WriteAddress(0x40);    //写显示地址,将在第2行第1列开始显示
      i = 0;                //从第一个字符开始显示
    while(Temp[i] != '\0')  //只要没有写到结束标志,就继续写
    {      
     WriteData(Temp[i]);   //将字符常量写入LCD
     i++;                 //指向下一个字符
     delaynms(50);        //延时1ms给硬件一点反应时间
    }
}
/*****************************************************
函数功能:显示温度的小数点
***************************************************/   
void  display_dot(void)
{         
  WriteAddress(0x49);   //写显示地址,将在第2行第10列开始显示     
  WriteData('.');      //将小数点的字符常量写入LCD
  delaynms(50);         //延时1ms给硬件一点反应时间  
}
/*****************************************************
函数功能:显示温度的单位(Cent)
***************************************************/   
void  display_cent(void)
{
           unsigned char i;   
        WriteAddress(0x4c);        //写显示地址,将在第2行第13列开始显示
      i = 0;                    //从第一个字符开始显示
    while(Cent[i] != '\0')     //只要没有写到结束标志,就继续写
    {     
     WriteData(Cent[i]);     //将字符常量写入LCD
     i++;                 //指向下一个字符
     delaynms(50);        //延时1ms给硬件一点反应时间
    }
}
/*****************************************************
函数功能:显示温度的数字部分
入口参数:x
***************************************************/
void display()
{
  WriteAddress(0x46);      //写显示地址,将在第2行第11列开始显示
WriteData(digit[key]);     //将小数部分的第一位数字字符常量写入LCD
delaynms(50);          //延时1ms给硬件一点反应时间
}
/*****************************************************
函数功能:主函数
***************************************************/
void main(void)
{   
   unsigned char k;
   P1=0xff;
   delaynms(15);
   LcdInitiate();         //将液晶初始化
    delaynms(5);        //延时5ms给硬件一点反应时间

  display_explain();
        display_symbol();    //显示温度说明
        display_cent();      //显示温度的单位
     display_dot();    //显示小数点
   while(1)               
  {
     P1=0xf0;
        if((P1&0xf0)!=0xf0)
     {
   delaynms(15);
    if((P1&0xf0)!=0xf0)
    {
      keyscan();
   display();   
    }
   
    }
      
    }
     
}

一位都会两位有什么难的么

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

网站地图

Top