/***************************************************************************************************************
水箱温度模糊控制系统设计
调试现象:
1 LED显示有问题
原因:温度转换时间过长(超过1S)
解决办法:去除1S延时
结果:LED正常显示,但是亮度不够
LED: 采取中断显示 ,中断时间50ms ,使用定时器1
致用楼311实验室
****************************************************************************************************************/
#include <at89x52.h>
#include <absacc.h>
#define led_data XBYTE[0xe000] /*显示数据端口*/
#define led_sel XBYTE[0xc000] /*显示器选择端口*/
#define key XBYTE[0xa000] /*键盘端口*/
#define uchar unsigned char
#define uint unsigned int
sbit ddata=P1^0; //输入温度数据端
sbit outPCM=P1^7; //控制输出端
sbit LED1=P1^1; //上限温度报警指示灯
sbit LED2=P1^2; //下限温度报警指示灯
sbit LED3=P1^3; //通电期间指示灯
sbit LED4=P1^4; //开启温度控制模式
sbit LED5=P1^5; //修改参数模式
sbit LED6=P1^6; //随机显示温度模式
uchar code table[10]={ 0x3F,0x06,0x5B,0x4F,0x66,
0x6D,0x7D,0x07,0x7F,0x6F,0x39}; /*LED显示变换*/
uchar code ttable[16]={0x0,0x01,0x01,0x02,0x03,0x03,
0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
uchar code Ucontrol[7][7]={{6,6,6,6,5,4,3},
{6,6,5,5,4,3,3},
{6,5,5,4,3,3,2},
{5,4,4,3,2,2,1},
{4,3,3,2,1,1,0},
{5,3,2,1,1,0,0},
{3,2,1,0,0,0,0}}; //输出控制规则表
uchar code period[2]={6,12};
uchar code TT[5]={2,4,6,8,10};
uchar code Kec[2]={1,2};
uchar code Ku[2]={1,2};
uchar Temp[6]={0,0,0,10,0,0};
uchar para[6]={0,6,8,1,50,1); //参数选择 1 Ts 采样周期
//2 TT 温度常数 ,改变论域 T0
//3 Ku 通电时间常数 Ton
//4 TR 给定温度
//5 Kec 温度变化常数 K
uchar count[2]; //中断次数
//count[0]输出控制时间的中断次数 count;
//count[1]采样中断次数 count_T;
uchar read_flag; //采样标志
uchar outTime; //输出控制时间
/*--------------------------------------------------------------------------------------------------------------
延时子程序
--------------------------------------------------------------------------------------------------------------*/
void delay(uint t)
{
uint i;
while(t--)
{
for(i=0;i<125;i++)
{
}
}
}
/*--------------------------------------------------------------------------------------------------------------
初始化DS18B20子
产生复位脉冲
--------------------------------------------------------------------------------------------------------------*/
void TxReset(void)
{
uint i;
ddata=0;
i=100; //拉低约900us
while(i>0)
{
i--;
}
ddata=1;
i=4;
while(i>0)
{
i--;
}
}
/*--------------------------------------------------------------------------------------------------------------
等待子程序
等待应答脉冲
--------------------------------------------------------------------------------------------------------------*/
void RxWait(void)
{
uint i;
while(ddata);
while(~ddata);
i=4;
while(i>0)
{
i--;
}
}
/*--------------------------------------------------------------------------------------------------------------
读取一位数据子程序
--------------------------------------------------------------------------------------------------------------*/
bit RdBit(void)
{
uint i;
bit b;
ddata =0;
i++;
ddata=1;
i++;
i++;
b=ddata;
i=8;
while(i>0)
{
i--;
}
return(b);
}
/*--------------------------------------------------------------------------------------------------------------
读取一个字节
--------------------------------------------------------------------------------------------------------------*/
uchar RdByte(void)
{
uchar i,j,b;
b=0;
for(i=1;i<=8;i++)
{
j=RdBit();
b=(j<<7)|(b>>1);
}
return(b);
}
/*--------------------------------------------------------------------------------------------------------------
写数据的一个字节
--------------------------------------------------------------------------------------------------------------*/
void WrByte(uchar b)
{
uint i;
uchar j;
bit btmp;
for(j=1;j<=8;j++)
{
btmp=b&0x01;
b=b>>1;
if(btmp)
{
ddata=0;
i++;
i++;
ddata=1;
i=8;
while(i>0)
{
i--;
}
}
else
{
ddata=0;
i=8;
while(i>0)
{
i--;
}
ddata=1;
i++;
i++;
}
}
}
/*--------------------------------------------------------------------------------------------------------------
启动温度转换
--------------------------------------------------------------------------------------------------------------*/
void convert(void)
{
TxReset();
RxWait();
delay(1);
WrByte(0xcc);
WrByte(0x44);
}
/*--------------------------------------------------------------------------------------------------------------
读取温度
读取温度数据
--------------------------------------------------------------------------------------------------------------*/
void RdTemp(void)
{
uchar tlsb,thsb;//存储温度数据,tlsb存低位,thsb存高位
TxReset();
RxWait();
delay(1);
WrByte(0xcc);
WrByte(0xbe);
tlsb=RdByte();
thsb=RdByte();
temp_dec=ttable[(tlsb&0x0f)]; //得到二进制小数位,在查表得到要显示的小数(保留小数点后一位)
temp_int=((tlsb&0x0f0)>>4)|((thsb&0x0f)<<4); //得到整数位
}
/*-----------------------------------------------------------------------------------------------------------------
查表求行向量 Ec
说明:每个采样周期 查 一次表 返回 行值
-----------------------------------------------------------------------------------------------------------------*/
uchar table_Ec(uchar Tempr1,uchar Tempr2)
{
uchar row;
uchar Ec;
uchar Ec1;
uchar Ec2;
uchar Ec3;
bit flag;
Ec1=Kec;
Ec2=2*Kec;
Ec3=3*Kec;
if(Tempr2>=Tempr1)
{
flag=0;
Ec=Tempr2-Tempr1;
}
else
{
flag=1;
Ec=Tempr1-Tempr2;
}
if(Ec>=Ec3)
{
if(flag)
row=0;
else
row=6;
}
else if(Ec>=Ec2&&Ec<=Ec3)
{
if(flag)
row=1;
else
row=5;
}
else if(Ec>=Ec1&&Ec<=Ec2)
{
if(flag)
row=2;
else
row=4;
}
else
{
row=3;
}
return(row);
}
/*-----------------------------------------------------------------------------------------------------------------
查表求列向量 E
说明:每个采样周期 查 一次表 返回 列 值
-----------------------------------------------------------------------------------------------------------------*/
uchar table_E(void)
{
uchar column;
uchar E1;
uchar E2;
uchar E3;
uchar E;
// uchar Tempr; //存储温度数据
uchar flag;
E1=TT/2;
E2=TT+E1;
E3=2*TT+E1;
if(TR>=temp_int)
{
flag=1;
E=TR-temp_int;
}
else
{
flag=0;
E=temp_int-TR;
}
if(E>=E3)
{
if(flag)
column=0;
else
column=6;
}
else if(E>=E2&&E<=E3)
{
if(flag)
column=1;
else
column=5;
}
else if(E>=E1&&E<=E2)
{
if(flag)
column=2;
else
column=4;
}
else
{
column=0;
}
return(column);
}
/*--------------------------------------------------------------------------------------------------------------
LED显示子程序
功能:将转换后的数据通过LED显示出来
--------------------------------------------------------------------------------------------------------------*/
void show(void)
{
uchar temp_int1;
uchar temp_int2;
uchar temp_int3;
temp_int1=temp_int/100; //取出百分位
temp_int2=(temp_int%100)/10; //取出十位
temp_int3=temp_int%10; //取出个位
led_sel=0xfe;
led_data=table[temp_int1];
delay(1
- 1
- 2
- 3
前往页