lcd1602计算器.c

来自「51单片机试验板-sch-pcb-4.0M.zip」· C语言 代码 · 共 401 行

C
401
字号
#include <reg52.H>
#include <stdio.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar keytime,cal,keydown;		//获取按键次数
unsigned int a[10], num1,num2,num,result;//获取数值数组最大10位


void Print(unsigned char *str);
void mDelay(unsigned char DelayTime){//一个延时程序
unsigned int j=0;
for(;DelayTime>0;DelayTime--)
	{ for(j=0;j<125;j++) {;} }
}
void delay_50us(uint t)
{
  uchar j;
  for(;t>0;t--)
   for(j=19;j>0;j--);

}

/******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++);
	mDelay(500);
}




//定义按键显示及获取按键数值========================
void key1()
{					
Print("1");
a[keytime-1]=1;
}

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

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

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

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

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

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

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

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

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

void err(){					//部分容错机制
	GotoXY(0, 1);
Print("ERROR!");

}

void over(){					//部分容错机制
	GotoXY(0, 1);
Print("overflow!");

}

void Value()
{					//获取数值子程序,6位数以下,超过即溢出
	switch(keytime)
     {
		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 get1()
{			//用于获取第一个数
if(num1!=0)
	num1=0;
Value();
num1=num;
num=0;
}
void get2()
{
if(num2!=0)
	num2=0;
Value();
num2=num;
num=0;

}


void calculate()
{			//用于获取第二个数并计算
char val[10];
get2();
result=0;
			switch(cal){
		case 1:		result=num1+num2;	break;	//加法
		case 2:		result=num1-num2;	break;	//减法
		case 3:		result=num1*num2;	break;	//乘法
		case 4:		{if(num2==0)		//除法容错机制,处理被除数
						err();

					else
						result=num1/num2;}break;}//除法(取整)
			GotoXY(0, 1);
		if(result!=0){
		sprintf(val,"%d",result);//字符转换
		Print(val);
				
		}
		num=num1=num2=0;
		keytime=0;
}

//处理符号按键==============================
void keyadd()
{			
if(keytime>7)
over();
else
{Print("+");
cal=1;
get1();
keytime=0;}
}
void keysub()
{
if(keytime>7)
over();
else
{Print("-");
cal=2;
get1();
keytime=0;}
}
void keymul()
{
if(keytime>7)
over();
else
{Print("*");
cal=3;
get1();
keytime=0;}
}
void keydiv()
{
if(keytime>7)
over();
else
{Print("/");
cal=4;
get1();
keytime=0;}
}
keyequa()
{
Print("=");
calculate();
keytime=0;}

void keyrst()
{
cal=0;
keytime=0;
num1=0;
num2=0;
result=0;
num=0;
LCD_Write(0, 0x01);
LCD_Write(0, 0x80);
}


void Keyscan()
{

uchar temp,temp1;			//暂存
temp1=0xff;
P3=0xf0;
temp1=P3;
temp1=temp1& 0xf0;
if(temp1==0xF0)
	keydown=0;
if(temp1!=0xF0)
	mDelay(30);
if(temp1!=0xF0)
		keydown=1;//有键
	else
		keydown=0;//无键

if(keydown==1)
{
  if(keytime==16)
  {	GotoXY(0, 0);
	keytime=0;}
	temp=0xfe;			
	P3=temp;
    switch(P3)
      { case 0xee:keyrst();break;
        case 0xde:keytime++;key9();break;
        case 0xbe:keytime++;key5();break;
        case 0x7e:keytime++;key1();break;
                
       }	
	temp=0xfd;
	P3=temp;
   switch(P3)
     {case 0xed:keyequa();break;
      case 0xdd:keytime++;key0();break;
      case 0xbd:keytime++;key6();break;
      case 0x7d:keytime++;key2();break;
    }
	temp=0xfb;
	P3=temp;
    switch(P3)
     {
    case 0x7b:keytime++;key3();break;
    case 0xbb:keytime++;key7();break;
    case 0xdb:keyadd();break;
    case 0xeb:keymul();break;
    }
	temp=0xf7;
	P3=temp;
    switch(P3)
      {
       case 0x77:keytime++;key4();break;
       case 0xb7:keytime++;key8();break;
       case 0xd7:keysub();break;
       case 0xe7:keydiv();break;
      }
}

}
void Init()
{
 P0=0xff;
 P3=0xff;
 P2=0xff;
 cal=0;
 result=0;
 num1=0;
 num2=0;
 num=0;
 keytime=0;
}


void main()
{			
		
Init();
LCD_Initial();
while(1)
{	
    Keyscan();//进入键盘扫描循环
	keydown=0;
}
}




⌨️ 快捷键说明

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