数字温度计仿真图+源程序

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

源程序
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
ucharyear,mon,day,xinqi;
ucharsecond,minute,hour;
ucharReadValue;
uchardown,count;
uchar flag; // 加减标志位
char newsec,newmin,newhour; //重写数据用的秒,分,时char newyear,newmon,newday,newxinqi;
uchar q;
//---------------------
ucharbai,shi,ge,fen,miao;
#define t_cont 0.0625
#define conever 0x44
#define config 0x5f
#define read 0xbe
#define write 0x4e
#define jmp 0xcc
#define copy 0x48
#define recall 0xb8
sbitfmq=P2^3;
sbitrs = P2^0;
sbitrw = P2^1;
sbit e = P2^2;
sbit K1=P3^4;
sbit K2=P3^5;
sbit K3=P3^6;
sbit K4=P3^7;
sbit DATA=P1^0; //位定义1302芯片的接口sbit SCLK=P1^1; //位定义1302芯片的接口sbit RST =P1^4; //位定义1302芯片的接口bit t_sign;
bit flag1;
sbit a=ACC^0;
sbitdq=P1^5;
float temp=0;
//----------------------------------------
//函数声明
//----------------------------------------
void delayus(uint n);
void delayms(uint k);
void mingling(uchar com);
void Write1302(uchardat);
uchar Read1302(void);
void WriteSet1302(ucharCmd,uchardat);
uchar ReadSet1302(ucharCmd);
void Int1302(void);
void readtime(void);
void display(void);
void Setdisplay(void);
void menu(void);
void inmenu(void);
void max();
void min();
void funcinc();
void turn_sub(ucharnewval,ucharnewaddr); void scanquit();
void funcquit();
//--------------------------------------------------------
//函数功能:us延时
//-------------------------------------------------------- void delayus(uint n)
{
uchar i;
for(i=0;i<n;i++);
}
void delayms(uint k)
{
uchar i;
for(i=0;i<k;i++)
delayus(100);
}
void delaya(uint m)
{
while(m--);
}
void init_1820()
{
uchar i=1;
while(flag1==0)
{
dq=1;
delaya(8);
dq=0;
delaya(52);
dq=1;
delaya(2);
while(1)
{
i=dq;
if(i==0)
{
flag1=1;
delaya(10);
break;
}
}
}
flag1=0;
}
/*************向1820发送字节************/ void byte_1820(uchardat)
{
uchar i=0;
for(i=0;i<8;i++)
{
dq=0;
ACC=dat&0x01;
dq=a;
delaya(5);
dq=1;
dat>>=1;
}
}
/**************读1820的数据*************/ uchar read_1820(void)
{
uchari,indat;
indat=0;
for(i=0;i<8;i++)
{
dq=0;
indat>>=1;
dq=1;
if(dq) indat|=0x80;
delaya(4);
}
return(indat);
}
/************获取TEM*****************/ void readtem()
{
uint y;
uchar td=0;
uchartg=0;
uchar k;
init_1820();
byte_1820(jmp);
byte_1820(conever);
init_1820();
byte_1820(jmp);
byte_1820(read);
td=read_1820();
tg=read_1820();
k=tg&0x08;
if(k==0x08)
{t_sign=1;
tg=tg&0x07;
temp=(tg*256+td)*t_cont;
temp=(-temp*100+52800);}
else {t_sign=0;tg=tg&0x07;
temp=(tg*256+td)*t_cont;
temp=temp*100;}
bai=(uint)temp/10000;
y=(uint)temp%10000;
shi=y/1000;
y=(uint)y%1000;
ge=y/100;
y=(uint)y%100;
fen=y/10;
miao=(uint)y%10;
}
//----------------------------------------------------------------------
//函数功能:向1302写一个字节数据
//----------------------------------------------------------------------
void Write1302(uchardat)
{
uchar i;
SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备delayus(2); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续写8个二进制位数据
{
DATA=dat&0x01; //取出dat的第0位数据写入1302
delayus(2); //稍微等待,使硬件做好准备
SCLK=1; //上升沿写入数据
delayus(2); //稍微等待,使硬件做好准备
SCLK=0; //重新拉低SCLK,形成脉冲
dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位}
}
//-----------------------------------------------------------------------
//函数功能:从1302读一个字节数据
//-----------------------------------------------------------------------
uchar Read1302(void)
{
uchari,dat;
delayus(2); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续读8个二进制位数据
{
dat>>=1; //将dat的各数据位右移1位,因为先读出的是字节的最低位if(DATA==1) //如果读出的数据是1
dat|=0x80; //将1取出,写在dat的最高位
SCLK=1; //将SCLK置于高电平,为下降沿读出
delayus(2); //稍微等待
SCLK=0; //拉低SCLK,形成脉冲下降沿
delayus(2); //稍微等待
}
return dat; //将读出的数据返回
}
//-----------------------------------------------------------------------
//函数功能:根据命令字,向1302写一个字节数据
//-----------------------------------------------------------------------
void WriteSet1302(ucharCmd,uchardat)
{
RST=0; //禁止数据传递
SCLK=0; //确保写数居前SCLK被拉低
RST=1; //启动数据传输
delayus(2); //稍微等待,使硬件做好准备
Write1302(Cmd); //写入命令字
Write1302(dat); //写数据
SCLK=1; //将时钟电平置于已知状态
RST=0; //禁止数据传递
}
//----------------------------------------------------------------------
//函数功能:根据命令字,从1302读取一个字节数据
//----------------------------------------------------------------------
uchar ReadSet1302(ucharCmd)
{
uchardat;
RST=0; //拉低RST
SCLK=0; //确保写数居前SCLK被拉低
RST=1; //启动数据传输
Write1302(Cmd); //写入命令字
dat=Read1302(); //读出数据
SCLK=1; //将时钟电平置于已知状态
RST=0; //禁止数据传递
return dat; //将读出的数据返回
}
//----------------------------------------------------------------------
//读取1302内部时间到second,minute,hour;
//----------------------------------------------------------------------
void readtime(void)
{
ReadValue = ReadSet1302(0x81); //从秒寄存器读数据second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
ReadValue = ReadSet1302(0x83); //从分寄存器读minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
ReadValue = ReadSet1302(0x85); //从分寄存器读hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
ReadValue = ReadSet1302(0x87); //从分寄存器读
day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = ReadSet1302(0x89); //从分寄存器读
mon=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = ReadSet1302(0x8d); //从分寄存器读
year=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = ReadSet1302(0x8b); //从分寄存器读
xinqi=(ReadValue&0x0F);
}
//--------------------------------------------------------------------------------
//DS1302的充电设置
//--------------------------------------------------------------------------------
void Int1302(void)
{
second=ReadSet1302(0x81);
second=((second&0x70)>>4)*10+(second&0x0f);
WriteSet1302(0x8e,0x00); //允许写入1302
WriteSet1302(0x90,0xa9); //打开充电二极管
WriteSet1302(0x80,(((second&0x7f)/10)<<4)|(second%10)); //保存当前秒并允许ds1302工作
WriteSet1302(0x8e,0x10); //禁止写入1302
}
//----------------------------------------------------
//调时菜单进入
//----------------------------------------------------
void menu(void)
{
if(!K1)
{
delayms(1);
if(!K1)
{
down=1;
while(K1!=1); //等待按键松开,如果按键不松,while条件成立进行空的死循环
count++; //记录menu按下的次数
if(count>7)count=1;
WriteSet1302(0x8e,0x00); //允许写入1302
second=ReadSet1302(0x81);
WriteSet1302(0x80,0x80|second); //按下menu键后禁止ds1302工作,把秒写回1302
WriteSet1302(0x8e,0x10); //禁止写入1302
}
}
}
//----------------------------------------------------------------------
//进入菜单,调时程序
//----------------------------------------------------------------------
void inmenu(void)
{
switch(count)
{
case 1:{
max();
min();
mingling(0xc7);
mingling(0x0f);//开显示显示光标
scanquit();
}break;
case 2:{
max();
min();
mingling(0xc4);
mingling(0x0f);//开显示显示光标
scanquit();
}break;
case 3:{
max();
min();
mingling(0xc1);
mingling(0x0f);//开显示显示光标
scanquit();
}break;
case 4:{
max();
min();
mingling(0x89);
mingling(0x0f);//开显示显示光标scanquit();
}break;
case 5:{
max();
min();
mingling(0x86);
mingling(0x0f);//开显示显示光标scanquit();
}break;
case 6:{
max();
min();
mingling(0x83);
mingling(0x0f);//开显示显示光标scanquit();
}break;
case 7:{
max();
min();
mingling(0x8d);
mingling(0x0f);//开显示显示光标scanquit();
}break;
default:break;
}
}
//---------------------------------------------------
//---------------------------------------------------
void max() //判断加
{
if(!K2)
{
delayms(1);
if(!K2)
while(!K2);
flag=1;
funcinc();
}
}
void min() //判断减
{
if(!K3)
{
delayms(1);
if(!K3)
while(!K3);
flag=0;
funcinc();
}
}
//----------------------------------------------------
void funcinc()
{
switch(count)
{
case 1:turn_sub(newsec,0x81);
second=ReadSet1302(0x81);
WriteSet1302(0x80,0x80|second);
break;
case 2:turn_sub(newmin,0x83);
break;
case 3:turn_sub(newhour,0x85);
break;
case 4:turn_sub(newday,0x87);
break;
case 5:turn_sub(newmon,0x89);
break;
case 6:turn_sub(newyear,0x8d);
break;
case 7:turn_sub(newxinqi,0x8b);
break;
default: break;
}
}
//--------------------------------------------------------------- void turn_sub(ucharnewval,ucharnewaddr)
{
newval=ReadSet1302(newaddr); //读取当前时间
newval=((newval&0x70)>>4)*10+(newval&0x0f); //将bcd码转换成十进制
if(flag==1)newval++;
else newval--;
switch(count)
{
case 1: if(newval>59) newval=0;break;
case 2: if(newval>59) newval=0;break;
case 3: if(newval>23) newval=0;break;
case 4: if(newval>31) newval=0;break;
case 5: if(newval>12) newval=0;break;
case 6: if(newval>99) newval=0;break;
case 7: if(newval>6) newval=0;break;
default:break;
}
WriteSet1302(0x8e,0x00); //允许写入1302
WriteSet1302((newaddr-1),((newval/10)<<4)|(newval%10)); //将新数据写入寄存器WriteSet1302(0x8e,0x10); //禁止写入1302
display(); //将修改后的值显示出来
}
//-----------------------------------------------------
//-----------------------------------------------------
void scanquit()
{
if(!K4)
{
mingling(0x0c);
delayms(1);
if(!K4)
while(!K4);
funcquit();
}
}
void funcquit()
{
mingling(0x0c);
count=0;
down=0;
second=ReadSet1302(0x81);
second=((second&0x70)>>4)*10+(second&0x0f);
WriteSet1302(0x8e,0x00);
WriteSet1302(0x80,(((second&0x7f)/10)<<4)|(second%10)); //保存当前秒并允许ds1302工作
WriteSet1302(0x8e,0x10);
}
//---------------------------------------------------------------------- //显示程序
//---------------------------------------------------------------------- //////////////命令/////////////////////
void delay(uint m)
{
uinti,j;
for(i=0;i<m;i++)
for(j=0;j<570;j++);
}
bit lcd_bz()
{
bit result;
rs=0;
rw=1;
e=1;
_nop_();
_nop_();
_nop_();
_nop_();
result=(bit)(P0&0x80);
e=0;
return(result);
}
void mingling(uchar com)
{
while(lcd_bz());
rs=0;
e=0;
rw=0;
P0=com;
e=1;
e=0;
delay(1);
}
void lcd_pos(ucharpos)
{
mingling(pos);
}
//////////////数据/////////////////////
void shuju(ucharshu)
{
rs=1;
rw=0;
e=0;
P0=shu;
e=1;
e=0;
delay(1);
}
////////////初始化//////////////////////
void init_1602(void)
{
mingling(0X38);//功能设置
delay(1);
mingling(0X0c);//显示开关控制
delay(1);
mingling(0X06);//输入方式设置
delay(1);
mingling(0X01);//清显示
delay(1);
}
//////////////显示//////////////////
void date(void)
{
switch(xinqi)
{
case 0: shuju('S');shuju('u');shuju('n');break;
case 1: shuju('M');shuju('o');shuju('n');break;
case 2: shuju('T');shuju('u');shuju('e');break;
case 3: shuju('W');shuju('e');shuju('d');break;
case 4: shuju('T');shuju('h');shuju('u');break;
case 5: shuju('F');shuju('r');shuju('i');break;
case 6: shuju('S');shuju('a');shuju('t');break;
default:break;
}
}
void display(void)
{
readtem();
readtime();
while(lcd_bz());
delay(100);
lcd_pos(0x80);
shuju('2');shuju('0');
shuju(year/10+0x30);
lcd_pos(0x83);
shuju(year%10+0x30);shuju('/');
shuju(mon/10+0x30);shuju(mon%10+0x30);shuju('/'); shuju(day/10+0x30);shuju(day%10+0x30);
lcd_pos(0xc0);
shuju(hour/10+0x30);shuju(hour%10+0x30);shuju(':'); shuju(minute/10+0x30);shuju(minute%10+0x30);shuju(':'); shuju(second/10+0x30);shuju(second%10+0x30);
lcd_pos(0x8c);date();
lcd_pos(0xc8);
if(t_sign==1)
{
shuju(0x2d);
delaya(10);
if(bai!=0)
shuju(0x20);
shuju(shi+0x30);
shuju(ge+0x30);
shuju(0x2e);
shuju(fen+0x30);
shuju(miao+0x30);
shuju(0xdf);
shuju(0x43);
}
else
{
shuju(0x20);
delaya(10);
if(bai!=0)shuju(bai+0x30);
else shuju(0x20);
shuju(shi+0x30);
shuju(ge+0x30);
shuju(0x2e);
shuju(fen+0x30);
shuju(miao+0x30);
shuju(0xdf);
shuju(0x43);}
/********/
if((shi>=3&&ge>=3)||(shi<=2&&ge<=9))
{
fmq=0;
}
if((shi<=3&&ge<3)||(shi>=2&&ge>9))
fmq=1;
}
//---------------------------------------------------------------------- //函数功能:主函数
//---------------------------------------------------------------------- void main(void)
{
Int1302();
init_1602();
init_1820();
down=0;
count=0;
while(1)
{
menu(); //检测是否调时
if(down==1)
{
inmenu(); //进入调时模式
}
else
{
while(lcd_bz());
display();
}
}
}。

相关文档
最新文档