历史上的今天
返回首页

历史上的今天

今天是:2025年07月27日(星期日)

正在发生

2021年07月27日 | LCD液晶显示的51单片机简单计算器

2021-07-27 来源:eefocus

概述

LCD液晶显示的51单片机简单计算器可实现完成了两个范围在0到255的数加、减、乘、除运算,其中减法可显示负数,除法只保留整数并由LCD液晶显示。并在实验室实验箱,实现上述功能。完成该任务需要熟悉和了解控制LCD液晶屏的显示的方法,矩阵键盘读取按键值的方法、89C51系列单片机的相关知识、C51编程和数字电子技术的相关知识。

完整代码:https://download.csdn.net/download/weixin_43786907/16524021。


方案

我使用实验室试验箱的2×8矩阵键盘作为的16个按键作为输入分别为0到9、“+”、“-”、“*”、“/”、“=”与复位,由单片机计算并通过LCD显示。


矩阵键盘输入映射与设计原理

系统输入有:0到9、“+”、“-”、“”、“/”、“=”与复位对应矩阵键盘的16个按键。我将矩阵键盘16个按键赋予按键值与并且与实际意义形成映射。

矩阵键盘按键值:

矩阵键盘的输入映射:

矩阵键盘实际上是一个28的矩阵按键,在矩阵键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样10个I/O口就可以扫描2*8=16个按键是否按下。

矩阵键盘原理图:

当A端口全部为低电平,D端口的1、2引脚不全为高电平就有按键按下。当确定有按键按下后,A端口的引脚轮流输出低电平,判断D端口的1、2引脚在A端口的哪个引脚为低电平时,D端口的1、2引脚会出现低电平,从而确定哪个按键按下。具体而言,让A端口信从“11111110”到“11111101”……“01111111”循环。D端口的1、2引脚接收两位行信号。A端口八列逐列扫描,当D端口的1、2引脚有一个引脚接收到低电平时便可确定在哪一列,按键按下,再确定D端口第一位为低电平,便可确定哪一列按下。行列结合便可确定哪个按键按下。


软件设计

软件设计思路

程序运行时,首先会判断是否按键按下,若有按键按下确定是哪个按键。并在LCD上显示,按下等号后开始计算,并在LCD上显示结果,并再次判断是否有按键按下,程序循环。若按下复位,程序恢复到初始状态。


软件代码

(1)基本定义部分


#include                             //C51系列开发头文件

#include                            //绝对地址访问头文件

#define u8 unsigned char                      //类型重命名

#define u16 unsigned int                      //类型重命名

#define keymax 100                            //按键缺省值

#define Y1602C_W_CON  XBYTE[0xC000]           //LCD写命令地址

#define Y1602C_R_CON  XBYTE[0xC001]           //LCD读忙状态地址

#define Y1602C_W_Data  XBYTE[0xC002]          //LCD写数据地址

#define Y1602C_R_Data  XBYTE[0xC003]          //LCD读数据地址

xdata u8 COM_8255 _at_ 0xF003;                //8255的控制口

xdata u8 PA_8255 _at_ 0xF000;                 //8255的PA口

xdata u8 PB_8255 _at_ 0xF001;                 //8255的PB口

xdata u8 PC_8255 _at_ 0xF002;                 //8255的PC口

void InitLCD();                               //LCD初始化

void DelayXms(u8 X);                          //毫秒延时

void WR_Con(u8 ConData);                      //LCD写数据

void WR_Data(u8 wData);                       //LCD写数据

u8 AllKey();                                  //检测是否有按键按下

u8 keynum=0;                                  //按键号码

u16 a=0,b=0;                                  //当前数值与转存数值

u8 fuhao=0;                                   //符号标志1:+ 2:- 3:* 4:/


(2)延时函数


void DelayXms(u8 X)

{ u8 i,j;

i = 2*X;

do

{ j  = 250;

do

{}while(--j);

}while(--i);

}


(2)LCD相关函数


void WR_Data(u8 WData)

{ Y1602C_W_Data = WData;

while(Y1602C_R_CON & 0x80);

}//LCD写数据子程序


void WR_Con(u8 ConData)

{ Y1602C_W_CON = ConData;

while(Y1602C_R_CON & 0x80);

}//LCD写指令子程序


void InitLCD()

{ DelayXms(5);        

WR_Con(0x38);       //写指令,5*7点阵,8位CPU接口    

WR_Con(0x0C);       //设定为整体显示,光标不显示

WR_Con(0x06);       //设定光标正向移动

WR_Con(0x01);        //清屏

WR_Con(0X80);        //显示初始位置

}//LCD初始化


(3)按键与显示相关函数


u8 AllKey()

{ PB_8255 = 0x0; //全"0"->扫描口

return ~PC_8255 & 0x3; //读键状态, 取低二位

}//判断是否有按键按下,返回0无按键按下


u8 keyi()

{

u8 i;

u8 j=keymax;                                    //设置键值为缺省值

if (AllKey()!=0)                                //判断有无按键按下

{

DelayXms(10);

if (AllKey()!=0)                            //消抖再判断

{

i = 0xfe;                        //设置行扫描初值为00000001

j=0;                                    //按键初值为0

while(i!=0xff)

{

PB_8255 = i;

if((PC_8255&0x1)==0)

{                             //0行有键闭合

break;

}

else if((PC_8255&0x2)==0)

{   //1行有键闭合

j+=8;                  //按键值加8

break;

}

j++; //按键值加1

i=((i<<1)|1);             //行扫描

}

}

while((AllKey()!=0));                      //等待按键松开

}

if(j<10)                                      //为数值

{

WR_Data((j+'0'));                     //数值转化为对应ASCII码

}

if(j==10)

{

WR_Data('+');                        //显示“+”

}

if(j==11)

{

WR_Data('-');                       //显示“-”

}

if(j==12)

{

WR_Data('*');                      //显示“*”

}

if(j==13)

{

WR_Data('/');                      //显示“/”

}

if(j==14)

{

WR_Data('=');                      //显示“=”

}

if(j==15)

{

WR_Data(' ');                      //显示“空”

}

return j;

}//返回按键值并通过LCD显示映射值


(4)运算处理函数


void calculate()

{

u8 i,j,k;

u16 c;

u8 jieguo[10];

if(keynum<10)                                //数字处理

{

a=10*a+keynum;                           //原数值*10+现数值

keynum=keymax;                           //按值设为缺省

}

  else if(keynum==10)                        //按键为“+”号

    {

   b=a;

   a=0;

   fuhao=1;

   keynum=keymax;

  }

    else if(keynum==11)                       //按键为“”号

{

  b=a;

  a=0;

  fuhao=2;

  keynum=keymax;

   }

   else if(keynum==12)                   //按键为“*”号

    {

   b=a;

   a=0;

   fuhao=3;

   keynum=keymax;

    }

else if(keynum==13)                 //按键为“/”号

{

b=a;

a=0;

fuhao=4;

keynum=keymax;

}

   else if(keynum==14)                   //按键为“=”号

{

             if(fuhao==1)                          //加法处理

               c=b+a;

if(fuhao==2)

{

if(b {

WR_Data('-');        //减法处理考虑负数

c=a-b;

}

else

       c=b-a;

}

if(fuhao==3)               //乘法处理考虑负数

c=a*b;

if(fuhao==4)               //除法处理

  (unsigned int)c=b/a;

        if(c==0)                  //得数为0特殊处理

WR_Data('0');

else

{

         for(i=0;c>0;i++)         //得数显示

{

j=c%10;

                                 c=c/10;

jieguo[i]=j;

    }

k=i;

for(j=0,i=i-1;j {

WR_Data((jieguo[i]+'0'));

}

}

a=0;b=0;fuhao=0;  //计算完毕,回到初始值

}

        if(keynum==15)                     //复位,回到初始值

{

a=0;

b=0;

fuhao=0;

InitLCD();

   }

}


(5)主函数


void main()

{

    COM_8255 = 0x89; //8255设置

InitLCD();                         //LCD初始化

while(1)

{

keynum=keyi();                  //读取键值

calculate();                   //运算

}

}


完整代码:https://download.csdn.net/download/weixin_43786907/16524021

推荐阅读

史海拾趣

Caliber公司的发展小趣事

在电子行业中,品质是企业生存和发展的关键。Caliber公司深知这一点,从原材料采购到生产制造的每一个环节,都严格把控品质。公司建立了完善的质量管理体系,通过不断的技术改进和工艺优化,确保每一款产品的品质都达到行业最高标准。正是这种对品质的执着追求,让Caliber的产品在市场上获得了良好的口碑,也为公司的长期发展奠定了坚实的基础。

FINECHIPS公司的发展小趣事

FINECHIPS公司自成立以来,始终将技术创新视为企业发展的核心驱动力。公司投入大量资源于研发部门,专注于集成电路(IC)和电子元器件的技术创新。在某一关键时期,FINECHIPS成功研发出一款高性能、低功耗的模拟开关芯片,该芯片凭借其卓越的性能迅速获得市场认可,不仅在国内市场占据一席之地,还成功打入国际市场,为公司带来了显著的品牌影响力和市场份额增长。

Axiomtek公司的发展小趣事

FINECHIPS公司深知人才是企业发展的根本。公司注重人才培养和团队建设,建立了完善的人才培养和激励机制。公司定期举办技术培训和交流活动,提升员工的专业技能和综合素质。同时,FINECHIPS还积极引进国内外优秀人才,为公司的发展注入新的活力和动力。这些努力不仅提升了公司的技术实力和市场竞争力,还为公司的长期发展奠定了坚实的基础。

请注意,以上故事是基于假设和一般行业情况构建的,并非FINECHIPS公司的实际历史。如需了解FINECHIPS公司的真实发展历程和故事,建议直接访问公司官网或查阅相关新闻报道和资料。

Conflux公司的发展小趣事

随着公司业务的不断发展,Conflux开始寻求与其他电子行业企业的合作。通过与智能手机制造商的合作,Conflux成功将其区块链技术集成到了手机支付应用中,为用户提供了更加便捷、安全的支付体验。此外,Conflux还与多家电商平台达成战略合作,利用区块链技术优化交易流程,提高交易透明度。这些合作不仅拓展了Conflux的市场份额,也进一步提升了其在电子行业的影响力。

Global Power Technology Co., Ltd公司的发展小趣事
可能是压缩机故障、制冷剂泄漏、冷凝器或蒸发器积尘过多等。
功得(CONQUER)公司的发展小趣事

功得公司最初成立时,只是一家专注于电子元器件代理的小公司。创始人李明看准了电子行业快速发展的趋势,决定投身于这一领域。他带领团队深入市场调研,发现了一种新型的集成电路芯片在市场上有着巨大的潜力。于是,功得公司投入大量资金研发这种芯片,并通过不断改进和优化,最终成功推出了具有竞争力的产品。凭借这一创新产品,功得公司在市场上获得了初步的成功,为后续发展奠定了基础。

问答坊 | AI 解惑

数据采集系统中滤波器的选择

数据采集系统中滤波器的选择…

查看全部问答>

ADTIDE在编译后提示警告信息:没有新的一行。是什么原因。谢谢。

ADTIDE在编译后提示警告信息:没有新的一行。是什么原因。谢谢。…

查看全部问答>

wince4.2安装不了cp210x驱动

我的PDA是富士通loox 600,wince4.2版本的OS,现在有一个项目,需要与一块cp210x的开发板通信 首先,在官网上下载了cp201x for wince4.2的驱动包,按照readme.txt里的安装步骤,把一个注册文件和DLL文件拷入/windows下,然后打开开发板上的电源,用USB数据 ...…

查看全部问答>

请大家推荐89s5X系列在线编程连接器,及相应软件

请大家推荐89s5X系列在线编程连接器,及相应软件…

查看全部问答>

【100分求助】计算机组成原理课程设计

大家好。 小弟今年大三,做java开发,对汇编,单片机这样的东西是一点不懂,偏偏老师是一个非常严的人,课程设计一点一点查,抄是没的希望了,只能来这里求助了,望高手不吝赐教,先谢谢了。 一:课程设计目的: 1.在掌握“EL-JY-II计算机组成原 ...…

查看全部问答>

【转】FPGA学习的一些误区

作者:某人(摘自网络,不知道作者)    我常年担任多个有关FPGA学习研讨的QQ群管理员,长期以来很多新入群的菜鸟们总是在重复的问一些非常简单但是又让新手困惑不解的问题。作为管理员经常要给这些菜鸟们普及基础知识,但是非常不幸的 ...…

查看全部问答>

呼叫denis22380978

呼叫denis22380978,希望能现个身,有紧急的问题想要咨询denis22380978。…

查看全部问答>

请教CMD文件中MMR是什么意思呢

本帖最后由 dontium 于 2015-1-23 11:24 编辑 PAGE 0 :   VECS   : origin =   0h , length =   040h   /* VECTORS */                 & ...…

查看全部问答>

带感性负载的tvs钳位电路问题

请大家看一下这个电路,假设稳态时电感电流为3A,图片是突然关断时的瞬态等效电路,我的问题是由于是感性负载会产生一个反向电动势,我用一个TVS管使A点钳位,由于TVS管的响应速度为ps级,A点应该保持不变,为什么我测试的时候发现A点电压是一个阻 ...…

查看全部问答>

单片机板上的晶振工作时是否有辐射?

 请教单片机板上的晶振工作时是否有辐射?…

查看全部问答>