display(4,temp_T_A/100); //数码管输出模拟量十位
display(3,temp_T_A%100/10+10); //数码管输出模拟量个位
display(2,temp_T_A%100%10); //数码管输出模拟量一位小数
}
else
{
Time_Set();
for(j=80;j>0;j--)
{
display(4,(TIME-TimeGo)/100); //数码管输出模拟量十位
display(3,(TIME-TimeGo)%100/10); //数码管输出模拟量个位
display(2,(TIME-TimeGo)%100%10); //数码管输出模拟量一位小数
display(0,volt_a);
}
if(TC == ON)
for(i=100;i>0;i--)
{
display(4,23); //数码管输出模拟量十位
display(3,23); //数码管输出模拟量个位
display(2,23); //数码管输出模拟量一位小数
display(0,volt_a);
}
}
}
void Key_check(void) //按键扫描函数
{ unsigned char temp;
temp=P3&0x03;
if(temp != 0x03)
delayMS(30);
if(temp != 0x03) //当P3.4和P3.5按下时
{
if(temp==0x01) //模式设置键被按下
Auto=~Auto;
else if(temp==0x02) //定时设置键被按下
{
TC++;
if(TC==3)
TC=0;
}
}
}
void TempTrans(void)
{
if(secflag == 1)
{
secflag=0;
temp_T=rd_temperature()/10;
if(temp_T<0)
{
temp_T_A=65536-temp_T; //温度为负数时,温度的绝对值为65536与温度的差
TBZF=1;
}
else
{
temp_T_A=temp_T; //温度为负数时,温度的绝对值即为温度
TBZF=0; //当值为正值,不显示负温度标志
}
}
}
void Anto_Control_speed(void) //根据温度实现温度与转速自动控制子函数
{
switch(temp_T/10)
{
case 29: volt_d=252;break;
case 28: volt_d=224;break;
case 27: volt_d=196;break;
case 26: volt_d=168;break;
case 25: volt_d=140;break;
case 24: volt_d=112;break;
case 23: volt_d=84;break;
case 22: volt_d=56;break;
case 21: volt_d=28;break;
default: volt_d=0;
}
if(temp_T>=300)
volt_d=252;
}
void Time_Set(void)
{
if(TC == ON)
{
switch(TimeGrade)
{
case 0:TIME=0;break;
case 1:TIME=TimeGrade1;break;
case 2:TIME=TimeGrade2;break;
case 3:TIME=TimeGrade3;break;
case 4:TIME=TimeGrade4;break;
case 5:TIME=TimeGrade5;break;
case 6:TIME=TimeGrade6;break;
case 7:TIME=TimeGrade7;break;
}
}
else if(TC == Confirm)
{TR1 = 1;display(5,22);}
else
{
TIME=0;
TR1 = 0; //关闭定时器2
TimeGo=0;
}
if((TimeGo>=TIME)&&(TC == Confirm)) //定时时间到
{
TC =OFF; //关闭时间显示标志
TR1 = 0; //关闭定时器2
TimeGo=0; //定时后已运行时间清零
volt_d=0; //定时时间到后,风扇停止转动
}
}
void main()
{
Initial();
while(1)
{
TempTrans();
if(Auto == OFF) //当系统为手动控制时子函数
{
if(Ch_Full==1)
display(1,22); //在数码管1显示一横线,表示档位已经最大或者最小
DA= volt_d; //把数字量赋给数模转换器
Handle_display();
}
if(Auto == ON) //系统为自动控制时函数
{
display(5,20); //显示自动控制允许标志
DA= volt_d;
Anto_Control_speed();
Handle_display();
}
}
}
void ex0() interrupt 0 //外部中断0子程序
{
delayMS(200);
if((TC == OFF)||(TC == Confirm)) //如果不是时间设置时,实现风扇调速
{ if(volt_d<250)
{
Ch_Full=0;
volt_d+=28;
}
else
Ch_Full=1;
}
else //如果时间设置标志位打开,则定时设置
{
TimeGrade++;
if(TimeGrade==8)
TimeGrade=0;
}
}
void isr_t0(void) interrupt 1
{
TH0 = (65536-20000)/256;
TL0 = (65536-20000)%256;
tflag++;
if(tflag == 10) //定时为1秒, 每1秒采集一次温度
{
tflag = 0;
secflag = 1;
Key_check(); //每过200ms扫描按键状态
}
}
void ex1() interrupt 2 //外部中断1子程序
{
delayMS(200);
if((TC == OFF)||(TC == Confirm)) //如果不是时间设置时,实现风扇调速
{ if(volt_d>0)
{
Ch_Full=0;
volt_d-=28;
}
else
Ch_Full=1;
}
else //如果时间设置标志位打开,则定时设置
{
TimeGrade--;
}
}
void isr_t1(void) interrupt 3
{
TH1 = (65536-50000)/256;
TL1 = (65536-50000)%256;
t1flag++;
if(t1flag == 1200)
{
t1flag = 0;
TimeGo++;
}
}
数字温度传感器DS18B20部分头文件
#ifndef _DS18B20_H
#define _DS18B20_H
#include "reg51.h"
#include "intrins.h"
sbit DQ = P3^4;
bit init_ds18b20(void);
void delay(unsigned int t);
void wr_ds18b20(unsigned char byt);
unsigned char rd_ds18b20(void);
int rd_temperature(void);
#endif
数字温度传感器DS18B20部分C文件
#include "ds18b20.h"
#include "math.h"
void delay(unsigned int t)
{
while(t--);
}
//DS18B20初始化函数
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
delay(12);
DQ = 0;
delay(80); // 延时大于480us
DQ = 1;
delay(10); // 14
initflag = DQ; // initflag等于1初始化失败
delay(5);
return initflag;
}
//通过单总线向从器件写一个字节
void wr_ds18b20(unsigned char byt)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = byt&0x01;
delay(5);
DQ = 1;
byt >>= 1;
}
delay(5);
}
//通过单总线从从器件读一个字节
unsigned char rd_ds18b20(void)
{
unsigned char i;
unsigned char byt;
for(i=0;i<8;i++)
{
DQ = 0;
byt >>= 1;
DQ = 1;
if(DQ)
{
byt |= 0x80;
}
delay(5);
}
return byt;
}
//温度转换、读取及数据处理器函数
int rd_temperature(void)
{
unsigned char low,high;
unsigned int tmpvalue;
int value; //存放温度数值
float t;
init_ds18b20();
wr_ds18b20(0xCC);
wr_ds18b20(0x44); //启动温度转换
delay(200);
init_ds18b20();
wr_ds18b20(0xCC);
wr_ds18b20(0xBE); //读取寄存器
low = rd_ds18b20(); //低字节
high = rd_ds18b20(); //高字节
tmpvalue = high;
tmpvalue <<= 8;
tmpvalue |= low;
value = tmpvalue;
//使用DS18B20的默认分辨率12位, 精确度为0.0625度, 即读回数据的最低位代表0.0625度
t = value * 0.0625;
//将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入
//如t=11.0625, 进行计数后, 得到value = 1106, 即11.06 度
//如t=-11.0625, 进行计数后, 得到value = -1106, 即-11.06 度
// value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5
value = t * 100/1.25+ (value > 0 ? 0.5 : -0.5);
return value;
}
ds18b20.h不存在,把这个文件找到,然后把文件放到工程根目录下