单片机
返回首页

51单片机系列——LCD1602显示计算器上按键字符

2021-12-23 来源:eefocus

昨天研究了矩阵按键在proteus7.8上的仿真问题,今天直接上个实例,用LCD1602显示在计算器上按下的按键字符。


仿真图:

LCD1602.h


#ifndef _LCD1602_H_

#define _LCD1602_H_

#include


//重定义关键字

#ifndef uchar

#define uchar unsigned char

#endif


#ifndef uint 

#define uint unsigned int

#endif


/**********************************

PIN口定义

**********************************/

#define Lcd1602DataPin P0

sbit LCD1602_E=P2^7;

sbit LCD1602_RW=P2^5;

sbit LCD1602_RS=P2^6;


/**********************************

函数声明

**********************************/

/*在51单片机12MHZ时钟下的延时函数*/

void Lcd1602_Delay1ms(uint c);   //误差 0us

/*LCD1602写入8位命令子函数*/

void LcdWriteCom(uchar com);

/*LCD1602写入8位数据子函数*/ 

void LcdWriteData(uchar dat) ;

/*LCD1602初始化子程序*/  

void Lcd1602Init();


#endif


LCD1602.c


#include 'lcd1602.h'

/*******************************************************************************

* 函 数 名         : Lcd1602_Delay1ms

* 函数功能     : 延时函数

* 输    入         : c

* 输    出         : 无

*******************************************************************************/

void Lcd1602_Delay1ms(uint c){//延时函数

    uchar a,b;

 for (; c>0; c--){

   for (b=199;b>0;b--){

     for(a=1;a>0;a--);

   }      

 }    

}


/*******************************************************************************

* 函 数 名         : LcdWriteCom

* 函数功能     : 向LCD写入一个字节的命令

* 输    入         : com

* 输    出         : 无

*******************************************************************************/

void LcdWriteCom(uchar com)   //写入命令

{

 LCD1602_E = 0;     //使能

 LCD1602_RS = 0;    /*选择发送命令*/

 LCD1602_RW = 0;    //选择写入

 Lcd1602DataPin = com;     //放入命令

 Lcd1602_Delay1ms(1);  //等待数据稳定

 LCD1602_E = 1;           //根据写数据时序图,拉高写入时序(数据)

 Lcd1602_Delay1ms(5);   //保持时间

 LCD1602_E = 0;     //再拉低数据写完了,释放

}


/*******************************************************************************

* 函 数 名         : LcdWriteData

* 函数功能     : 向LCD写入一个字节的数据

* 输    入         : dat

* 输    出         : 无

*******************************************************************************/     

void LcdWriteData(uchar dat)   //写入数据

{

 LCD1602_E = 0; //使能清零

 LCD1602_RS = 1; /*选择输入数据*/

 LCD1602_RW = 0; //选择写入 

 Lcd1602DataPin = dat; //写入数据

 Lcd1602_Delay1ms(1);

 LCD1602_E = 1;   //写入时序

 Lcd1602_Delay1ms(5);   //保持时间

 LCD1602_E = 0;

}


/*******************************************************************************

* 函 数 名       : Lcd1602Init()

* 函数功能   : 初始化LCD屏

* 输    入       : 无

* 输    出       : 无

*******************************************************************************/     

void Lcd1602Init()        //LCD初始化子程序

{

  LcdWriteCom(0x38);  //开显示,设置为8总线,2行显示,5*7点阵,这是“功能设定指令”

 LcdWriteCom(0x0c);  //开显示不显示光标,“显示开关控制指令”

 LcdWriteCom(0x06);  //写一个指针加1,“进入模式设置指令”

 LcdWriteCom(0x01);  //清屏,“清屏指令”

 LcdWriteCom(0x80);  //设置数据指针起点,第一个字符是在0x00,位置,但写入的数据地址格式必须是0x**+0x80,因此在这提前加地址加一个0x80;这里不写也行但必须在main函数中调用前将数据要写入的地址+0x80

}


main.c


#include

#include

#include'lcd1602.h'


#define uint unsigned int

#define uchar unsigned char


#define GPIO_KEY P1  //宏定义P1口,方便移植


uint dat;  // 传入LCD1602写数据函数的数,用于存放最终获得的计算器上按键的行列信息

uchar i;  //用于主函数的for循环

uchar  KeyValue;  //设一个最后的传递值(给P0的)

void delay(uint x){

 while(x--); 

}


/*******************************************************************************

* 函 数 名       : KeyDown()

* 函数功能   : 矩阵按键的扫描,确定按下哪个键

* 输    入       : 无

* 输    出       : 无

*******************************************************************************/     

void KeyDown(void){ 

   if((GPIO_KEY&0xf0)!=0xf0){//读取是否有按键按下,符合(1)的说明;补充:P1.0——P1.3是低四位,行表示 

   KeyValue=~(0xf0|GPIO_KEY); //这步很关键,得到KeyValue(P0)低四位数据,P0.0~P0.3亮的含义:分别表示是第一行到——第四行的某行亮

   switch((GPIO_KEY&0xf0)){ //这个'|'要有

    case(0X70): KeyValue|=0x80;break; //'4'行

    case(0Xb0): KeyValue|=0x40;break; //'3'行

    case(0Xd0): KeyValue|=0x20;break; //'2'行

    case(0Xe0): KeyValue|=0x10;break; //'1'行

   } 

    } else{GPIO_KEY=_crol_(GPIO_KEY,1); 

    }  //如果高四位是为1,到下一行去判断

  if(GPIO_KEY==0xef){GPIO_KEY=0xfe;}   //这句很重要!!!,判断第四次移位是否完成:若低电平移到第五位P1.4,则返回P1.0重新轮询扫描!!!

   

}


void main(void){

 

 GPIO_KEY=0xfe; //设一个行的轮询的初始值,从第一行开始

 while(1){ //死循环,不断的查询中

  

    for(i=0;i<4;i++){   //完成一整次轮询

     KeyDown();     //调用按键判断函数  

  delay(1000);

  dat=KeyValue;   //得到按键所在行列的信息

    }

   GPIO_KEY=0xfe;  //再赋值准备下次轮询

    i=0;//清零,为下次轮询准备

  switch(dat){ //根据获得的行列信息,匹配是哪个对应的字符

   case 0x88: dat='+';break;

   case 0x48: dat='=';break;

   case 0x28:  dat='0';break;

   case 0x18: dat='C';break;

   case 0x84: dat='-';break;

   case 0x44: dat='3';break;

   case 0x24: dat='2';break;

   case 0x14: dat='1';break;

   case 0x82: dat='*';break;

   case 0x42: dat='6';break;

   case 0x22: dat='5';break;

   case 0x12: dat='4';break;

   case 0x81: dat='/';break;

   case 0x41: dat='9';break;

   case 0x21: dat='8';break;

   case 0x11: dat='7';break; 

 }

 Lcd1602Init(); //调用LCD1602的初始化函数

 LcdWriteData(dat);//将获取的字符显示在显示屏上   

 }   

}


结果:按下‘7’键显示屏上显示‘7’

学会了这个基础,就可以接下来模拟计算器啦!!!

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 家用电源无载自动断电装置的设计与制作

  • 用数字电路CD4069制作的万能遥控轻触开关

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 开关电源的基本组成及工作原理

  • 用NE555制作定时器

  • 带有短路保护系统的5V直流稳压电源电路图

    相关电子头条文章