⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fuzzy_pid.c

📁 针对被控对象存在的大惯性、纯滞后的特点,采用了模糊控制方式的控制策略,设计了一种高精度温度控制算法
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************************************************

 ******************************* 
 **^_^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 + -