📄 fuzzy_pid.c
字号:
/***************************************************************************************************************
*******************************
**^_^Challenge Everything^_^**
*******************************
水箱温度模糊控制系统设计
设计思路:
将程序划分为三个模式:1 随机模式(随机显示温度)
2 修改模式(修改参数设定值)
3 测控模式(每个周期测一次温度并显示出来,输出通电脉冲 )
调试现象:
1 LED显示有问题
原因:温度转换时间过长(超过1S)
解决办法:去除1S延时
结果:LED正常显示,但是亮度不够
2 串口向PC机发送温度数据时,发现显示的温度不正常(发送语句为printf("%d",Temp[4])),
如50度,在PC机上显示1280度。经分析,可能是字节顺序的问题:单片机为小端字节序,PC机为大端字节序。
因此,0010 1000(50)就变成了 0000 0101 0000 0000 (1280)
温度传感器DS1820测量温度
2007/01/15
8:56
致用楼311实验室
****************************************************************************************************************/
#include <reg52.h>
#include <absacc.h>
#include<stdio.h>
#define led_data XBYTE[0xe000] /*显示数据端口*/
#define led_sel XBYTE[0xc000] /*显示器选择端口*/
#define key XBYTE[0xa000] /*键盘端口*/
#define uchar unsigned char
#define uint unsigned int
#define Temp_max 80
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[13]={ 0x3F,0x06,0x5B,0x4F,0x66,
0x6D,0x7D,0x07,0x7F,0x6F,0x39,0x63,0}; //LED显示变换 C O 灭
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,5,5,4,3}, //输出控制规则表
{6,5,4,3,3,2,1},
{4,3,2,1,0,0,0},
{3,2,1,0,0,0,0},
{3,2,1,0,0,0,0},
{2,1,0,0,0,0,0},
{1,0,0,0,0,0,0}};
uchar Temp[7]; //存储温度
//0 十位
//1 个位
//2 小数位
//3 温度标号 C
//4 前次温度
//5 当前温度
uchar para[5]={6,8,1,50,1}; //存储参数 0 Ts 采样周期
//1 TT 温度常数 ,改变论域 T0
//2 Ku 通电时间常数 Ton
//3 TR 给定温度
//4 Kec 温度变化常数 K
uchar count[3]; //中断次数
//count[0]输出控制时间的中断次数 ;
//count[1]采样中断次数 ;
//count[2]记录中断次数
bit serial_flag; //开启串口发送数据标志
bit read_flag; //采样标志
uchar outTime=0; //输出控制时间
uchar button; //按键1,2,3,4 分别表示K1 ,K2,K3,K4
uchar parameter=0; //参数标号
uchar show_LED[7]={2,0,0,7,0,1,12}; //LED灯显示值
/**************************************************************************************************
延时子程序
说明:uchar t 最多可延时256ms (uint t可用于更长时间的延时)
***************************************************************************************************/
void delay(uchar t)
{
uchar i;
while(t--)
{
for(i=0;i<125;i++)
{
}
}
}
/***************************************************************************************************
LED显示子程序
功能:
***************************************************************************************************/
void show(void)
{
uchar i;
uchar led_settle=0xfe;
for(i=0;i<7;i++)
{
led_sel=led_settle;
if(i==1)
led_data=table[show_LED[i]]+0x80;
else
led_data=table[show_LED[i]];
led_settle=(led_settle<<1)|(led_settle>>7);
delay(1);
}
/* led_sel=0xfe; //显示十位
led_data=table[show_LED[0]];
delay(1);
led_sel=0xfd;
led_data=table[show_LED[1]]+0x80; //显示个位
delay(1);
led_sel=0xfb; //显示小数位
led_data=table[show_LED[2]];
delay(1);
led_sel=0xf7; //显示温度表号 C
led_data=table[show_LED[3]];
delay(1);
led_sel=0xef;
led_data=table[show_LED[4]];
delay(1);
led_sel=0xdf; //显示输出通电时间
led_data=table[show_LED[5]];
delay(1); */
}
/***************************************************************************************************
键盘扫描子程序
***************************************************************************************************/
void keyscan(void)
{
// uchar i;
// uchar key_settle=0xfe;
key=0xff; //为输入键盘信息作准备
led_sel=0xfe;
// led_data=0;
/* for(i=1;i<5;i++)
{
delay(4);
if(key==key_settle)
{
button=i;
while(key==key_settle);
}
key_settle=(key_settle<<1)|(key_settle>>7);
}
button=0; */
if(key==0xfe)
{
// for (i=0; i<500; i++);
delay(4);
button=1;
while(key==0xfe);
}
else if(key==0xfd)
{
// for (i=0; i<500; i++);
delay(4);
button=2;
while(key==0xfd);
}
else if(key==0xfb)
{
//for (i=0; i<500; i++);
delay(4);
button=3;
while(key==0xfb);
}
else if(key==0xf7)
{
//for (i=0; i<500; i++);
delay(4);
button=4;
while(key==0xf7);
}
else
button=0;
}
/***************************************************************************************************
初始化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存高位
convert(); //开启温度转换
TxReset();
RxWait();
delay(1);
WrByte(0xcc);
WrByte(0xbe);
tlsb=RdByte();
thsb=RdByte();
Temp[2]=ttable[(tlsb&0x0f)]; //得到二进制小数位,在查表得到要显示的小数(保留小数点后一位)
Temp[4]=((tlsb&0x0f0)>>4)|((thsb&0x0f)<<4); //得到整数位
Temp[0]=Temp[4]/10; //得到十位数
Temp[1]=Temp[4]%10; //得到个位
if(Temp[4]>Temp_max) //达到上限温度报警
LED1=0;
else
LED1=1;
}
/***************************************************************************************************
查表求行向量 Ec
说明:每个采样周期查表返回行值
***************************************************************************************************/
uchar table_Ec(void)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -