📄 18b20+1602液晶计算器.c
字号:
#include<at89x52.h>
#include<intrins.h>
#include<stdlib.h>
#include<stdio.h>
#include <math.h>
#include <string.h>
#define uchar unsigned char
#define uint signed int
#define pi 3.1415926
uchar key1,calc,calc1,key2=0;
uchar a[10]; //储存计算器运算过程中的数据
uchar alen; //字符串的长度
float one=0,result1=0;
#define pi 3.1415926
#define T_CONVER 0x44
#define T_CONFIG 0x5f
#define T_READ 0xbe
#define T_WRITE 0x4e
#define T_ROM_JMP 0xcc
#define T_COPY_E2 0x48
#define T_RECALL_E2 0xb8
#define T_cont 0.0625
bit T_sign;
bit flag2=1; //18B20驱动程序的标准位
sbit DQ=P2^2; //单片机与18B20的通信端
sbit a_0=ACC^0;
float temp=0;
uchar t_bai;
uint flag=0; //计算器加减乘除的标准位
void add();
uchar shuzhi[6]={0}; // 用于储存温度的数组
uchar idata seg[14]={'0','1','2','3','4','5','6','7','8','9',':','.','.','C'};
uchar* jianzero(uchar *str);
typedef unsigned char BYTE;
typedef unsigned char WORD;
typedef bit BOOL;
sbit rs=P2^3;
sbit rw=P2^5;
sbit ep=P2^7;
sbit k2=P2^6;
sbit k3=P2^4; // P2^3到P2^7用于控制液晶显示
sbit k1=P2^0;//模式切换标志位
void delay1(uint time)
{while(time--);}
void DS18B20_send(uchar out_data)
{uchar i=0;
for(i=8;i>0;i--)
{ DQ=0;
ACC=out_data&0x01;
DQ=a_0;
delay1(5);
DQ=1;
out_data>>=1;
}
}
void DS18B20_init()
{uchar i=1;
while(flag2==0)
{DQ=1;
delay1(8);
DQ=0;
delay1(52);
DQ=1;
delay1(2);
while(1)
{i=DQ;
if(i==0)
{flag2=1;
delay1(10);
break;
}
}
}
flag2=0;
}
uchar DS18B20_read(void)
{ uchar i,in_data;
in_data=0;
for(i=8;i>0;i--)
{DQ=0;
in_data>>=1;
DQ=1;
if(DQ) in_data|=0x80;
delay1(4);
}
return(in_data);
}
void ReadTemperature()
{uint y;
uchar T_L=0;
uchar T_H=0;
uchar k;
DS18B20_init();
DS18B20_send(T_ROM_JMP);
DS18B20_send( T_CONVER);
DS18B20_init();
DS18B20_send(T_ROM_JMP);
DS18B20_send( T_READ );
T_L=DS18B20_read();
T_H=DS18B20_read();
k=T_H&0x08;
if(k==0x08) T_sign=1;
else T_sign=0;
T_H=T_H&0x07;
temp=(T_H*256+T_L)*T_cont;
temp=temp*100;
t_bai=(uint)temp/10000;
y=(uint)temp%10000;
shuzhi[0]=y/1000;
y=(uint)y%1000;
shuzhi[1]=y/100;
y=(uint)y%100;
shuzhi[3]=y/10;
shuzhi[2]=11;
shuzhi[4]=12;
shuzhi[5]=13;
}
void delay(BYTE ms)
{
BYTE i;
while(ms--)
{
for(i=0;i<250;i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
/**************************************************************
函数功能:测试LED忙碌状态
入口参数:
出口参数:
***************************************************************/
BOOL lcd_bz()
{
BOOL result;
rs=0;
rw=1;
ep=1;
_nop_();
_nop_();
_nop_();
_nop_();
result=(BOOL)(P0&0x80);
ep=0;
return result;
}
/****************************************************************
函数功能:写指令数据到LCD
入口参数:cmd
出口参数:
****************************************************************/
lcd_wcmd(BYTE cmd)
{
while(lcd_bz());
rs=0;
rw=0;
ep=0;
_nop_();
_nop_();
P0=cmd;
_nop_();
_nop_();
_nop_();
_nop_();
ep=1;
_nop_();
_nop_();
_nop_();
_nop_();
ep=0;
}
/**************************************************************
函数功能:设定显示位置
入口参数:pos
出口参数:
**************************************************************/
lcd_pos(BYTE pos)
{
lcd_wcmd(pos|0x80);
}
/*************************************************************
函数功能:写入显示数据到LCD
入口参数:dat
出口参数:
**************************************************************/
lcd_wdat(BYTE dat)
{
while(lcd_bz());
rs=1;
rw=0;
ep=0;
P0=dat;
_nop_();
_nop_();
_nop_();
_nop_();
ep=1;
_nop_();
_nop_();
_nop_();
_nop_();
ep=0;
}
lcd_init()
{
lcd_wcmd(0x38);
delay(1);
lcd_wcmd(0x0c);
delay(1);
lcd_wcmd(0x06);
delay(1);
lcd_wcmd(0x01);
delay(1);
}
/*****************************/
delay1ms(uint t)
{ uchar i,j;
for(i=0;i<t;i++)
for(j=0;j<120;j++);
}
/****************************/
void clr_lcd()
{
lcd_wcmd(0x01);
delay(1);
delay(1);
}
void lcdprintf()
{
uint j;
clr_lcd();
lcd_pos(0x0f+1-alen); //用于控制数据移位
for(j=0;a[j]!='\0';j++)
{
lcd_wdat(a[j]);
}
}
uchar getkey()
{ uchar X,Y,Z;
P1=0xff;
P1=0x0f;
if(P1!=0x0f)
{
delay1ms(10);
if(P1!=0x0f)
{
X=P1;
P1=0xf0;
Y=P1;
Z=X|Y;
while(P1==Y);
switch(Z)
{ case 0x77:return'0';break;
case 0x7b:return'1';break;
case 0x7d:return'2';break;
case 0x7e:return'3';break;
case 0xb7:return'4';break;
case 0xbb:return'5';break;
case 0xbd:return'6';break;
case 0xbe:return'7';break;
case 0xd7:return'8';break;
case 0xdb:return'9';break;
case 0xdd:return'.';break;
case 0xde:flag=1; return'+';break;
case 0xe7:flag=1;return'-';break;
case 0xeb:flag=1;return'*';break;
case 0xed:flag=1;return'/';break;
case 0xee:return'=';break;
}
}
}
}
uchar getkey1()
{ uchar X,Y,Z;
P1=0xff;
P1=0x0f;
if(P1!=0x0f)
{
delay1ms(10);
if(P1!=0x0f)
{
X=P1;
P1=0xf0;
Y=P1;
Z=X|Y;
while(P1==Y);
switch(Z)
{ case 0x77:return'0';break;
case 0x7b:return'1';break;
case 0x7d:return'2';break;
case 0x7e:return'3';break;
case 0xb7:return'4';break;
case 0xbb:return'5';break;
case 0xbd:return'6';break;
case 0xbe:return'7';break;
case 0xd7:return'8';break;
case 0xdb:return'9';break;
case 0xdd:return'.';break;
case 0xde: return's';break;
case 0xe7:return't';break;
case 0xeb:return'z';break;
case 0xed:return'd';break;
case 0xee:return'g';break;
}
}
}
}
uchar* jianzero(uchar *str) //去除浮点数后面多余的零
{
uchar i;
i=strlen(str);
while((i>0)&&(str[i-1]=='0'))
{
str[i-1]='\0';
i--;
}
if(str[i-1]=='.') str[i-1]='\0';/*如果不加这句话0.5*20为10.0*/
return str;
}
void number() //数字键0-9 & 小数点'.'
{
if(flag==1)
clr_lcd();
alen=strlen(a);
if((key1>='0')&&(key1<='9'))
{
if((alen==1)&&(a[0]=='0'))
{
if(key1=='0')
{
alen=0;
key1=0;
return;
}
if(key1!='0') alen=0;
}
if(alen<10)
{
alen++;
a[alen-1]=key1;
a[alen]='\0';
}
lcdprintf();
key1=0;
}
if(key1=='.')
{
if(strpos(a,'.')<0)
{
if((alen<10)&&(alen>0))
{
alen++;
a[alen-1]=key1;
a[alen]='\0';
lcdprintf();
}
}
key1=0;
}
}
void number1() //数字键0-9 & 小数点'.'
{
if(flag==1)
clr_lcd(); //清屏函数
alen=strlen(a);
if((key2>='0')&&(key2<='9'))
{
if((alen==1)&&(a[0]=='0'))
{
if(key2=='0')
{
alen=0;
key2=0;
return;
}
if(key2!='0') alen=0;
}
if(alen<10)
{
alen++;
a[alen-1]=key2;
a[alen]='\0';
}
lcdprintf();
key2=0;
}
if(key2=='.')
{
if(strpos(a,'.')<0)
{
if((alen<10)&&(alen>0))
{
alen++;
a[alen-1]=key2;
a[alen]='\0';
lcdprintf();
}
}
key2=0;
}
}
void add() //加减乘除键'+ - * /'
{
if(a[0]=='\0')
{
key1=0;
return;
}
if(calc!=0)
{
switch(calc)
{
case '+':
one=one +atof(a);break; //atof(a)将字符串转换成浮点数
case '-':
one=one - atof(a);break;
case '*':
one=one * atof(a);break;
case '/':
one=one / atof(a);break;
}
calc=key1;
key1=0;
a[0]='\0';//这样可以使全局变量alen变成0,下一次按数字键时,只显示下一次的键值
}
else
{
calc=key1;
key1=0;
one=atof(a);
a[0]='\0';
}
}
void add1() //加减乘除键'+ - * /'
{
if(a[0]=='\0')
{
key2=0;
return;
}
calc1=key2;
key2=0;
if(calc1!=0)
{
switch(calc1)
{
case 's': result1=sin(atof(a)*pi/180);break;
case 't': result1=tan(atof(a)*pi/180);break;
case 'z': result1=pow(10,atof(a));break;
case 'd': result1=log10(atof(a));break;
case 'g': result1=sqrt(atof(a));break;
}
}
else
{
calc1=key2;
key2=0;
one=atof(a);
a[0]='\0';
}
clr_lcd();
sprintf(a,"%f",result1);//将result1以%f输出赋给数组a
strcpy(a,jianzero(a));
alen=strlen(a);
clr_lcd();/*这句话比较重要清屏函数*/
lcdprintf();
}
void dengyu() //等于键'='
{
key1=0;
if((calc==0)||(a[0]=='\0')) return;
switch(calc)
{
case '+':
result1=one + atof(a);break;
case '-':
result1=one - atof(a);break;
case '*':
result1=one * atof(a);break;
case '/':
result1=one / atof(a);break;
}
calc=0;
a[0]='\0';
clr_lcd();
sprintf(a,"%f",result1);
strcpy(a,jianzero(a));
alen=strlen(a);
clr_lcd();/*这句话比较重要清屏函数*/
lcdprintf();
}
lcdprintf1()
{
lcd_pos(0x0f);
lcd_wdat('0');
}
void int1(void) interrupt 2 //此函数用于模式切换
{
k1=~k1;
}
void into(void) interrupt 0 //此函数用于清0
{ uint i;
clr_lcd();
one=0,result1=0;
flag=0;
for(i=0;i<10;i++)
a[i]='\0';
lcdprintf1();
}
void LeD() //此函数用于显示采集的温度
{uint i;
lcd_pos(0x4A);
for(i=0;i<=5;i++)
lcd_wdat(seg[shuzhi[i]]);
}
void main()
{
uchar i;
EA=1;
EX1=1;
IT1=1;
EX0=1;
IT0=1;
k2=1;
k3=0;
k1=0;
lcd_init();// 初始化LCD
delay(10);
key1=0;
a[0]='\0';
calc=0;calc1=0;
lcd_pos(0x00);
for(i=0;i<10;i++)
{a[i]='\0';
lcd_wdat(a[i]);
}
clr_lcd(); //清屏函数
while(1)
{
ReadTemperature(); //采集温度
LeD(); //显示温度
if(k1==0)
{
key1=getkey();
if(key1!=0)
{
if((key1>='0')&&(key1<='9')||(key1=='.')) number();
if((key1=='+')||(key1=='-')||(key1=='*')||(key1=='/'))add();
if(key1=='=') dengyu();
}
}
if(k1==1){
key2=getkey1();
if(key2!=0)
{
if((key2>='0')&&(key2<='9')||(key2=='.')) number1();
if((key2=='s')||(key2=='t')||(key2=='z')||(key2=='d')||(key2=='g'))add1();
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -