📄 fsdfs.txt
字号:
/***************************************************************************************************************
水箱温度模糊控制系统设计
调试现象:
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);
led_sel=0xfd;
led_data=table[temp_int2];
delay(1);
led_sel=0xfb;
led_data=table[temp_int3]+0x80;
delay(1);
led_sel=0x0f7;
led_data=table[temp_dec];
delay(1);
led_sel=0x0ef; //显示温度表号 C
led_data=0x39;
delay(1);
led_sel=0x0df; //显示输出通电时间
led_data=table[outTime];
delay(1);
}
/*-----------------------------------------------------------------------------------------------------------------
初始化子程序
-----------------------------------------------------------------------------------------------------------------*/
void Initial(void)
{
TR=30;//给定温度
Ku=1;
Ts=6;//采样周期
TT=8;//温度常数 ,改变论域 T0
Kec=1;//温度变化常数 K
outTime=0;//输出控制时间
TMOD=0x01;
TL0=0x3c;//初始化定时器0,定时50ms
TH0=0xb0;
count_T=Ts*20;
}
/*-----------------------------------------------------------------------------------------------------------------
键盘扫描子程序
-----------------------------------------------------------------------------------------------------------------*/
uchar keyscan(void) /*键盘扫描子程序*/
{
uint i;
uchar button;
key=0xff; /*为输入键盘信息作准备*/
led_sel=0xfe;
led_data=0;
if(key==0xfe)
{
for (i=0; i<500; i++);
button=1;
while(key==0xfe);
}
if(key==0xfd)
{
for (i=0; i<500; i++);
button=2;
while(key==0xfd);
}
if(key==0xfb)
{
for (i=0; i<500; i++);
button=3;
while(key==0xfb);
}
if(key==0xf7)
{
for (i=0; i<500; i++);
button=4;
while(key==0xf7);
}
return(button);
}
/*-----------------------------------------------------------------------------------------------------------------
50ms定时子程序
说明:输出控制时间
-----------------------------------------------------------------------------------------------------------------*/
void time0_50ms(void) interrupt 1
{
uchar i=0;
TL0=0x3c;
TH0=0xb0;
i++;
if(i==count[0])
outPCM=1; //停电
if(i==count_T) //采样周期到
{
i=0;
read_flag=1;
}
}
/*-----------------------------------------------------------------------------------------------------------------
参数显示子程序
-----------------------------------------------------------------------------------------------------------------*/
void para_LED(uchar para,uchar n)
{
led_sel=0xfe;
led_data=table[para/10];
delay(1);
led_sel=0xfd;
led_data=table[para%10];
delay(1);
led_sel=0x0df; //显示输出通电时间
led_data=table[n];
delay(1);
}
/*-----------------------------------------------------------------------------------------------------------------
主程序
-----------------------------------------------------------------------------------------------------------------*/
void main(void)
{
uchar column;
uchar row;
uchar button;//按键1,2,3,4 分别表示K1 ,K2,K3,K4
uchar flag=2;//模式选择 2随机模式 1修改模式 4测控模式
uchar Tempr1; //存储温度数据
uchar Tempr2;
uchar para_count=0; //参数选择 1 Ts 2 TT 3 Ku(通电时间常数)4 TR 5 Kec (k)
uchar para;
uchar read_flag1=1;
Initial();
para=Ts;
do
{
button=keyscan();
while(flag==2) //随机模式 ,即随机显示温度
{
//TR0=0;
LED4=1;
LED5=1;
LED6=0;
outTime=0;
delay(1);
convert();
RdTemp(); //读取温度
Tempr1=temp_int;
show(); //显示温度
button=keyscan();
if(button==1) //进入修改模式
{
flag=1;
read_flag1=1;
TR0=0;
break;
}
if(button==4) //进入测控模式
{
flag=4;
read_flag1=1;
break;
}
}
while(flag==1) //修改模式
{
LED4=1;
LED5=0;
LED6=1;
button=keyscan();
switch(button)
{
case 1:
{
para_count++;
if(para_count>5)
para_count=1;
}break;
case 2:
{
if(para_count==1)
Ts++;
else if(para_count==2)
TT++;
else if(para_count==3)
Ku++;
else if(para_count==4)
TR++;
else
Kec++;
}break;
case 3:
{
if(para_count==1)
Ts=Ts-1;
else if(para_count==2)
TT=TT-1;
else if(para_count==3)
Ku=Ku-1;
else if(para_count==4)
TR=TR-1;
else
Kec=Kec-1;
}break;
case 4:
flag=2; break;
}
if(para_count==1)
para=Ts;
else if(para_count==2)
para=TT;
else if(para_count==3)
para=Ku;
else if(para_count==4)
para=TR;
else
para=Kec;
para_LED(para,para_count);
if(flag==2) //进入随机模式
{
TR0=0;
break;
}
}
while(flag==4) //测控模式
{
LED4=0;
LED5=1;
LED6=1;
if(read_flag||read_flag1) //采样
{
Tempr2=temp_int; //纪录当前采样值
column=table_E();
row=table_Ec(Tempr1,Tempr2);
outTime=Ucontrol[column][row];//查控制规则表
count=outTime*20;
TR0=1;
if(outTime>0)
outPCM=0; //通电
else
outPCM=1;
Tempr1=Tempr2; //纪录上次采样值
read_flag1=0;
read_flag=0;
}
convert();
RdTemp(); //读取温度
show();
button=keyscan();
if(button==1) //退出测控模式 ,进入 修改 模式
{
flag=1;
TR0=0;
break;
}
else if(button==2) //推出测控模式,进入随机模式
{
flag=2;
TR0=0;
break;
}
else
flag=4;
}
}
while(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -