数字温度计的程序
- 格式:doc
- 大小:42.50 KB
- 文档页数:5
#include "reg51.h"
#include "intrins.h" //_nop_();延时函数用
#define Disdata P0 //段码输出口
#define discan P2 //扫描口
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P1^2; //温度输入口
sbit DIN=P0^7; //LED小数点控制
sbit k1=P1^1; //温度设定按键
sbit k2=P1^0; //温度设定按键
sbit pwmout=P1^3; //pwm信号输出口
sbit l1=P1^4; //温度指示灯
uint h;
uint temp;
uchar xiaoshu=0,ge=0,shi=0,bai=0; //设置部分个、十、百、小数位
uchar n1=0,n2=0; //标记用
uint n3=0; //标记用
uint pwm=0x77; //pwm初值
uint w=200; //用作分段控制
程序初始定义部分
uchar code ditab[16]=
{0x00,0x01,0x01,0x02,
0x03,0x03,0x04,0x04,
0x05,0x06,0x06,0x07,
0x08,0x08,0x09,0x09};//温度显示小数部分
uchar code dis_7[12]=
{0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0xff,0xbf};//共阳LED段码表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-"
uchar code scan_con[8]=
{0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
//列扫描控制字
uchar data temp_data[2]={0x00,0x00};
//读出温度暂放
uchar data display[9]=
{0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00};
//显示单元数据,共8个数据和一个运算暂用
/*11us延时函数*/
void delay(uint t)
{
for (;t>0;t--);
} /*显示扫描函数*/
scan()
{
char k;
for(k=0;k<8;k++) //8位LED扫描控制
{
Disdata=dis_7[display[k]]; //数据显示
if (k==1||k==5){DIN=0;} //小数点显示
switch(n1) //根据n1改变输出方式
{
case 0: discan=scan_con[k];break;
default: discan=scan_con[k];break;
case 1: { if(k==4)
{ n2++;
if(n2<=50)
discan=scan_con[k];
else ;
if(n2==100)
n2=0;
}
else discan=scan_con[k];
break;
}
case 2: { if(k==5)
{ n2++;
if(n2<=50)
discan=scan_con[k];
else ;
if(n2==100)
n2=0;
}
else discan=scan_con[k];
break;
}
case 3: { if(k==6)
{ n2++;
if(n2<=50)
discan=scan_con[k];
else ;
if(n2==100)
n2=0;
}
else discan=scan_con[k];
break; }
case 4: { if(k==7)
{ n2++;
if(n2<=50)
discan=scan_con[k];
else ;
if(n2==100)
n2=0;
}
else discan=scan_con[k];
break; } }
delay(150); P2=0xff; } }
/*温度数据处理与pwm控制函数*/
work_temp(uint tem)
{
uchar n=0;
n3++;
if(tem>6348) // 温度值正负判断
{tem=65536-tem;n=1;} // 负温度求补码,标志位置1
display[8]=tem&0x0f; // 取小数部分的值
display[0]=ditab[display[8]]; // 存入小数部分显示值
display[8]=tem>>4; // 取中间八位,即整数部分的值
display[3]=display[8]/100; // 取百位数据暂存
display[1]=display[8]%100; // 取后两位数据暂存
display[2]=display[1]/10; // 取十位数据暂存
display[1]=display[1]%10;
if(xiaoshu!=0||ge!=0||shi!=0||bai!=0)
{ if(pwm<0x10)
pwm=0x10;
if(pwm>0xef)
pwm=0xef;
if((pwm>=0x10)&&(pwm<=0xef))
{ if(n3>=w)
{ n3=0;
if(display[3]!=bai)
{ w=300;
f((display[3]>bai)&&((pwm-30)>0))
pwm-=30;
if((display[3]
}
else
{ if(display[2]!=shi)
{ w=100;
if((display[2]>shi)&&((pwm-15)>0)) pwm-=15;
if((display[2]
pwm+=15;
}
else
{ if(display[1]!=ge)
{ w=50;
if((display[1]>ge)&&((pwm-7)>0))
pwm-=7;
if((display[1]
pwm+=7;
}
else
{ if(display[0]!=xiaoshu)
{ w=10;
if((display[0]>xiaoshu)&&((pwm-1)>0))
pwm--;
if((display[0]
pwm++;
} } } } } } }
if(display[3]==bai&&display[2]==shi&&display[1]==ge)
l1=0;
else
l1=1;
/*符号位显示判断*/
if(!display[3])
{ display[3]=0x0a; //最高位为0时不显示
if(!display[2])
{ display[2]=0x0a; //次高位为0时不显示
} }
if(n){display[3]=0x0b;} //负温度时最高位显示"-"
}
/*定时器0中断服务程序.*/
void timer0() interrupt 1
{ TR1=0 ;
TH0=0xfc ;
TL0=0x66 ;
TH1=pwm ;
TR1=1 ;
pwmout=0 ; //启动输出
}
/* 定时器1中断服务程序*/
void timer1() interrupt 3
{ TR1=0 ; pwmout=1; //结束输出
}
/*主函数*/
main()
{ pwminit();
Disdata=0xff; //初始化端口
discan=0xff;
for(h=0;h<4;h++) //开机显示"0000"
{display[h]=0;}
ow_reset(); //开机先转换一次
write_byte(0xcc); //Skip ROM
write_byte(0x44); //发转换命令
for(h=0;h<100;h++) //开机显示"0000"
{scan();}
while(1)
{ if(xiaoshu==0&&ge==0&&shi==0&&bai==0)
EA=0;
else
EA=1;
if(k1==0)
{ delay(500);
if(k1==0)
{ n1++;
while(!k1)
scan();
set();
}
}while(!k1);
work_temp(read_temp()); //处理温度数据
scan(); //显示温度值
} }
/***************结束**************************//