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

📄 main.c

📁 基于增量式PID控制算法的数控横流源的设计
💻 C
字号:

#include "config.h"
#include "zlg7290.h"
#include "I2CINT.h"

volatile uint8 key_flag;	//键盘中断标志
volatile uint16 duty;	//占空比
volatile uint16 feedcurrent;	//反馈电流
volatile uint16	setcurrent;	//设定电流
volatile fp32 kp; //比例系数
volatile fp32 ki; //积分系数 
volatile fp32 kd; //微分系数
volatile fp32 e[3]; //偏差数组
uint8 buff[8];		//显示缓存

void Delay(uint32 dly)
{  uint8  i;

   for(; dly>0; dly--) 
      for(i=0; i<100; i++);
}

//键盘中断处理函数
void __irq IRQ_Key(void)
{
	
	
	key_flag=1;
	
	EXTINT=0x04;
	VICVectAddr=0x00;
}

//键盘中断初始化
void Key_Int()
{
	PINSEL0=(PINSEL0&0xffff0fff)|(1<<15)|(1<<14);	//中断2,P0.7,16号
	VICIntSelect=0x00000000;
	VICVectCntl1=(0x20|16);
	VICVectAddr1=(int)IRQ_Key;
	EXTPOLAR=0x00;
	EXTMODE=0x04;
	EXTINT=0x04;
	VICIntEnable|=(1<<16);
}

//程序初始化函数
void Init_all()
{
	//-------PWM Init
	setcurrent=500;		//初始设置占空比50%
	duty =0;               //初始输出占空比为0
	PINSEL0|=0x00080000;	//PWM6
	PWMPR=0x00;
	PWMMCR=0x02;
	PWMMR0=1024;	//周期1024
	PWMMR6= duty;	
	PWMLER=0x41;
	PWMPCR=0x4000;
	PWMTCR=0x09;
	//---------PWM Init
	
	//---------ADC Init----------
	PINSEL1|=(1<<28)|(0<<29);	//AIN3
	ADCR=(1<<3)|
		 ((Fpclk/1000000-1)<<8)|
		 (0<<16)|
		 (0<<17)|
		 (1<<21)|
		 (0<<22)|
		 (0<<24)|		//don't start
		 (0<<27);
	//---------ADC Init-----------
	
	I2C_Init(30000);
	Key_Int();
	key_flag=0;
	//--------PID Init------------
	e[1] = 0;
	e[2] = 0;
	kp = 0.175;
	ki =2.95;
	kd = 0.932;
	//--------PID Init------------
}

//ADC转换函数
uint32 ADC_relust()
{
	uint32 adc;
	ADCR|=(1<<24);	//start adc
	//while((ADDR&80000000)==0);	//wait adc finish
	Delay(100);
	ADCR|=(0<<24);	//close adc
	adc=ADDR;
	adc=(adc>>6)&0x000003ff;
	return adc;
}




//键盘输入电流值处理
uint16 Input_Current()
{
	uint8 key;
	uint32	key_counter=0;
	uint16 incurrent,temp;
	incurrent=0;
	buff[3]=0;	buff[2]=0;	buff[1]=0;	buff[0]=0;
	ZLG7290_SendBuf(buff,8);
	while(1)
	{
		while(key_flag==0);	//等待键按下
		key_flag=0;
		Delay(100);	
		key=ZLG7290_GetKey();
		if(key_counter==4)		
		{	
			if(key!=11&key!=12)
				continue;
		}
		switch(key)
		{
			case 1:
				incurrent=incurrent*10+1;
				key_counter++;
				break;	
			case 2:		
				incurrent=incurrent*10+2;
				key_counter++;
				break;	
				
			case 3:
				incurrent=incurrent*10+3;
				key_counter++;
				break;	
						
			case 4:		
				incurrent=incurrent*10+4;
				key_counter++;
				break;	
				
			case 5:
				incurrent=incurrent*10+5;
				key_counter++;
				break;	
						
			case 6:		
				incurrent=incurrent*10+6;
				key_counter++;
				break;	
				
			case 7:		
				incurrent=incurrent*10+7;
				key_counter++;
				break;	
				
			case 8:		
				incurrent=incurrent*10+8;
				key_counter++;
				break;	
				
			case 9:		
				incurrent=incurrent*10+9;
				key_counter++;
				break;	
				
			case 10:
				if(key_counter==0)	break;
				
				incurrent=incurrent*10+0;
				key_counter++;
				break;	
				
			case 11:				//11从新设定
				incurrent=0;
				key_counter=0;
				break;			
					
			case 12:				//12为确定键,返回设定的电流值
				return incurrent;	
				break;	
			default:break;		
		}
		temp=incurrent;
		buff[3]=temp/1000;temp=temp%1000;
		buff[2]=temp/100;temp=temp%100;
		buff[1]=temp/10;temp=temp%10;
		buff[0]=temp;
		ZLG7290_SendBuf(buff,8);
		Delay(100);	
	}
	return setcurrent;
}

void set_duty()
{
	PWMMR6= duty;	
	PWMLER=0x41;
}
uint16 floatabs(fp32 data)
{
  if(data<0)
     data = -data;
  return data;
}

//PID控制算法
void PID(uint32 adc)
{   
    int16 addcurrent; //电流增量
    int16 duty_temp;
    fp32 ukp,uki,ukd;//比例、积分、微分输出分量
    duty_temp = (int16)duty;
    e[0] = (int16)setcurrent - (int16)adc;
    if( floatabs (e[0]) < 5)
      addcurrent = 0;
    else
      { 
        ukp = kp * (e[0] - e[1]);
        uki = kp * ki * e[0];
        ukd = kp * kd * (e[0] - 2 * e[1] + e[2]);
       
        addcurrent = ukp + uki + ukd; 
      }
    duty_temp = duty_temp + addcurrent;
    duty = (uint16)duty_temp;
    if(duty >900)
      duty = 900;
    if(duty <100)
      duty = 100;
	set_duty();
	e[2] = e[1];
	e[1] = e[0];
	
}

int main (void)
{
	uint8 key;
	uint16 incurrent,temp;
	uint32 adc;
	Init_all();	
	Delay(100);
	
	temp=setcurrent;
	temp=((temp*(3.3/1024))/20)*1000;
	buff[3]=temp/1000;temp=temp%1000;
	buff[2]=temp/100;temp=temp%100;
	buff[1]=temp/10;temp=temp%10;
	buff[0]=temp;
	
	ZLG7290_SendBuf(buff,8);
	while(1)
	{
		adc=ADC_relust();
		
		PID(adc);
		temp=adc;
		temp=((temp*(3.3/1024))/20)*1000;
		buff[7]=temp/1000;temp=temp%1000;
		buff[6]=temp/100;temp=temp%100;
		buff[5]=temp/10;temp=temp%10;
		buff[4]=temp;
		ZLG7290_SendBuf(buff,8);
		if(key_flag==1)
		{
			key_flag=0;
			key=ZLG7290_GetKey();
			if(key==11)		//11键为设定建
			{
				incurrent=Input_Current();
				setcurrent=(incurrent*20)*(1024/3.3)/1000;
				//duty=setcurrent;
				//set_duty();
			}
			
		}
		Delay(2);
	}
    return 0;
}

⌨️ 快捷键说明

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