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

📄 main.c

📁 通过pid算法来对水温的测量、控制等功能
💻 C
字号:
//======================================================================
//	The information contained herein is the exclusive property of
//	Sunnnorth Technology Co. And shall not be distributed, reproduced,
//	or disclosed in whole in part without prior written permission.
//	(C) COPYRIGHT 2003 SUNNORTH TECHNOLOGY CO.
//	ALL RIGHTS RESERVED
//	The entire notice above must be reproduced on all authorized copies.
//======================================================================
//====================================================================================
//工 程 名: Temperature.spj
//功能描述: 水温的测量、控制等功能
//包含文件: main.c
//          isr.asm\key.asm\led.asm、system.asm
//          SPCE061A.h\key.h\system.h
//          SPCE061A.inc\key.inc
//硬件连接: 
//		IOA0~2		KEY1~3
//		IOA4		A/D输入
//		IOA7		继电器控制信号Ctrl
//		IOA8~15		SEG(a~f,dp)
//		IOB3~5		DIG4~6
//		IOB7		Rx1
//		IOB10		Tx1
//维护记录: 2006年9月20     v1.0
//====================================================================================

//====================================================================================
//文 件 名: main.c
//功能描述: 水温的测量、控制
//维护记录: 2006年9月20     v1.0
//====================================================================================

#include "key.h"
#include "system.h"
#include "SPCE061A.h"

typedef struct PID 
{
	float  SetPoint;										//  设定目标 Desired Value
	float  Proportion;										//  比例常数 Proportional Const
	float  Integral;										//  积分常数 Integral Const
	float  Derivative;										//  微分常数 Derivative Const
	int    LastError;										//  Error[1]
	int    SumError;										//  误差累计值
} PID;
PID  stPID;

int  fOut = 0;												// PID计算结果
float fT,K,B;    

float PIDCalc( PID *pp, int NextPoint );   					// PID计算函数             
void  ADC_temperature(void);								// AD值的数值处理
void  Send_temperature(void); 								// 温度值的通信
void  Control_temperature(void); 							// 温度控制处理
void  PIDinit(void);										// PID初始化
int   adc_data_cmp();										// ADC结果处理
void  SetPointValue();										// 设置目标温度

unsigned int    giADC_DataSave[18] ;						// ADC转换的数据
unsigned int    guiLED_Value[3] ={0,0,0};					// 保存显示的LED数字
unsigned int  	G_ADC_flag = 0;
unsigned int  	uiStep = 1;									// 设置目标温度的位数指针
unsigned int 	uiBlink;									// 设置目标温度的闪烁指针

//====================================================================================
//语法格式:int main(void)
//功能描述: 主函数
//入口参数: 无
//出口参数: 无
//====================================================================================
int main(void)
{ 
	int iKeyValue;
	System_Initial();										// 系统初始化
	while(1)
	{
		SP_INT_IRQ5();                          			// 允许ADC
		System_ServiceLoop();								// 键盘扫描
		iKeyValue = SP_GetCh();								// 取键值
		if(iKeyValue == 4 )
			SetPointValue();								// 设置目标温度
	    if(G_ADC_flag == 1)
	    {
			ADC_temperature();								// ADC结果处理得温度
			if (uiStep == 0)
			{
				Send_temperature();							// 温度送PC机
				Control_temperature();						// 根据当前温度执行控制
			}
		}
		*P_Watchdog_Clear = 0x0001;							// 清看门狗
   }
}
//=============================================================
// 语法格式:	void PIDinit(void);
// 实现功能:	PID初始化
//入口参数: 无
//出口参数: 无
//====================================================================================
void PIDinit(void)
{
	stPID.LastError = 0;
	stPID.SumError =  0;
}   

//=============================================================
// 语法格式:	PIDCalc( PID *pp, int NextPoint);
// 实现功能:	PID运算处理
// 入口参数:	PID *pp:PID指针;
//				int NextPoint:当前温度结果
// 出口参数:	PID运算结果
//=============================================================
float PIDCalc( PID *pp, int NextPoint )
{
	int dError,Error;       
	Error = pp->SetPoint*10 -  NextPoint;					// 偏差	
	dError = Error - pp->LastError;     					// 当前微分
	pp->LastError = Error;        	
	return (pp->Proportion * Error  	            		// 比例项
		-   pp->Derivative * dError				    		// 微分项
	);
}
//=============================================================
// 语法格式:	void ADC_temperature(void);
// 实现功能:	将ADC_Value转换为温度值
// 入口参数:	无
// 出口参数:	无
//=============================================================
void ADC_temperature(void)
{
	int adc_data;
	adc_data = adc_data_cmp();                     
	adc_data /= 16;        									// 计算温度平均值
	K = 0.1555;  											// 确定温度系数
	B = 32.4;												// 调整温度偏差
	fT = (adc_data * K) - B;				    	        // 换算成温度值	   
  															// 将温度值转换成十进制
	guiLED_Value[0] = (int)fT/10;		   					// 温度十位
	guiLED_Value[1] = (int)fT%10;							// 温度个位
	guiLED_Value[2] = (int)(fT*10)%10;						// 温度小数位

	G_ADC_flag = 0;
} 
//=============================================================
// 语法格式:	Send_temperature(void);
// 实现功能:	将温度值传送至上位机
// 入口参数:	无
// 出口参数:	无
//=============================================================
void Send_temperature(void)									//Uart Send
{															
	*P_UART_Data = 0xaa;									//桢头
	while((*P_UART_Command2&0x0040)==0);					//Wait
	*P_UART_Data = (int)fT;									//整数部分
	while((*P_UART_Command2&0x0040)==0);					//Wait
	*P_UART_Data = guiLED_Value[2];							//小数部分
	while((*P_UART_Command2&0x0040)==0);					//Wait
	*P_UART_Data = 0x55;									//桢尾
}
//=============================================================
// 语法格式:	Control_temperature();
// 实现功能:	设置PID调解参数,并跟据PID运算结果控制加热器
// 入口参数:	无
// 出口参数:	无
//=============================================================
void Control_temperature()
{	
	stPID.Proportion = 2;              						//设置PID比例值
	stPID.Integral   = 0;              						//设置PID积分值
	stPID.Derivative = 5;              						//设置PID微分值
	fOut = PIDCalc ( &stPID,(int)(fT*10) );					//PID计算

	if(fOut<=0)
		*P_IOA_Buffer &= 0xff7f; 			   	   	    	//温度高于设定值,关闭电炉
	else
		*P_IOA_Buffer |= 0x0080; 			        	  	//温度低于设定值,打开电炉
}
//=============================================================
// 语法格式:	adc_data_cmp();
// 实现功能:	ADC参数处理,去掉最大值和最小值
// 入口参数:	无
// 出口参数:	去除最大值和最小值后的16次采样总和
//=============================================================
int adc_data_cmp()
{
	int max;
	int min;
	int Sum=0;    
	int i;
	max = giADC_DataSave[0];
	for(i=0;i<18;i++)
	{
		if(giADC_DataSave[i]>max)     
			max = giADC_DataSave[i];        					//取出最大值
    }
	min = giADC_DataSave[0];
	for(i=0;i<18;i++){
		if(giADC_DataSave[i]<min)
			min =  giADC_DataSave[i];        					//取出最小值
	}
	for(i=0;i<18;i++)
		Sum += giADC_DataSave[i];             					//累计值
	Sum = Sum - max-min;                    					//排除最大最小值
	return(Sum);
}
//=============================================================
// 语法格式:	void SetPointValue();
// 实现功能:	设置目标温度
// 入口参数:	无
// 出口参数:	无
//=============================================================
void SetPointValue()
{	
	unsigned int iKeyValue;
	*P_INT_Ctrl_New |= 0x0008;									// 打开4Hz,用于闪烁数码管,表明当前设置位数
	uiStep = 0x3;
	uiBlink = 0x8;												// 闪烁
	*P_IOA_Buffer &= 0xff7f;
	while(1)
	{
		*P_Watchdog_Clear = 0x0001;
		System_ServiceLoop();									// 键盘扫描
		iKeyValue = SP_GetCh();									// 取键值
    	if (iKeyValue == 4)
    	{
			*P_IOB_Dir |= 0x0038 ;
    		uiStep-- ;
    		uiBlink = uiBlink << 1;  
    		if(uiStep == 0)
    		{
    			stPID.SetPoint = guiLED_Value[0]*10 
								+ guiLED_Value[1] 
								+ 0.1*guiLED_Value[2];
    		
   			break;												// 跳出while
   			}
    	}

		switch(uiStep)
		{
			case 3:
				if (iKeyValue == 2)
				{
					guiLED_Value[0]++;                  		 // 温度值增加
					if(guiLED_Value[0]==10)
						guiLED_Value[0] = 0;
				}
				else if (iKeyValue == 1)
				{
					if(guiLED_Value[0]==0)
						guiLED_Value[0] = 9;
					else
						guiLED_Value[0]--;                  	 // 温度值增加
				}
				break;
			case 2:
				if (iKeyValue == 2)
				{
					guiLED_Value[1]++;                  		 // 温度值增加
					if(guiLED_Value[1]==10)
						guiLED_Value[1] = 0;
				}
				else if (iKeyValue == 1)
				{
					if(guiLED_Value[1]==0)
						guiLED_Value[1] = 9;
					else 
						guiLED_Value[1]--;                  	 // 温度值增加
				}
				break;
			case 1:
				if (iKeyValue == 2)
				{
					guiLED_Value[2]++;                  		 // 温度值增加
					if(guiLED_Value[2]==10)
						guiLED_Value[2] = 0;
				}
				else if (iKeyValue == 1)
				{
					if(guiLED_Value[2]==0)
						guiLED_Value[2] = 9;
					else
						guiLED_Value[2]--;                  	 // 温度值增加
				}
				break;
		}
	}	
	*P_INT_Ctrl_New &= 0xFFF7;									// 关闭4Hz
}	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -