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 + -
显示快捷键?