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’ 学会了这个基础,就可以接下来模拟计算器啦!!!