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

📄 main.c

📁 At91sam7s64+ucosII+pid温度控制
💻 C
字号:
#include "AT91SAM7S128.h"
#include "SAMinit.h"

#include "S64Pit.h"
#include "SAMIsr.h"
#include "SAMuart.h"
#include "SAMpwmc.h"
#include "SAMtc.h"
#include "SAMtwi.h"
#include "SAMadc.h"
#include "SAMdbgu.h"
#include "SAMpioc.h"
#include "SAMpioc.h"
#include "pcf8563.h"
#include "lib_at91sam7s128.h"
#include "includes.h"
#include "ADS1110.h"
#include "pid.h"
#include "st7920.h"
#include "zlg7290.h"
#include "menu.h"

#include "KEY.h"
#include "E2PROM.h"
#define TP_DEF 10		//调节参数,在温差大于该值时不使用PID
INT32U STK_TASK1[USER_TASK_STK_SIZE];
INT32U STK_TASK2[USER_TASK_STK_SIZE];
INT32U STK_TASK3[USER_TASK_STK_SIZE];
INT32U STK_TASK4[USER_TASK_STK_SIZE];

SetDat set_dat;			//设置参数的结构体
SysDat sys_dat;			//系统读取的参数结构体
pid stPid;
pid *pp;
char SysState = 0;			//当前系统状态,设置还是测量
char MenuNxt = 0;			//当前菜单项 测量状态
char MenuSet = 0;			//当前菜单项,设置状态
char MenuDsp = 0;			//设置状态,显示菜单
char CharNxt = 0;			//当前字符项
char KeyAvi = 0;			//按键有效
int OPX = 0;
int CutTime = 0;			//手动切割时的定时时间0~999秒
//char kpadj = 0;				//pid运算中kp值的调节、
int Tnow = 0;   //当前测量得到的温度
char gol_pid_calc = 0;	
char gol_work_ok = 0;		//有无设置控制温度	
char gol_motor_cut = 0;		//自动、手动切割时间到	
char gol_pwm_work = 0;		//pwm开始工作
char gol_key_down = 0;		//按键按下
char gol_pgmcut_work = 0;	//自动工作时切割与否
char gol_alarm_on = 0;		//报警开
char gol_alarm_beep = 0;	//消音键
char gol_temp_fw = 0;		//
OS_EVENT *Disp_fresh = NULL;


extern char	disp_buff[12][20];
//***************************************************

//****************************************************/

	


/*****************************************************

*****************************************************/

void task1(void *pd)
{
char s[10];

int i = 0;
int tmp ;
pd=pd;
//AT91F_DBGU_Printk("\n\rThis is debug usart test1\n\r");	
 while(1)
 {
 //	OPX++;
//	

	
 }
} 

/*****************************************************

*****************************************************/
//extern volatile unsigned int OSTime;
void task2(void *pd)
{
unsigned char j;
unsigned char KeyNum = 0;
unsigned char TimeNum = 0;
unsigned char AdNum = 0;
unsigned char PidNum = 0;
unsigned char lastsec;		//上次读到的秒
unsigned char adjnum = 0;
int 	last_ut = 0;
int 	last_tp = 0;
char calcnum = 0;
char dutynum = 0;
char pwmnum = 0;
int ADVal;
int AdGrp[13];
int ADdat;
int AdLast;

int i;
int deff_adval;
char key[4];
char s[200];
int fTnow = 0;
char flagt1 = 0;
int tmp;
unsigned short pidval = 0;
pd=pd;
pp = &stPid;
OSTimeDly(100);


read_eep(0xa1,AD_SET,(char *)&set_dat,sizeof(SetDat));
if(set_dat.FLAG==0xaa)
{
	gol_work_ok = 1;
	if(set_dat.Number <0)
	{
		set_dat.Number = 0;
	}
	else if(set_dat.Number >9999)
	{
		set_dat.Number = 9999;
	}
	if(set_dat.CutPeriod<0)
	{
		set_dat.CutPeriod = 0;
	}
	else if(set_dat.CutPeriod>999)
	{
		set_dat.CutPeriod = 999;
	}
	if(set_dat.SetTemp	<0)
	{
		set_dat.SetTemp	=0;
	}
	else if(set_dat.SetTemp	>4000)
	{
		set_dat.SetTemp	=4000;
	}
	if(set_dat.AdTemp > 999)
	{
		set_dat.AdTemp = 0;
	}
	else if(set_dat.AdTemp < -999)
	{
		set_dat.AdTemp = -999;
	}
	if(set_dat.D<0 )
	{
		set_dat.D = 0;
	}
	if(set_dat.Weight <0 )
	{
		set_dat.Weight = 0;
	}
	if(set_dat.pidkp <0)
	{
		set_dat.pidkp = 300;
	}
	if(set_dat.pidkd <0)
	{
		set_dat.pidkd = 4000;
	}
	if(set_dat.pidext <0)
	{
		set_dat.pidkd = 400;
	}
	pp->setval = set_dat.SetTemp;
}
else
{
	gol_work_ok = 0;
}
PWMCinit();
PWMCoff(AT91C_PWMC_CHID2);
pid_init(pp);

set_adc(0,0x8f);

while(1)
   {
   		//-----------ad conv----------------------------
		read_adc(0,s);
		if((s[2] & 0x80)==0)
		{
		 ADVal = s[0];
		 ADVal = ADVal <<8;
		 ADVal += s[1];
		 if((ADVal - AdLast)<100)
		 {
		 	AdLast = ADVal;
			AdGrp[AdNum] = ADVal;
		 	AdNum ++;
			if(AdNum >= 6)
			{
				AdNum = 0;
				Px(AdGrp,6);
				ADdat = aver(&AdGrp[1],4);
				i = (set_dat.AdTemp <<15)/6000;
				ADdat = ADdat + i;
				//Tnow = ((ADdat * 6000)>>15)-110;
				Tnow = ((ADdat * 6000)>>15);//-110;
				//Tnow = ((ADdat * 6000)/32767);
				//fTnow=4.79278+1.73525*Tnow;
				//Tnow = (int) fTnow;
			//	Tnow += set_dat.AdTemp;

				if(Tnow<0)
				{
					Tnow = 0;
				}
				else if(Tnow >=10000)
				{
					
					Tnow = 9999;
				}
				if(Tnow > sys_dat.Temp)
				{
					gol_temp_fw = 0;		  		//up temp
				}
				else if(Tnow < sys_dat.Temp)
				{
					gol_temp_fw = 1;
				}
				
				sys_dat.Temp = Tnow;
				
	//------------led disp----------------------			
				int2char(Tnow,s);
				if(s[0]==0)
				{ 
					s[0] = 0x1f;			//led seg is dark
					if(s[1]==0)
					{
						s[1] = 0x1f;
					}
				}
				ZLG7290_Download(0, 0, 0, s[0]);
				ZLG7290_Download(1, 0, 0, s[1]);
				ZLG7290_Download(2, 1, 0, s[2]);
				ZLG7290_Download(3, 0, 0, s[3]);
	//------------pid---------------------------
			KeyAvi = 1;
		//	if(++PidNum>1)
			{
				
				PidNum = 0;
				gol_pid_calc = 1;
			//	OSSemPost(Disp_fresh);
			}
			if(Tnow > (4050))
			{
				gol_alarm_on =1;
			}
			else if(Tnow < (4050))    //中间留0.1度的空间做滞回用
			{
				gol_alarm_on = 0;
				gol_alarm_beep = 0;
			}
			
	//---------------------------------------
			}
		  }
		  else
		  {
		  	AdLast = ADVal;
		  }
	}	 

	//---------------key------------------------
	if((AT91F_PIO_GetInput(AT91C_BASE_PIOA) & KEY_IRQ))
	{
		if(++KeyNum>=3)
		{
			beepdida();
			gol_key_down = 1;
			KeyNum = 0;
			ZLG7290_GetKey(key);
			
			key_process(key[0]);
			KeyAvi = 1;
		}
	}
//================read Time==================================
	if(++TimeNum>20)
	{
		TimeNum = 0;
		PCFGetTime(s);
		sys_dat.Time[0] = s[0]&0x7f;		//秒
		sys_dat.Time[1] = s[1]&0x7f;		//分
		sys_dat.Time[2] = s[2]&0x3f;		//时
		sys_dat.Time[3] = s[3]&0x3f;		//日
		sys_dat.Time[5] = s[5]&0x1f;		//月
		sys_dat.Time[6] = s[6];				//年
		
		if(sys_dat.Time[0] != lastsec)
		{
			CutTime = CutTime + 1;
			if(CutTime ==1000)
				CutTime = 0;
		}
		if(gol_pgmcut_work)			//自动状态时开始切割?
		{
		if(sys_dat.CutState==0)		//自动状态
		{
			if(CutTime>=set_dat.CutPeriod)
			{
				CutTime = 0;
				gol_motor_cut = 1;
			}
			else
			{
				gol_motor_cut = 0;
			}
		}
		}
	lastsec = sys_dat.Time[0];
	KeyAvi = 1;
	}
//=============================================================
//=============pid calc=======================================
if(gol_work_ok)
{
	if(gol_pid_calc)
	{
		gol_pid_calc = 0;
		
	//	pp->feed = Tnow;
		pp->feed = ADdat;
	/*	if((pp->setval-Tnow)<0)			//接近温度,停止加热
		{
			adjnum = 0;
			PWMCoff(AT91C_PWMC_CHID2);
		//	sprintf(s, "\n\rTime=%u,pid_ut=%u,CDTY2=%u,pid_err=%u,pid_derr=%u,adjnum=%u,kp = %u,kpadj=%d,temp=%u\n\r", CutTime, (unsigned short) pp->ut,AT91C_BASE_PWMC_CH2->PWMC_CDTYR,pp->err,pp->derr,adjnum,pp->kp,pp->kpadj,Tnow);
		//		AT91F_DBGU_Printk(s);
			gol_pwm_work = 0;
		}
		else */if(gol_pwm_work == 0 )
		{
			gol_pwm_work = 1;
			PWMCinit();
			Delay(DLY3);				//代替下面的语句,延时一段时间。
			pp->kpadj =0;
			adjnum = 0;
			//pid_calc(pp);				//去掉这条语句,pwm脉冲就反向控制。
			pidval = 1000;
			calcnum = 0;
			PWMCduty(AT91C_PWMC_CHID2,pidval);	
			PWMCon(AT91C_PWMC_CHID2);
	//		sprintf(s, "\n\rTime=%u,pid_ut=%u,CDTY2=%u,pid_err=%u,pid_derr=%u,adjnum=%u,kp = %u,kpadj=%d,temp=%u\n\r", CutTime, (unsigned short) pp->ut,AT91C_BASE_PWMC_CH2->PWMC_CDTYR,pp->err,pp->derr,adjnum,pp->kp,pp->kpadj,Tnow);
	//			AT91F_DBGU_Printk(s);
		}
		else
		{
			if(AT91C_BASE_PWMC->PWMC_ISR & AT91C_PWMC_CHID2)		//pwm2 isr
			{
			    i = set_dat.SetTemp - Tnow;
				deff_adval= pp->setval - ADdat;
			/*	if(++adjnum>=12 )
				{
						adjnum = 0;
						if(i>=0)
						{
							pidval = 22000;
							calcnum = 0;
						}
				}
				if((Tnow < last_tp) && (i >=0))
				{
					calcnum = 0;
					pidval = 25000;
				}
				last_tp = Tnow;	
	
		 	if(i < -1)
			{
					if(pidval>20)
						pidval = 20;
			}
			else if((i<=10))
			{
					if(pidval >25000)
					{
						pidval = 25000;
					}
			} 
			  */
			if((i<=500))		   		//从误差50度开始控制
			{
				pwmnum++;
				if(pidval >15000)
				{
					if(dutynum >= 2)	   //2/5
					{
						pidval = 100;
					}
					else
					{
						dutynum ++;
					}
				}
				if(pwmnum>=5)
				{
					pwmnum = 0;	
					dutynum = 0;
				}
			}  
			 /*
 				if(gol_temp_fw ==0)		//temp is get high
				{

					if(i<=0)
					{
						pidval = 20;
					}

				}
				else
				{
					if(Tnow <= (set_dat.SetTemp+1) )
					{
						if(pidval<600)
							pidval = 600;
					}
				}
				   */
				PWMCduty(AT91C_PWMC_CHID2,pidval);
				sprintf(s, "\n\rTime=%u,pid_ut=%u,CDTY2=%u,pid_err=%u,pid_derr=%u,adjnum=%u,kp = %u,kd = %u,ext = %u,ADdat=%d,temp=%u\n\r", CutTime, (unsigned short) pp->ut,AT91C_BASE_PWMC_CH2->PWMC_CDTYR,pp->err,pp->derr,adjnum,pp->kp,pp->kd,set_dat.pidext,ADdat,Tnow);
				AT91F_DBGU_Printk(s);
		
			//	AT91F_DBGU_Printk(disp_buff[9]);
				
				
				pid_calc(pp);
				if(calcnum==0)
				{
					pidval = (unsigned short)pp->ut;
				}
				else
				{
					calcnum--;
				}
				
			}
		}

	}
	
}

	//====================================================	 
	if(gol_work_ok)
	{
		if(gol_motor_cut)
		{
			spmotor();
			gol_motor_cut = 0;
		}
		if(gol_alarm_beep)
		{
			gol_alarm_on = 0;
			//rly1off();	
		}
		if(gol_alarm_on)
		{
			rly1on();
		}
		else
		{
			rly1off();
		}
	}	
	
	OSTimeDly(1);	
   } 
}

/*****************************************************

*****************************************************/
void task3(void *pd)
{
char s[20];
char *Dfsh_err;
int i;
char j;
char n = 0;

OSTimeDly(5);
//Disp_fresh = OSSemCreate(1);
//if (Disp_fresh==NULL)
//AT91F_DBGU_Printk("SEM CREATE ERR");
//else
//AT91F_DBGU_Printk("SEM CREATE OK");
lcd_init();

//AT91F_DBGU_Printk("\n\r===****=================\n\r");
OSTimeDly(200);
lcd_clr();
//OSSemPost(Disp_fresh);
OSTimeDly(10);

 while(1)
   {
		
	//	TWIsend(0xa1,isd ,(unsigned char *)&isd,1);

	//	sprintf(s, "\n\rFLEX_BUS=%d, ", tmp);
	//	AT91F_DBGU_Printk(s);
	//	OSTimeDly(100);
    //	sprintf(s, "\n\rISD=%d, 0x%02x\n\r", isd, tmp);
	//sprintf(s, " 0x%02x\n\r", tmp);
	//	AT91F_DBGU_Printk(s);
	//	tmp = 0x33;
//		AT91F_US_PutChar ((AT91PS_USART) AT91C_BASE_DBGU,temp);
//		AT91F_US_PutChar (COM1,temp);
//sprintf(s, "\n\rTEMP=%d\n\r", OPX);
//AT91F_DBGU_Printk(s);
//sys_dat.Temp = OPX;
		if(SysState==0)		//测量状态			
		{
			disp_init();
			//lcd_wr_cmd(0x0c);		//显示打开,光标关,反白显示关
			scr_display(MenuNxt,SysState);
			//AT91F_DBGU_Printk("SYSSTATE = 0");
			}
		else			//设置状态		
		{
		//	disp_set();
			scr_display(MenuDsp,SysState);
			lcd_wr_cmd(0x0d);		//显示打开,光标关,反白显示开
			cursor(MenuSet,CharNxt);		//光标指示
			//AT91F_DBGU_Printk("SYSSTATE = 1");
		}
	//	OSSemPend(Disp_fresh,1000,Dfsh_err);
	//	AT91F_US_PutChar ((AT91PS_USART) AT91C_BASE_DBGU,*Dfsh_err);	
		while(KeyAvi==0)
		{
			OSTimeDly(10);
		}
		KeyAvi = 0;
   } 
}
/*****************************************************

*****************************************************/
void task4()
{
int i;
AT91PS_USART COM0 = AT91C_BASE_US0;
AT91PS_USART COM1 = AT91C_BASE_US1;
char ubuff[]= {
"\n\r  *** Hello world!!! ***\n\r"
"      This is a test\n\r"
"      2007.11.28\n\r"
};
while(1)
{
OSTimeDly(500);
	for(i=0;i<100;i++)
	{

	OSTimeDly(50);

	}


}
}	

/*************************************************************************************/
void Main(void)
{
	AT91F_PIO_CfgOutput(AT91C_BASE_PIOA,RL1);
	AT91F_PIO_ClearOutput(AT91C_BASE_PIOA,RL1);
 S64Init();
 AT91F_DBGU_Init();
 Uart0Init();
 Uart1Init();
 PWMCinit();
 S64PitInit();
 TC2init();
 TWIinit();
 ADCinit();
 PIOinit();

 //PCFinit();


 OSInit();

 //OSTaskCreate(task1,(void *)0,(OS_STK *)&STK_TASK1[USER_TASK_STK_SIZE-1],0);
 OSTaskCreate(task2,(void *)0,(OS_STK *)&STK_TASK2[USER_TASK_STK_SIZE-1],6);
 OSTaskCreate(task3,(void *)0,(OS_STK *)&STK_TASK3[USER_TASK_STK_SIZE-1],5);
// OSTaskCreate(task4,(void *)0,(OS_STK *)&STK_TASK4[USER_TASK_STK_SIZE-1],3);
 //OSTaskCreate(flex_ctl,(void *)0,(OS_STK *)&STK_TASK4[USER_TASK_STK_SIZE-1],3);
 //CONSOLEsem=OSSemCreate(1);
 
 OSStart();

}

⌨️ 快捷键说明

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