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

发布者:诗意世界最新更新时间:2022-02-25 来源: eefocus关键字:51单片机系列  LCD1602显示  计算器 手机看文章 扫描二维码
随时随地手机看文章

昨天研究了矩阵按键在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’

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

关键字:51单片机系列  LCD1602显示  计算器 引用地址:51单片机系列——LCD1602显示计算器上按键字符

上一篇:51单片机系列学习——逐行扫描的方式实现矩阵按键的仿真
下一篇:51单片机系列——学习LCD1602液晶显示-8总线-显示一串字符

推荐阅读最新更新时间:2024-11-10 21:35

51单片机数字时钟仿真(LCD1602液晶显示)+源程序+电路原理图
下面是51单片机数字时钟程序: #include AT89X52.h #define DSbus P0 #define LCDbus P1 //定义DS12C887和LCD的控制线 sbit DS_CS = P2^7; //引脚13,片选信号输入,低电平有效。 sbit DS_AS = P2^4; //引脚14,地址选通输入。 sbit DS_RW = P2^5; //引脚15,读/写输入。 sbit DS_DS = P2^6; //引脚17,数据选通或读输入。 sbit LCD_RS=P2^0; sbit LCD_EN=P2^2; //时间变量定义 unsigned char Counter; u
[单片机]
<font color='red'>51单片机</font>数字时钟仿真(<font color='red'>LCD1602</font>液晶<font color='red'>显示</font>)+源程序+电路原理图
字符设备驱动-按键驱动
驱动源码: #include linux/module.h #include linux/kernel.h #include linux/fs.h #include linux/init.h #include linux/delay.h #include asm/uaccess.h #include asm/irq.h #include asm/io.h #include asm/arch/regs-gpio.h #include asm/hardware.h int major = 0; static struct class *keydrv_class; static struct
[单片机]
51单片机简易计算器程序 实现数字的加减乘除运算
单片机源程序如下: #include reg51.h //头文件 #define uint unsigned int #define uchar unsigned char sbit lcden=P1^1; //LCD1602控制引脚 sbit rs=P1^0; sbit rw=P1^2; sbit busy=P0^7;//LCD忙 char i,j,temp,num,num_1; long a,b,c; //a,第一个数 b,第二个数 c,得数 float a_c,b_c; uchar flag,fuhao;//flag表示是否有运算符键按下,fuhao表征按下的是哪个运算符 //flag=1表示运算符键按
[单片机]
<font color='red'>51单片机</font>简易<font color='red'>计算器</font>程序 实现数字的加减乘除运算
23. 模拟计算器数字输入及显示
1. 实验任务 (1. 开机时,显示 0 (2. 第一次按下时,显示 D1 ;第二次按下时,显示 D1D2 ;第三按下时,显示 D1D2D3 ,8个全显示完毕,再按下按键下时,给出 嘀 提示音。 2. 电路原理图 图4.23.1 3. 系统板上硬件连线 (1. 把 单片机系统 区域中的P1.0端口用导线连接到 音频放大模块 区域中的SPK IN端口上; (2. 把 单片机系统 区域中的P3.0-P3.7端口用8芯排线连接到 4X4行列式键盘 区域中的C1-C4 R1-R4端口上; (3. 把 单片机系统 区域中的P0.0-P0.7端口用8芯排线连接到 动态数码显示 区域中的A
[单片机]
23. 模拟<font color='red'>计算器</font>数字输入及<font color='red'>显示</font>
10分钟理解LCD1602液晶显示模块
1. 初识LCD1602液晶模块 LCD1602什么意思,LCD表示LiquidCrystal Display,1602表示一行可以显示16个字符,一共有两行。实物图如下所示: 2. 思路分析 LCD1602是显示模块,主要作用当然是显示了。既然是显示,我们可以想一想,无非就是两个内容: 第一点:你打算让它在哪里显示(显示位置) 第二点:你要显示什么内容 (显示内容) 很明显,这两点都是来自于单片机的控制,单片机让它显示什么它就显示什么,单片机让它在哪里显示它就在哪里显示。这一句话也可以换个说法,比如单片机'告诉'LCD1602模块:请你在第1行的第4个位置,显示字符‘A'. 所谓'告诉
[单片机]
10分钟理解<font color='red'>LCD1602</font>液晶<font color='red'>显示</font>模块
pic单片机 DS18B20采样 LCD1602显示
#include 18b20.h #include main.h //--------------产生复位脉冲--------------------// void tx_reset() { ADCON1=0X06; TR ISA 5=0; DQ=1; delay_us2(10,5); //65us while(!DQ); //判断总线是否忙 DQ=0; delay_us2(10,23); //730us } //----------------等待应答脉冲----------------// void tx_wait () { TRISA5=1; //设为输入方式后,DQ被
[单片机]
51单片机系列连载7—综合应用
在中断之前介绍了静态数码管,当然,与静态对应的就是动态,动态显示就是轮流点亮各位显示器,也就是我们经常提到的扫描方式,从效果上看,各位显示器都能连续而稳定地显示不同的字符,这就是动态显示。关于亮灭的原理与静态显示是一样的,就不再赘述。 到现在已经介绍了单片机的静态、动态数码管、中断、定时器等,貌似很简单,但是综合在一起就会出现问题了,不信,看一道例题。 这个应该说并不难,但是开始却不知从何下手,先来看看标准答案: #include #include #define uchar unsigned char #define uint unsigned int sbit dula=P2^6; s
[单片机]
简易加法计算器
学到这里,我们已经掌握了一种显示设备和一种输入设备的使用,那么是不是可以来做点综合性的实验了。好吧,那我们就来做一个简易的加法计算器,用程序实现从板子上标有0~9 数字的按键输入相应数字,该数字要实时显示到数码管上,用标有向上箭头的按键代替加号,按下加号后可以再输入一串数字,然后回车键计算加法结果,并同时显示到数码管上。虽然这远不是一个完善的计算器程序,但作为初学者也足够你研究一阵子了。 首先,本程序相对于之前的例程要复杂得多,需要完成的工作也多得多,所以我们把各个子功能都做成独立的函数,以使程序便于编写和维护。大家分析程序的时候就从主函数和中断函数入手,随着程序的流程进行就可以了。大家可以体会体会划分函数的好处,想想如果还是
[单片机]

推荐帖子

串口通讯,接收端数据错误问题
板子采用串口通讯,板端设置如下:ioctl(com1Fd,FIOBAUDRATE,9600);//设置波特率ioctl(com1Fd,FIOFLUSH,0);//清空缓冲区ioctl(com1Fd,FIOSETOPTIONS,OPT_RAW);//设置com口工作模式板子启动后会发送消息,板端显示消息内容正确,但是在接收端收到的消息中倒数第二个字节位置多出一个字节0x0d,并且这种情况只是偶而出现.我想问一下出现这种情况可能和哪些因素有关?多
superjeson 嵌入式系统
电感线圈的品质因素Q
因数Q是表示线圈质量的一个重要参数。Q值的大小,表明电感线圈损耗的大小,其Q值越大,线圈的损耗越小;反之,其损耗越大。品质因数Q的定义为:当线圈在某一频率的交流电压下工作时,线圈所呈现的感抗和线圈直流电阻的比值。它可以用公式表达如下:式中:W--工作角频率 L--线圈电感量 R--线圈总耗损电阻根据使用场合的不同,对品质因数Q的要求也不同。对调谐回路中的电感线圈,Q值要求较高,因为Q值越高,回路的损耗就越小,回路的效率就越高;对鹅合线圈来说,Q值可以低一些;而
qwqwqw2088 模拟与混合信号
什么是汽车音响系统?汽车音响技术五要点讲解
1、组成结构音响系统之所以可以称为音响,最基本的条件就是,有回放声音的功能。音响系统中,至少要包含笔者提出的下列几点,才有资格称为音响,这一点任何音响系统皆然,汽车音响亦不例外。汽车音响主要包括主机、扬声器、功放三部分。主机是汽车音响中最重要的组成部分,就好像人的大脑,要发出什么样的声音,得由大脑来控制。流行的主机有只有广播接收功能的RADIO主机、RADIO加MP3主机、CD主机、MP3加CD碟盒、CD加导航主机和CD/DVD/车载MP5主机,MP5主机已替代一般的车载CD音响系统,海量硬
Jacktang 模拟与混合信号
ESP8266模块通信问题
有没有哪位大神知道ESP8266连接上WIFI和TCP服务器之后我向模块发送AT指令和AT+CIPSEND指令模块没有返回OK而是直接发送到TCPServer端是什么原因ESP8266模块通信问题检查一下硬连接,先串口配置完成,再用串口调试工具操作ESP8266串口WIFI模块,让它与OneNet建立连接、传输数据,这几步必须正确固件的问题你先检查是你的AT配置是不是进入了透传模式,用AT+CIPMODE?命令查询下,不明白多看下官方文档模块已经是进入透传模式了吧,所有接收到的数据
xuannian stm32/stm8
MSP430
我使用IAR环境,编写MSP430F6433单片机,遇到以下两个问题。请各位大侠帮帮忙(1)从低功耗模式LPM3.5唤醒,按照手册写得应当有BOR事件,则系统复位,复位标志置位。但是我唤醒LPM3.5时,复位标志没有置位,所以也没有系统复位。(2)系统复位中断向量0xFFFE。但是只要程序中写入以下代码,编译就会出错。按照论坛高手提示。菜单Project的Options的Linker选项中的Config中,选择Overridedefaultprogram,并在其子项中选择Defined
zilong 微控制器 MCU
高效单端正激DC/DC变换器
摘要:介绍一种特殊的单端正激DC/DC变换器,该变换器具有较高的功率传输效率和较大的功率输出。关键词:单端正激变换器高效DC/DC变换器广泛应用于通信、计算机及汽车等领域,近年来DC/DC变换器技术有了很大的发展,重点是研究高效、高功率输出、结构简单和价廉的变换器。本文介绍一种特殊的单端正激200W48V/24V变换器,由于电路的特殊结构,该变换器具有稳定性好、效率高、功率密度高等优点。高效单端正激DC/DC变换器
zbz0529 模拟电子
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved