这段代码是基于 8051 单片机和 LCD1602 显示屏的简易四则运算器程序。程序通过按键输入数字和运算符,进行四则运算并将结果显示在 LCD 上。

#include<reg51.h>
#define uint unsigned int 
#define uchar unsigned char

sbit lcden=P1^1; // LCD1602 使能引脚, 允许使用 E
sbit rs=P1^0;
sbit rw=P1^2;
sbit busy=P0^7;
uchar mode=0; // 记录状态按钮状态

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 表示有运算符下,flag=0 表示没有运算符下
// fuhao=1 表示加法,fuhao=2 表示减法,fuhao=3 表示乘法,fuhao=4 表示除法

uchar code table[]={// 计算数字键盘输入数组
7,8,9,0,
4,5,6,0,
1,2,3,0,
0,0,0,0
};

uchar code table1[]={	// 进行后续处理显示按钮组合的数组 lcd
7,8,9,0x2f-0x30,								// 7,8,9,/
4,5,6,0x2a-0x30,								// 4,5,6,*
1,2,3,0x2d-0x30,								// 1,2,3,-
0x01-0x30,0,0x3d-0x30,0x2b-0x30	// C,0,=,+
};

void delay(uchar z) // 延时函数
{
  uchar y;
  for(z;z>0;z--)
    for(y=0;y<110;y++);
}

void write_com(uchar com) // 写命令函数
{
  rs=0;
  P0=com;    // 将 com 命令赋给 P0 端口
  delay(5);
  lcden=1;
  delay(5); 
  lcden=0;
}

void write_date(uchar date) // 写数据函数
{
  rs=1; 
  P0=date;
  delay(5);
  lcden=1;
  delay(5);
  lcden=0;
}

void init() // 初始化
{
  num=-1;
  lcden=1; // 允许控制为高电平
  rw=0;
  write_com(0x38); // 8 位,2 行
  delay(5);
  write_com(0x38); // 8 位,2 行
  delay(5);
  write_com(0x0c); // 显示开,光标禁止,不闪烁
  delay(1); 
  write_com(0x06); // 光标右移模式不左移
  delay(1);
  write_com(0x80); // 设置显示地址
  delay(1);
  write_com(0x01); // 清屏
  num_1=0;
  i=0; j=0;
  a=0;     // 第一个数与运算的数
  b=0;     // 第二个数与运算的数
  c=0;
  flag=0; // flag 表示是否有运算符 
  fuhao=0; // fuhao 表示当前输入的是哪个运算符
}

void keyscan() // 按键扫描程序
{
  P2=0xfe;//1111 1110  第一行为低电平
  if(P2!=0xfe)
  {
    delay(20);// 延时 20ms
    if(P2!=0xfe)
    {    								 // 1101 1110 & 1111 0000
      temp=P2&0xf0; // 取最低位,只留高位
      switch(temp)
      {
        // 0xe0=1110 0000,针对第 7 位按键
        case 0xe0:num=0;   break;	// 7
        case 0xd0:num=1;   break; 	// 8
        case 0xb0:num=2;   break;	// 9
        case 0x70:num=3;   break;	// /
      }
    }   
    while(P2!=0xfe);  // 1111 1110
    if(num==0||num==1||num==2)// 如果按下的是'7','8'或'9'
    {
       if(j!=0){write_com(0x01); j=0;  }
       if(flag==0)// 没有按下运算符按钮
      { a=a*10+table[num];    } // 将下面的数字保存到 a 中
      else// 如果按下了运算符按钮
      {    b=b*10+table[num];   }// 将下面的数字保存到 b 中
    }
    else// 如果按下的是'/'  	  除法
    {
      flag=1;	 // 标记已经按下运算符按钮
      fuhao=4;// 4 表示除号
    }
    i=table1[num];     // 将数据显示到上方显示区
    write_date(0x30+i);// 显示数据或运算符
  }

  P2=0xfd;  // 1111 1101
  if(P2!=0xfd)
  {
    delay(20);
    if(P2!=0xfd){  temp=P2&0xf0;
      switch(temp)
      {
        case 0xe0:num=4; break; // 4
        case 0xd0:num=5; break; // 5
        case 0xb0:num=6; break; // 6
        case 0x70:num=7; break; // *
      }
    }
    while(P2!=0xfd);// 等待松开按键
    if(num==4||num==5||num==6)// 如果按下的是'4','5'或'6'
    {
      if(j!=0){ write_com(0x01);  j=0;   }
       if(flag==0)// 没有按下运算符按钮
      { a=a*10+table[num];     }
      else// 如果按下了运算符按钮
      { b=b*10+table[num];   }
    }
    else// 如果按下的是'*'
    {
      flag=1;
      fuhao=3;// 3 表示乘号
    }
    i=table1[num];      // 将数据显示到上方显示区
    write_date(0x30+i);// 显示数据或运算符
  }

  P2=0xfb;  // 1111 1011
  if(P2!=0xfb)
  {
    delay(20);
    if(P2!=0xfb)
    {
      temp=P2&0xf0;
      switch(temp)
      {
        case 0xe0:num=8;    break;	 // 1
        case 0xd0:num=9;    break;	 // 2
        case 0xb0:num=10;   break;	 // 3
        case 0x70:num=11;   break;	 // -
      }
    }
    while(P2!=0xfb);
    if(num==8||num==9||num==10)// 如果按下的是'1','2'或'3'
    {
      if(j!=0){ write_com(0x01);  j=0;  }
        if(flag==0)// 没有按下运算符按钮
      { a=a*10+table[num];   }
      else// 如果按下了运算符按钮
      { b=b*10+table[num]; }
    }
    else if(num==11)// 如果按下的是'-'
    {
      flag=1;
      fuhao=2;// 2 表示减号
    }
    i=table1[num];  // 将数据显示到上方显示区
    write_date(0x30+i);// 显示数据或运算符
  }

  P2=0xf7; // 1111 0111
  if(P2!=0xf7){ 
      delay(20);
    if(P2!=0xf7)
    {
      temp=P2&0xf0;
      switch(temp)
      {
        case 0xe0:num=12; break;  // 清 0 按钮    
        case 0xd0:num=13; break;  // 数字 0 按钮    
        case 0xb0:num=14; break;  // 等于按钮    
        case 0x70:num=15; break;  // +
      }								   
    }
    while(P2!=0xf7);
    switch(num)
    {
      case 12:{
        if(mode==0){
        write_com(0x0f);a=0;b=0;flag=0;fuhao=0;mode++;
        }
        if(mode!=0){
        write_com(0x01);a=0;b=0;flag=0;fuhao=0;mode++;write_com(0x0f);
        }
        }// 如果按下的是"清屏"
        break;
            
      case 13:{
         if(flag==0)// 没有按下运算符按钮
         { a=a*10;  write_date(0x30);     P2=0;       }
         else if(flag>=1)// 如果按下了运算符按钮
         {  b=b*10;   write_date(0x30);       }
        }     
        break;
            
      case 14:{
          j=1; // 如果按下的是等号,根据运算符不同进行不同的处理
          write_com(0x0c); // 光标禁止
             if(fuhao==1)	   // 加法运算
                {
              write_com(0x80+0x4f);// 如果按下的是等号,先显示下方数据
                   write_com(0x04);     // 设置从后向前显示数据,每显示一次,光标前进一个位置	
                   c=a+b;   // 进行加法运算
                   while(c!=0){write_date(0x30+c%10);	c=c/10;		} 
                   write_date(0x3d);     // 再显示"="
                   a=0;b=0;flag=0;fuhao=0;
              }
             
            else if(fuhao==2)	 // 减法运算
               {
              write_com(0x80+0x4f);// 这里设置从后向前显示数据
                  write_com(0x04);     // 设置从后向前显示数据,每显示一次,光标前进一个位置
                   if(a-b>0) 
                c=a-b;
                   else 
              c=b-a;
                while(c!=0)	{
                      write_date(0x30+c%10); 
                  c=c/10;	
                } 
                if(a-b<0) 
                      write_date(0x2d);
                  if(a==b)	
                      write_date(0x30+0);	// 当两个数相等时,输出结果 0
                   write_date(0x3d);     // 再显示"="           
                   a=0;b=0;flag=0;fuhao=0;
               }
             
             else if(fuhao==3)	// 乘法运算 
             {
             write_com(0x80+0x4f); 
             write_com(0x04);
                  c=a*b;
                  while(c!=0)	
                {
                  write_date(0x30+c%10);	c=c/10; 
                } 
                  write_date(0x3d);
                  a=0;b=0;flag=0;fuhao=0;
              }

              else if(fuhao==4)// 除法运算	
                {
                write_com(0x80+0x4f);
               write_com(0x04);
                   i=0;
                  if(b!=0)
                  {
                  c=(long)(((float)a/b)*1000);
                  while(c!=0)
                    { 
                       write_date(0x30+c%10);
                       c=c/10;
                    i++; 
                      if(i==3) write_date(0x2e);
                       }
                    if(a/b<=0)
                      {
                   if(i<=2)
                    {	
                    
                      if(i==1) write_date(0x30);
                      write_date(0x2e);	   //  .
                      write_date(0x30);
                     } 
                    
                      write_date(0x30);	   // 
                }
                   write_date(0x3d);                              
                    a=0;b=0;flag=0;fuhao=0;
              }
              else
              {
                write_date('!');write_date('R');write_date('O');
                write_date('R');write_date('R');write_date('E');
              }
      }
          break;	
         case 15:{
         write_date(0x30+table1[num]);flag=1;fuhao=1;}    
         break;	// 加号	设置加号标志 fuhao=1;
    }
  }//P2!=0xf7
}

main()
{
  init();		// 初始化
  while(1)
  {
     keyscan();// 按键扫描
  }
}

代码功能解析

该程序代码实现了一个简易的计算器,主要功能包括:

  1. 数字输入: 通过按键输入数字,程序将数字保存到对应变量中。
  2. 运算符输入: 通过按键输入运算符,程序记录当前运算符。
  3. 计算: 当用户按下“=”按键时,程序根据当前运算符进行相应的计算。
  4. 结果显示: 程序将计算结果显示在 LCD1602 上。

变量定义

代码中定义了以下变量:

  • lcden, rs, rw, busy: 分别对应 LCD 的使能引脚、RS 引脚、RW 引脚和 BUSY 引脚,用于控制 LCD 的操作。
  • mode: 记录状态按钮的状态。
  • i, j, temp, num, num_1: 用于临时存储数据或进行运算。
  • a, b, c: 分别用于存储第一个数、第二个数和计算结果。
  • a_c, b_c: 用于存储浮点数,但程序中未实际使用。
  • flag: 表示是否已有运算符输入。
  • fuhao: 表示当前输入的运算符类型。
  • table: 存储数字键盘输入的数组。
  • table1: 存储显示按钮组合的数组,用于在 LCD 上显示相应的符号。

函数解析

代码中定义了以下函数:

  • delay(uchar z): 延时函数,用于控制程序执行速度。
  • write_com(uchar com): 写命令函数,用于向 LCD 发送命令。
  • write_date(uchar date): 写数据函数,用于向 LCD 发送数据。
  • init(): 初始化函数,用于初始化 LCD 和程序变量。
  • keyscan(): 按键扫描函数,用于读取按键状态并进行相应的处理。
  • main(): 主函数,程序的入口点,循环调用 keyscan 函数进行按键扫描处理。

代码分析

代码中的 keyscan 函数主要负责处理按键扫描,进行数字输入、运算符输入、计算和结果显示等操作。代码中还使用了 switch 语句和 while 循环等语句结构,实现程序的逻辑控制。

总结

该代码通过简洁的代码结构和清晰的逻辑,实现了一个功能完备的四则运算器程序。开发者可以通过分析代码,学习如何使用 8051 单片机和 LCD1602 显示屏,并掌握基本的程序设计技巧。

8051 单片机 LCD1602 计算器程序代码详解

原文地址: https://www.cveoy.top/t/topic/bzN9 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录