⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd1602计算器2.c

📁 51单片机试验板-sch-pcb-4.0M.zip
💻 C
字号:
#include <reg52.h>
#include <math.h>
#include <string.h>
#include <intrins.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int




uchar temp,Flag,key,keynum,fuctionkey,keydown;
uint  num,num1,num2,calcuresult;
uint   a[10];



void Init();
void delay_50us(uint t);
unsigned char LCD_Wait(void);
void LCD_Write(bit Comm_Dat, unsigned char input);//向LCD写入命令或数据
void LCD_SetDisplay(unsigned char DisplayMode);
void LCD_SetInput(unsigned char InputMode);
void LCD_Initial();
void GotoXY(unsigned char x, unsigned char y);
void Print(unsigned char *str);
Value();
void  Keyscan();
void calculate();
/******LCD1602驱动程序****************************************************************/
//Port Definitions**********************************************************
sbit LcdRs		= P2^0;
sbit LcdRw		= P2^1;
sbit LcdEn  	= P2^2;
sfr  DBPort 	= 0x80;		//P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口

//内部等待函数**************************************************************************
unsigned char LCD_Wait(void)
{
	LcdRs=0;
	LcdRw=1;	_nop_();
	LcdEn=1;	_nop_();
						 
	LcdEn=0;
	return DBPort;		
}
//向LCD写入命令或数据************************************************************
#define LCD_COMMAND			0      // Command
#define LCD_DATA			1      // Data
#define LCD_CLEAR_SCREEN	0x01      // 清屏
#define LCD_HOMING  		0x02      // 光标返回原点
void LCD_Write(bit Comm_Dat, unsigned char input)
{
	LcdEn=0;
	LcdRs=Comm_Dat;
	LcdRw=0;		_nop_();
	DBPort=input;	_nop_();//注意顺序
	LcdEn=1;		_nop_();//注意顺序
	LcdEn=0;		_nop_();
	LCD_Wait();	
}

//设置显示模式************************************************************
#define LCD_SHOW			0x04    //显示开
#define LCD_HIDE			0x00    //显示关	  

#define LCD_CURSOR			0x02 	//显示光标
#define LCD_NO_CURSOR		0x00    //无光标		     

#define LCD_FLASH			0x01    //光标闪动
#define LCD_NO_FLASH		0x00    //光标不闪动

void LCD_SetDisplay(unsigned char DisplayMode)
{
	LCD_Write(LCD_COMMAND, 0x08|DisplayMode);	
}

//设置输入模式************************************************************
#define LCD_AC_UP			0x02
#define LCD_AC_DOWN			0x00      // default

#define LCD_MOVE			0x01      // 画面可平移
#define LCD_NO_MOVE			0x00      //default

void LCD_SetInput(unsigned char InputMode)
{
	LCD_Write(LCD_COMMAND, 0x04|InputMode);
}

//初始化LCD************************************************************
void LCD_Initial()
{
	LcdEn=0;
    delay_50us(5000);
    LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);   //清屏
	LCD_Write(LCD_COMMAND,0x38); 
    delay_50us(5000);               //8位数据端口,2行显示,5*7点阵
	LCD_Write(LCD_COMMAND,0x38);
	LCD_SetDisplay(0x0c);    //开启显示, 无光标
	LCD_SetInput(0x06);       //AC递增, 画面不动
    LCD_Write(LCD_COMMAND,0x80);   
    Print("LCD Calculate");
    delay_50us(5000);  
	LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);   //清屏
    LCD_Write(LCD_COMMAND,0x80);   //   
}       

//液晶字符输入的位置************************
void GotoXY(unsigned char x, unsigned char y)
{
	if(y==0)
		LCD_Write(LCD_COMMAND,0x80|x);
	if(y==1)
		LCD_Write(LCD_COMMAND,0x80|(x-0x40));
}

//将字符输出到液晶显示
void Print(unsigned char *str)
{
	while(*str!=0)
		LCD_Write(LCD_DATA,*str++);
        delay_50us(6000);
}


/*************************************************************************************/

void delay_50us(uint t)
{
  uchar j;
  for(;t>0;t--)
   for(j=19;j>0;j--);

}
/********计算处理******************************************************************/
//Calculate

void key1()
{
 					
 Print("1");
 a[keynum-1]=1;
}

void key2()
{
  Print("2");
  a[keynum-1]=2;
}

void key3()
{
  Print("3");
  a[keynum-1]=3;
}

void key4()
{
   Print("4");
   a[keynum-1]=4;
}

void key5()
{
  Print("5");
  a[keynum-1]=5;
}

void key6()
{
   Print("6");
   a[keynum-1]=6;
}

void key7()
{
  Print("7");
  a[keynum-1]=7;
}

void key8()
{  
   Print("8");
   a[keynum-1]=8;
}

void key9()
{
  Print("9");
  a[keynum-1]=9;
}

void key0()
{
  Print("0");
  a[keynum-1]=0;
}


/******************************************************************************************/
Value()
{

   switch(keynum)
   {
 		case 1:num=a[0];break;
		case 2:num=a[0]*10+a[1];break;
		case 3:num=a[0]*100+a[1]*10+a[2];break;
		case 4:num=a[0]*1000+a[1]*100+a[2]*10+a[3];break;
		case 5:num=a[0]*10000+a[1]*1000+a[2]*100+a[3]*10+a[4];break;
		case 6:num=a[0]*100000+a[1]*10000+a[2]*1000+a[3]*100+a[4]*10+a[5];break;
//	  default:return(0);break;
   }

}

/*****************************************************************************************************/
void GetValue1()   //获取第一个数值
{
   if(num1!=0)
      num1=0;
    Value();
    num1=num;
    num=0;

}

void GetValue2()   //获取第二个数值
{
   if(num2!=0)
      num2=0;
    Value();
    num2=num;
    num=0;
}
/******************************************************************************************************/
void keyadd()     //加法键'+'
{
   Print("+");
   fuctionkey=1;
   GetValue1() ; 
   keynum=0;                    
}

void  keysub()  //减法键'-'
{
  Print("-");
  fuctionkey=2;
  GetValue1();
   keynum=0;             
}
void  keyrst()   //清除键'rst'
{   
    fuctionkey=0;
    keynum=0;
    Flag=0; 
    num=0;
    num1=0; 
    num2=0;
    calcuresult=0;
    LCD_Write(LCD_COMMAND,0x01);   //清屏  
    LCD_Write(LCD_COMMAND,0x80);   //          
}

void  keyequa()  //等于键'='
{
   Print("="); 
   calculate();
   keynum=0;           
}
void keymul()  //乘法键'*'
{
   Print("*");
   fuctionkey=3;
   GetValue1();
   keynum=0;                
}

void keydiv()   //除法键'/'
{
   Print("/");
   fuctionkey=4;
   GetValue1();              
   keynum=0;
}
/**********键盘扫描******************************************************/
void Keyscan()
{
   int tmp4;			//暂存
   tmp4=0xff;
   P3=0xf0;
   tmp4=P3;
   if(tmp4==0xF0)
	keydown=0;
   if(tmp4!=0xF0)
   delay_50us(50);;
   if(tmp4!=0xF0)
		keydown=1;//有键
	else
		keydown=0;//无键
   
 if(keydown==1)
  {
 if(keynum==16)
  {	LCD_Write(0, 0x80);
	keynum=0;}
   temp=0xfe;
   P3=temp;
   if((P3&0xf0)!=0xf0)  
     {
       delay_50us(100);
       if((P3&0xf0)!=0xf0) 
         {
            switch(P3)
             {
               case 0xee:keyrst();break;
               case 0xde:keynum++;key9();break;
               case 0xbe:keynum++;key5();break;
               case 0x7e:keynum++;key1();break;
             }
         }
   }

    temp=0xfd;
    P3=temp;
   if((P3&0xf0)!=0xf0)  
     {
       delay_50us(100);
       if((P3&0xf0)!=0xf0) 
         {   
            switch(P3)
             {
               case 0xed:keyequa();break;
               case 0xdd:keynum++;key0();break;
               case 0xbd:keynum++;key6();break;
               case 0x7d:keynum++;key2();break;
             }
         }
     }

    temp=0xfb;
    P3=temp;
      if((P3&0xf0)!=0xf0)  
     {
       delay_50us(100);
       if((P3&0xf0)!=0xf0) 
         {   Flag=1;
            switch(P3)
             {
               case 0xeb:keymul();break;
               case 0xdb:keyadd();break;
               case 0xbb:keynum++;key7();break;
               case 0x7b:keynum++;key3();break;
             }
          }
      }

     temp=0xf7;
   P3=temp;
      if((P3&0xf0)!=0xf0)  
     {
       delay_50us(100);
       if((P3&0xf0)!=0xf0) 
         {  Flag=1;
            switch(P3)
             { 
               case 0xe7:keydiv();break;
               case 0xd7:keysub();break;
               case 0xb7:keynum++;key8();break;
               case 0x77:keynum++;key4();break;
             }
         }
     } 
  }
 
     keydown=0;

}
/****************************************************************************************/
void calculate()
{
    uchar b[10];
    GetValue2();
    calcuresult=0;//再次保证 calcuresut=0;
    
    switch(fuctionkey)
    {
      case 1: calcuresult=num1+num2;break;
      case 2: calcuresult=num1-num2;break;
      case 3: calcuresult=num1*num2;break;
      case 4: {if(num2==0)
                {
                 GotoXY(0, 0);
                 Print("Input is error!");
                 GotoXY(0, 1); 
                 Print("Please restart!");                
                }
                else
                calcuresult=num1/num2;}break;
    } 

  /**********************************************
   char     String[8];   //sprintf使用例子
   int   dataddd;   
   sprintf(String,"%d",dataddd);   
    
   如果dataddd=10           String="31,30,00,00,00,00,00,00";   
   sprintf(String,"%2.1f",dataddd);   
    
   如果dataddd=10.5           String="31,30,2e,35,00,00,00,00";
  /**********************************************/
      GotoXY(0, 1);
      sprintf(b,"%d",calcuresult);
      Print(b);
   num1=num2=num=0;
   keynum=0;    
}




void Init()
{
 P0=0xff;
 P3=0xff;
 P2=0xff;
 Flag=0;
 fuctionkey=0;
 calcuresult=0;
 num1=0;
 num2=0;
 num=0;
 keynum=0;
}



void main()
{
 Init();
 LCD_Initial();
 while(1)
  {  
     Keyscan();

  }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -