【附报告】51单片机计算器(LCD1602液晶显示)

这篇具有很好参考价值的文章主要介绍了【附报告】51单片机计算器(LCD1602液晶显示)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  由于本文较早,这里推荐一下近期刚优化的:【优化】51单片机计算器(LCD1602液晶显示)_Gxtoeilee的博客-CSDN博客

 文章来源地址https://www.toymoban.com/news/detail-500887.html

1 设计目标

设计可选模式的计算器 

2 主要功能

功能一:可选两种计算模式,模式一为四则运算,模式二为扩展内容;

功能二:除法的计算结果保留到小数点后四位;

功能三:除数为0时报错。

3 硬件部分讲解

51单片机,导线,矩阵键盘,独立按键,LCD1602液晶显示屏

【附报告】51单片机计算器(LCD1602液晶显示) 【附报告】51单片机计算器(LCD1602液晶显示)

                         图1                                                                         图2

【附报告】51单片机计算器(LCD1602液晶显示)   【附报告】51单片机计算器(LCD1602液晶显示)

                                         图3                                                                        图4

 

【附报告】51单片机计算器(LCD1602液晶显示)  【附报告】51单片机计算器(LCD1602液晶显示)

                                      图5                                                                            图6

【附报告】51单片机计算器(LCD1602液晶显示)

图7

【附报告】51单片机计算器(LCD1602液晶显示)

图8

【附报告】51单片机计算器(LCD1602液晶显示)

图9

【附报告】51单片机计算器(LCD1602液晶显示)

图10

【附报告】51单片机计算器(LCD1602液晶显示)

图11

图1为矩阵键盘模块。

图2为独立按键模块。K1连接P2_0,K2连接P2_1。

图3为LCD1602接口。控制效果如下:

    RW:P2_5控制;

    RS:P2_6控制;

    EN:P2_7控制;

    D0—D7:P0_0—P0_7。

图4为矩阵键盘由P1组控制的效果。

图5为LCD1602显示代码。

图6为LCD1602显示位置及代码。

图7为LCD1602的引脚接口说明。

图8为LCD1602的写操作时序图。

图9为LCD1602的时序参数。

图10为计算器计算按键,对应矩阵键盘。

图11为计算器模式选择按键,对应独立按键。

 

4 软件流程及代码实现

 

4.1主要代码说明

本程序由一个主函数和六个子函数组成。子函数分别为:延时函数、LCD写命令函数、LCD写数据函数、LCD初始化函数、模式判定函数、计算器函数。

4.1.1 主函数

主函数首先调用LCD初始化函数对LCD1602显示屏进行初始化,然后显示欢迎语句welcome,延时1s后清屏。进入循环后首先调用功能判定函数选择计算器模式。在设计之初计划设定两种模式,模式一中为四则运算,模式二中为扩展其他功能,随后根据所选模式的返回值进入不同的计算器程序。此处只对模式一进行展示,即四则运算。

void main()
{ 
  uint x;
  lcdinit();//LCD1602初始化 
  for(x=0;x<12;x++)
    lcdwrd(wel[x]);//显示欢迎语句:Welcome 
  delay(1000); 
  lcdwrc(0x01);//LCd1602清屏 
  while(1)
  {  
	MODE();//功能判定函数
    KeyDown();//按键判断函数 
  }
}

 

4.1.2 子函数1

延时函数为延时x毫秒,主要用于LCD1602的初始化、显示语句、按键消抖。

void delay(unsigned int xms)//延时x毫秒 
{
  unsigned int i,j;
  for(i=xms;i>0;i--)
    for(j=112;j>0;j--);
return;
}

4.1.3 子函数2

LCD写命令函数。RS为寄存器选择,高电平时选择数据寄存器,低电平时选择指令寄存器。此处为RS赋低电平选择指令寄存器。由写操作时许图可知,RW可全过程定义为低电平;EN为使能端,由EN和DB0—DB7时序可知,EN首先为低电平,高电平时写指令,低电平时写指令完成,液晶模块执行命令。

void lcdwrc(uint c)
{
 delay(100);
 rs=0;
 rw=0;
 e=0;
 P0=c;
 e=1;
 delay(100);
 e=0;
}

4.1.4 子函数3

LCD写数据函数。RS为寄存器选择,高电平时选择数据寄存器,低电平时选择指令寄存器。此处为RS赋高电平选择数据寄存器。由写操作时许图可知,RW可全过程定义为低电平;EN为使能端,由EN和DB0—DB7时序可知,EN首先为低电平,高电平时写数据,低电平时写数据完成,液晶模块执行命令。

void lcdwrd(uint dat) //设置LCD写数据
{
 delay(100);
 rs=1;
 rw=0;
 e=0;
 P0=dat;
 e=1;
 delay(100);
 e=0;
 rs=0;
}

4.1.5 子函数4

初始化LCD函数。固定程序以及定义计算器需要用的变量。

void lcdinit()   //初始化LCD
{
 delay(150);
 lcdwrc(0x38);//写指令38H
 delay(50);
 lcdwrc(0x38);//显示模式设置
 delay(50);
 lcdwrc(0x38);
 delay(50);
 lcdwrc(0x38);//功能设定指令
 lcdwrc(0x08);
 lcdwrc(0x01);//清屏
 lcdwrc(0x06);//显示光标移动设置
 lcdwrc(0x0c); //显示开关控制指令
 num=0;//用于判定按键是否为“=”或者“归零”时的变量
 fuhao=0;//用于判定是否为运算符号
 flag=0;//用于判定运算方式时的变量
 a=0;//计算的第一个数
 b=0;//计算的后一个数
 c=0;//计算结果
 x=0;//判定小数点的变量,暂存c值
 k=0;//判定小数点的变量,小数点后非零数个数
 j=0;//显示ERROR时的循环用变量
}

4.1.6子函数5

模式判定函数。用于显示选择的是哪个模式并且返回主函数值,使主函数运行相应值。此处因我只定义了一个模式,故只有模式1。

void MODE()
{
  if(P2_0==0)
  { 
    for(j=0;j<10;j++)
    lcdwrd(MODE1[j]);//显示语句:MODE1               
    delay(1000);//延时
    lcdinit();//重新初始化LCD1602			   
  }
}

4.1.7子函数6

计算器函数。该函数较为复杂,大致分为按键判定、按键扫描、实现功能。

按键判定使判断是否有按键按下。

按键扫描部分是判定哪个键被按下。首先对第一列扫描,若扫描结果为归零键,便会将LCD执行清零操作。若扫描到其他按键,则显示对应数字。后面二、三、四列的定义均如此。

计算部分为扫描结果为“=”键时。加法和乘法运算都只需要直接计算即可。计算的结果是从后往前输入,这样便于确定结果显示的位置。

减法运算中,程序会先判断减数和被减数的大小关系,从而确定结果是否为负数。若为负数,则会显示负号。

    除法运算时,因为除法中可能会出现小数,所以先将计算结果乘以10000,然后将结果循环除以10,直到为0,每次循环都会使变量k加1,最后跟据k的大小(1-4)来确定小数点的位置,即保留四位小数。

void KeyDown()//计算器函数
{
  k=0;     
  P1=0x0f;   //0000 11111,行都为低电平0,列都为高电平
  if(P1!=0x0f)//P1不为0x0f,则判定为有按键被按下 
  {
    delay(100);//消抖
    if(P1!=0x0f)//延时后,再次判断 
    {
      P1=0x0f;//0000 11111,行都为低电平0,列都为高电平
      switch(P1)//
      {
      /********************第一列有按键按下*********************/ 
		case 0x07://0000 0111 第一列有按键被按下  
		{
          P1=0xf0;//列都为低电平0,行都为高电平1 
          switch(P1)//判断哪一行的按键被按下 
          {
          case 0x70: num = 1/*S1*/;k=7;break;    //0111 0000第一列第一行 数字7
          case 0xb0: num = 5/*S5*/;k=4;break;    //1011 0000第一列第二行 数字4
          case 0xd0: num = 9/*S9*/;k=1;break;    //1101 0000第一列第三行 数字1
          case 0xe0: num = 13/*S13*/;break;       //1110 0000第一列第四行 归零
          } 
          		  
		  if(num!=13)//被按下的按键不是归零键 
          {
            if(fuhao==0)//fuhao==0,表示第一个数a,fuhao==1,表示第二个数b 
              a=a*10+k;
            else
              b=b*10+k;
          }
          lcdwrd(0x30+k);//显示按下的数,0x30为ASCII码中数字组的开头,0x3k:显示k,即按下数字k 
          
		  if(num==13)//按下的按键是清零键
          {  
            lcdwrc(0x01); //清屏指令   
            lcdinit();//重新初始化LCD1602 
          }      
        }while(P1!=0xf0);break;//当有按键被按下时,结束此次判断,进行下一次判断 
 	 
	 
      /********************第二列有按键按下*********************/
      case 0x0b: //0000 1011 第二列有按键被按下 
      {
        P1=0xf0;//行都为高电平1,列都为低电平0
        switch(P1)//判断哪一行有按键被按下 
        {
          case 0x70: k=8;break;//第二列第一行 数字8
          case 0xb0: k=5;break;//第二列第二行 数字5
          case 0xd0: k=2;break;//第二列第三行 数字2
          case 0xe0: k=0;break;//第二列第四行 数字0
        }   
        
		if(fuhao==0)//fuhao==0,表示第一个数a,fuhao==1,表示第二个数b
          a=a*10+k;
        else
          b=b*10+k; 
        lcdwrd(0x30+k);//显示按下的数,0x30为ASCII码中数字组的开头,0x3k:显示k,即按下数字k 
      }	while(P1!=0xf0);break;//当有按键被按下时,结束此次判断,进行下一次判断
 	  
	  
	  /********************第三列有按键按下*********************/
      case 0x0d: //0000 1101 第三列有按键被按下 
      {
        P1=0xf0;//行都为高电平1,列都为低电平0
        switch(P1)//判断哪一行有按键被按下
        {
        case 0x70: num=3;k=9;break;//第三列第一行 数字9 
        case 0xb0: num=7;k=6;break;//第三列第二行 数字6 
        case 0xd0: num=11;k=3;break;//第三列第三行 数字3
        case 0xe0: num=15;break;//第三列第四行 “=”键 
        } 
        if(num!=15)//按下的键不为“=”键 
        { 
          if(fuhao==0)//fuhao==0,表示第一个数a,fuhao==1,表示第二个数b
            a=a*10+k;
          else
            b=b*10+k; 
          lcdwrd(0x30+k);//显示按下的数,0x30为ASCII码中数字组的开头,0x3k:显示k,即按下数字k
        }
        
	    /************"="键被按下************/
		if(num==15)//按下的键为=键 
        {
          switch(flag)//判断进行哪种运算 
          {
                 /*******加法运算*********/
			case 1://加法运算
            {
              c=a+b;//计算结果 
              lcdwrc(0x4f/*第二行末尾位置*/+0x80);//光标置于第二行末尾 
              lcdwrc(0x04);//设置显示方式:显示后指针减一,即前移一位 
              
			  if(c==0)//若结果为0 
                lcdwrd(0x30);//显示0 
              while(c!=0)
              {
                lcdwrd(0x30+c%10);//从后向前显示最后一位 
                c=c/10;//去掉最后一位后再循环显示 
              }
              lcdwrd(0x3d);//显示完计算结果后,显示“=” 
              }break;
 				 
				 /*******减法运算*********/
            case 2://减法运算
            {
              if(a>b)//大数减小数
                c=a-b;
              else//小数减大数
                c=b-a;//计算两数相减的绝对值 
              lcdwrc(0x4f+0x80);//将光标置于第二行末尾 
              lcdwrc(0x04);//设置显示方式:显示后指针减一 
 
              if(c==0)//若结果为零 
                lcdwrd(0x30);//显示0 
              while(c!=0) 
              {
                lcdwrd(0x30+c%10);//从后向前显示最后一位
                c=c/10;//去掉最后一位后再循环显示
              }
              if(a<b)//若结果为负数 
                lcdwrd(0x2d);//ASCII中的“-”,显示负号
              lcdwrd(0x3d);//显示= 
              }break;
 				 
				 /*******乘法运算*********/
            case 3://乘法运算
            {
              c=a*b; //计算结果 
              lcdwrc(0x4f+0x80);//光标置于第二行末尾 
              lcdwrc(0x04);//显示设置:显示后指针减一 
              if(c==0)//若结果为0 
                lcdwrd(0x30);//显示0 
              while(c!=0)  
              {                           
                lcdwrd(0x30+c%10);//从后向前显示最后一位
                c=c/10;//去掉最后一位后再循环显示 
              }
              lcdwrd(0x3d);//显示=  
            }break;
 
				 /*******除法运算*********/
            case 4: //除法运算 
            { 
              if(b==0)//若除数为0 
              { 
                lcdwrc(0x01);//清屏 
                for(j=0;j<11;j++)
                {
                  lcdwrd(ERROR[j]);//显示语句:ERROR! 
                }
                delay(1000);//延时 
                lcdinit();//重新初始化LCD1602
              }
              
			  else
              {  
                c=(long)(((float)a/b)*10000);//将结果放大10000倍,即:若无法整除,保留4位小数
                x=c;
                lcdwrc(0x4f+0x80);//光标置于第二行末尾
                lcdwrc(0x04);//显示设置:显示后指针减一
                while(c!=0)//一位一位显示
                {
                  k++;
                  lcdwrd(0x30+c%10);//显示结果的最后一位在0x4f的位置  //0  00  000  0000
                  c=c/10;//取前面的结果数据
                  if(x>0&&x<=9)//0.0001到0.0009
                  {
                    if(k==1)//只有小数点后最后一位  x.000x
                    { 
                      lcdwrd(0x30);//0
                      lcdwrd(0x30);//0
                      lcdwrd(0x30);//0 
                      lcdwrd(0x2e);//.
                      k=0;
                    }
                  }
                  if(x>9&&x<=99)//0.0010到0.0099
                  { 
                    if(k==2)//只有小数点后最后两位  x.00xx
                    { 
                    lcdwrd(0x30);//0
                    lcdwrd(0x30);//0
                    lcdwrd(0x2e);//.
                    k=0;
                    }
                  }
                  if(x>99&&x<=999)//0.0100到0.0999
                  {
                    if(k==3)//只有小数点后最后三位  x.0xxx
                    {
                      lcdwrd(0x30);//0
                      lcdwrd(0x2e);//.
                      k=0;
                    } 
                  }
                  else if(k==4)//小数点后四位都非零  x.xxxx
                  {
                    lcdwrd(0x2e);//.         
                  }  
                }
                if(x<10000)//若结果小于1,在个位补0 
                  lcdwrd(0x30);//个位补0
                lcdwrd(0x3d);//显示=
				k=0;//将k定回0用于下次计算   
              } 
            } break;
          }
        }
      }
      while(P1!=0xf0);break;//当有按键被按下时,结束此次判断,进行下一次判断
      
	  
	  /********************第四列有按键按下*********************/
      case 0x0e://0000 1110 第四列有按键被按下
      { 
        fuhao=1;//有符号键被按下 
        P1=0xf0;//1111 0000
        switch(P1)
        {
          case 0x70:/*0111 0000*/flag=4;lcdwrd(0xfd);break;//“/”第四列第一行 
          case 0xb0:/*1011 0000*/flag=3;lcdwrd(0x2a);break;//“*”第四列第二行 
          case 0xd0:/*1101 0000*/flag=2;lcdwrd(0x2d);break;//“-”第四列第三行 
          case 0xe0:/*1110 0000*/flag=1;lcdwrd(0x2b);break;//“+”第四列第四行 
        }  
      }  
      while(P1!=0xf0);break;
      }
    }
  }
}

 

 

 

 

 

 

5 演示 

  • 测试开机显示欢迎语

【附报告】51单片机计算器(LCD1602液晶显示)

  • 测试计算模式选择

【附报告】51单片机计算器(LCD1602液晶显示)

  • 测试加法运算功能

【附报告】51单片机计算器(LCD1602液晶显示)

  • 测试减法运算功能

【附报告】51单片机计算器(LCD1602液晶显示)

  • 测试乘法运算功能

【附报告】51单片机计算器(LCD1602液晶显示)

  • 测试除法运算功能

【附报告】51单片机计算器(LCD1602液晶显示)

  • 测试除数为0时显示“ERROR!”

【附报告】51单片机计算器(LCD1602液晶显示)

6 结论

    制作过程中建议先学会使用单个模块的功能,再将这些部分拼接起来,从而组成完整的计算器。

7 源代码

#include <REGX51.H>
typedef unsigned int uint;   //定于无符号int
typedef unsigned char uchar;  //定义无符号char
/*****************************定义引脚**********************************/
sbit rw=P2^5;            
sbit rs=P2^6;            
sbit e=P2^7;             
/*****************************定义变量**********************************/ 
uint fuhao,flag,k,i,j,num;          
uchar ERROR[]="     ERROR!";//除数为0时,显示 
uchar wel[]="    Welcome!";//初始化时显示
uchar MODE1[]="     MODE1";
long a,b,c,x;
/*****************************延时函数**********************************/ 
void delay(unsigned int xms)//延时x毫秒 
{
  unsigned int i,j;
  for(i=xms;i>0;i--)
    for(j=112;j>0;j--);
return;
}
/*****************************LCD写命令————位置**********************************/ 
void lcdwrc(uint c)
{
 delay(100);
 rs=0;
 rw=0;
 e=0;
 P0=c;
 e=1;
 delay(100);
 e=0;
}
 
/*****************************LCD写数据————内容**********************************/ 
void lcdwrd(uint dat) //设置LCD写数据
{
 delay(100);
 rs=1;
 rw=0;
 e=0;
 P0=dat;
 e=1;
 delay(100);
 e=0;
 rs=0;
}
/*****************************初始化LCD**********************************/ 
void lcdinit()   //初始化LCD
{
 delay(150);
 lcdwrc(0x38);//写指令38H
 delay(50);
 lcdwrc(0x38);//显示模式设置
 delay(50);
 lcdwrc(0x38);
 delay(50);
 lcdwrc(0x38);//功能设定指令
 lcdwrc(0x08);
 lcdwrc(0x01);//清屏
 lcdwrc(0x06);//显示光标移动设置
 lcdwrc(0x0c); //显示开关控制指令
 num=0;//用于判定按键是否为“=”或者“归零”时的变量
 fuhao=0;//用于判定是否为运算符号
 flag=0;//用于判定运算方式时的变量
 a=0;//计算的第一个数
 b=0;//计算的后一个数
 c=0;//计算结果
 x=0;//判定小数点的变量,暂存c值
 k=0;//判定小数点的变量,小数点后非零数个数
 j=0;//显示ERROR时的循环用变量
}
/*****************************模式判定函数**********************************/
void MODE()
{
  if(P2_0==0)
  { 
    for(j=0;j<10;j++)
    lcdwrd(MODE1[j]);//显示语句:MODE1               
    delay(1000);//延时
    lcdinit();//重新初始化LCD1602			   
  }
}
/*****************************计算器函数**********************************/ 
void KeyDown()//计算器函数
{
  k=0;     
  P1=0x0f;   //0000 11111,行都为低电平0,列都为高电平
  if(P1!=0x0f)//P1不为0x0f,则判定为有按键被按下 
  {
    delay(100);//消抖
    if(P1!=0x0f)//延时后,再次判断 
    {
      P1=0x0f;//0000 11111,行都为低电平0,列都为高电平
      switch(P1)//
      {
      /********************第一列有按键按下*********************/ 
		case 0x07://0000 0111 第一列有按键被按下  
		{
          P1=0xf0;//列都为低电平0,行都为高电平1 
          switch(P1)//判断哪一行的按键被按下 
          {
          case 0x70: num = 1/*S1*/;k=7;break;    //0111 0000第一列第一行 数字7
          case 0xb0: num = 5/*S5*/;k=4;break;    //1011 0000第一列第二行 数字4
          case 0xd0: num = 9/*S9*/;k=1;break;    //1101 0000第一列第三行 数字1
          case 0xe0: num = 13/*S13*/;break;       //1110 0000第一列第四行 归零
          } 
          		  
		  if(num!=13)//被按下的按键不是归零键 
          {
            if(fuhao==0)//fuhao==0,表示第一个数a,fuhao==1,表示第二个数b 
              a=a*10+k;
            else
              b=b*10+k;
          }
          lcdwrd(0x30+k);//显示按下的数,0x30为ASCII码中数字组的开头,0x3k:显示k,即按下数字k 
          
		  if(num==13)//按下的按键是清零键
          {  
            lcdwrc(0x01); //清屏指令   
            lcdinit();//重新初始化LCD1602 
          }      
        }while(P1!=0xf0);break;//当有按键被按下时,结束此次判断,进行下一次判断 
 	 
	 
      /********************第二列有按键按下*********************/
      case 0x0b: //0000 1011 第二列有按键被按下 
      {
        P1=0xf0;//行都为高电平1,列都为低电平0
        switch(P1)//判断哪一行有按键被按下 
        {
          case 0x70: k=8;break;//第二列第一行 数字8
          case 0xb0: k=5;break;//第二列第二行 数字5
          case 0xd0: k=2;break;//第二列第三行 数字2
          case 0xe0: k=0;break;//第二列第四行 数字0
        }   
        
		if(fuhao==0)//fuhao==0,表示第一个数a,fuhao==1,表示第二个数b
          a=a*10+k;
        else
          b=b*10+k; 
        lcdwrd(0x30+k);//显示按下的数,0x30为ASCII码中数字组的开头,0x3k:显示k,即按下数字k 
      }	while(P1!=0xf0);break;//当有按键被按下时,结束此次判断,进行下一次判断
 	  
	  
	  /********************第三列有按键按下*********************/
      case 0x0d: //0000 1101 第三列有按键被按下 
      {
        P1=0xf0;//行都为高电平1,列都为低电平0
        switch(P1)//判断哪一行有按键被按下
        {
        case 0x70: num=3;k=9;break;//第三列第一行 数字9 
        case 0xb0: num=7;k=6;break;//第三列第二行 数字6 
        case 0xd0: num=11;k=3;break;//第三列第三行 数字3
        case 0xe0: num=15;break;//第三列第四行 “=”键 
        } 
        if(num!=15)//按下的键不为“=”键 
        { 
          if(fuhao==0)//fuhao==0,表示第一个数a,fuhao==1,表示第二个数b
            a=a*10+k;
          else
            b=b*10+k; 
          lcdwrd(0x30+k);//显示按下的数,0x30为ASCII码中数字组的开头,0x3k:显示k,即按下数字k
        }
        
	    /************"="键被按下************/
		if(num==15)//按下的键为=键 
        {
          switch(flag)//判断进行哪种运算 
          {
                 /*******加法运算*********/
			case 1://加法运算
            {
              c=a+b;//计算结果 
              lcdwrc(0x4f/*第二行末尾位置*/+0x80);//光标置于第二行末尾 
              lcdwrc(0x04);//设置显示方式:显示后指针减一,即前移一位 
              
			  if(c==0)//若结果为0 
                lcdwrd(0x30);//显示0 
              while(c!=0)
              {
                lcdwrd(0x30+c%10);//从后向前显示最后一位 
                c=c/10;//去掉最后一位后再循环显示 
              }
              lcdwrd(0x3d);//显示完计算结果后,显示“=” 
              }break;
 				 
				 /*******减法运算*********/
            case 2://减法运算
            {
              if(a>b)//大数减小数
                c=a-b;
              else//小数减大数
                c=b-a;//计算两数相减的绝对值 
              lcdwrc(0x4f+0x80);//将光标置于第二行末尾 
              lcdwrc(0x04);//设置显示方式:显示后指针减一 
 
              if(c==0)//若结果为零 
                lcdwrd(0x30);//显示0 
              while(c!=0) 
              {
                lcdwrd(0x30+c%10);//从后向前显示最后一位
                c=c/10;//去掉最后一位后再循环显示
              }
              if(a<b)//若结果为负数 
                lcdwrd(0x2d);//ASCII中的“-”,显示负号
              lcdwrd(0x3d);//显示= 
              }break;
 				 
				 /*******乘法运算*********/
            case 3://乘法运算
            {
              c=a*b; //计算结果 
              lcdwrc(0x4f+0x80);//光标置于第二行末尾 
              lcdwrc(0x04);//显示设置:显示后指针减一 
              if(c==0)//若结果为0 
                lcdwrd(0x30);//显示0 
              while(c!=0)  
              {                           
                lcdwrd(0x30+c%10);//从后向前显示最后一位
                c=c/10;//去掉最后一位后再循环显示 
              }
              lcdwrd(0x3d);//显示=  
            }break;
 
				 /*******除法运算*********/
            case 4: //除法运算 
            { 
              if(b==0)//若除数为0 
              { 
                lcdwrc(0x01);//清屏 
                for(j=0;j<11;j++)
                {
                  lcdwrd(ERROR[j]);//显示语句:ERROR! 
                }
                delay(1000);//延时 
                lcdinit();//重新初始化LCD1602
              }
              
			  else
              {  
                c=(long)(((float)a/b)*10000);//将结果放大10000倍,即:若无法整除,保留4位小数
                x=c;
                lcdwrc(0x4f+0x80);//光标置于第二行末尾
                lcdwrc(0x04);//显示设置:显示后指针减一
                while(c!=0)//一位一位显示
                {
                  k++;
                  lcdwrd(0x30+c%10);//显示结果的最后一位在0x4f的位置  //0  00  000  0000
                  c=c/10;//取前面的结果数据
                  if(x>0&&x<=9)//0.0001到0.0009
                  {
                    if(k==1)//只有小数点后最后一位  x.000x
                    { 
                      lcdwrd(0x30);//0
                      lcdwrd(0x30);//0
                      lcdwrd(0x30);//0 
                      lcdwrd(0x2e);//.
                      k=0;
                    }
                  }
                  if(x>9&&x<=99)//0.0010到0.0099
                  { 
                    if(k==2)//只有小数点后最后两位  x.00xx
                    { 
                    lcdwrd(0x30);//0
                    lcdwrd(0x30);//0
                    lcdwrd(0x2e);//.
                    k=0;
                    }
                  }
                  if(x>99&&x<=999)//0.0100到0.0999
                  {
                    if(k==3)//只有小数点后最后三位  x.0xxx
                    {
                      lcdwrd(0x30);//0
                      lcdwrd(0x2e);//.
                      k=0;
                    } 
                  }
                  else if(k==4)//小数点后四位都非零  x.xxxx
                  {
                    lcdwrd(0x2e);//.         
                  }  
                }
                if(x<10000)//若结果小于1,在个位补0 
                  lcdwrd(0x30);//个位补0
                lcdwrd(0x3d);//显示=
				k=0;//将k定回0用于下次计算   
              } 
            } break;
          }
        }
      }
      while(P1!=0xf0);break;//当有按键被按下时,结束此次判断,进行下一次判断
      
	  
	  /********************第四列有按键按下*********************/
      case 0x0e://0000 1110 第四列有按键被按下
      { 
        fuhao=1;//有符号键被按下 
        P1=0xf0;//1111 0000
        switch(P1)
        {
          case 0x70:/*0111 0000*/flag=4;lcdwrd(0xfd);break;//“/”第四列第一行 
          case 0xb0:/*1011 0000*/flag=3;lcdwrd(0x2a);break;//“*”第四列第二行 
          case 0xd0:/*1101 0000*/flag=2;lcdwrd(0x2d);break;//“-”第四列第三行 
          case 0xe0:/*1110 0000*/flag=1;lcdwrd(0x2b);break;//“+”第四列第四行 
        }  
      }  
      while(P1!=0xf0);break;
      }
    }
  }
}
/*****************************主函数**********************************/      
void main()
{ 
  uint x;
  lcdinit();//LCD1602初始化 
  for(x=0;x<12;x++)
    lcdwrd(wel[x]);//显示欢迎语句:Welcome 
  delay(1000); 
  lcdwrc(0x01);//LCd1602清屏 
  while(1)
  {  
	MODE();//功能判定函数
    KeyDown();//按键判断函数 
  }
}

 

 

 

到了这里,关于【附报告】51单片机计算器(LCD1602液晶显示)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于AT89C51单片机的计算器设计与仿真

    点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87759134?spm=1001.2014.3001.5503 源码获取 主要内容: 本次设计所提出的一种基于单片机技术的简易计算器的方案,能更好的解决计算机计算的问题,随着数字生活的到来,单片机在生活中越来越重要,它

    2024年02月03日
    浏览(17)
  • 基于AT89C51单片机四位加法计算器的设计

    1.设计任务 利用AT89C51单片机为核心控制元件,设计一个四位加法计算器,设计的系统实用性强、操作简单,实现了智能化、数字化。 1)、通过4*4矩阵键盘输入数字及运算符; 2)、可以进行4位十进制数以内的加法 运 算。如果计算结果超出四位数,则全部显示“E ” LED灯亮

    2024年02月04日
    浏览(25)
  • 基于AT89C51单片机的简易计算器的设计与仿真

    点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87755299?spm=1001.2014.3001.5503 源码获取 本设计是以单片机AT89C51为核心的简易计算器设计,要通过芯片AT89C51实现计算器程序运行来完成加、减、乘和除的简单计算功能。 基本要求: 1、采用软件设计与

    2024年02月03日
    浏览(24)
  • 【普中】基于51单片机简易计算器数码管显示设计( proteus仿真+程序+实物演示+讲解视频)

    【普中开发板】基于51单片机简易计算器数码管显示设计( proteus仿真+程序+实物演示+讲解视频) Proteus 仿真:Proteus 8.16(有低版本) 程序编译器:keil 4/keil 5 编程语言:C语言 设计编号:P04 普中开发板实验设计 本设计旨在设计一个基于51单片机的简易计算器仿真设计。 功能要求

    2024年02月02日
    浏览(32)
  • 单片机实现简易计算器功能,附有解析与代码

    目录 首先分为根据要实现的功能来选择硬件和软件: 硬件部分 软件部分 输入部分: 计算部分: 连续计算: 源代码示例: 主函数: 键盘输入: LCD1602显示: 蜂鸣器: 延时函数: 首先我们要实现的功能有:多位显示,小数计算,连续计算,符号按错修改,, 用到LCD1602显示

    2024年02月09日
    浏览(22)
  • 基于AT89C52单片机的计算器设计与仿真

    点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/88637995?spm=1001.2014.3001.5503 源码获取 B 源码+仿真图+课程设计+51 摘 要 计算器一般是指“电子计算器”,能进行数学运算的手持机器,拥有集成电路芯片,结构简单,功能较弱,但由于它使用方便、操

    2024年01月16日
    浏览(26)
  • 51单片机——LCD1602模块

    一.LCD1602介绍 1.LCD1602 (Liquid Crystal Display )液晶显示屏是一种字符型液晶显示模块,可以显示ASCII码的标准字符和其它的一些内置特殊字符,还可以有8个自定义字符。 2.显示容量:16x2个字符,每个字符为5*7点阵。 二.LCD1602接口介绍 引脚 功能 VSS 接地 VDD 电源正极(4.5v-5.5v) VO 对

    2024年02月07日
    浏览(16)
  • 51单片机入门——LCD1602

    LCD ( Liquid Crystal Display 的简称) 液晶显示器 。 LCD 的构造是在两片平行的玻璃基板当中放置液晶盒,下基板玻璃上设置TFT(薄膜晶体管),上基板玻璃上设置彩色滤光片,通过TFT上的信号与电压改变来控制液晶分子的转动方向,从而达到控制每个像素点偏振光出射与否而达

    2024年02月09日
    浏览(16)
  • 51单片机LCD1602的使用

    本篇文章将为大家讲解LCD1602的使用方法。 LCD1602是一种常用的液晶显示器,它的原理是通过液晶分子的振荡来控制显示内容的。液晶分子在电场的作用下,会发生振荡,从而改变液晶分子的极性,从而控制显示内容。液晶显示器的控制电路会根据输入的信号,控制电场的强度

    2024年02月06日
    浏览(16)
  • 51单片机LCD1602调试工具

    参考视频:江协科技51单片机 LCD1602头文件代码 LCD1602 C语言文件 LCD1602主函数文件

    2024年01月24日
    浏览(22)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包