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

📄 main.c

📁 这是一个控制发电机的直流励磁程序
💻 C
字号:
#include "DSP28_Device.h"


#define write_RAM 		GpioDataRegs.GPFDAT.bit.GPIOF13 = 0	
#define read_RAM 		GpioDataRegs.GPFDAT.bit.GPIOF13 = 1

#define power_on 		GpioDataRegs.GPBDAT.bit.GPIOB0 = 0 	 //主回路上电控制
#define resistance_off 	GpioDataRegs.GPFDAT.bit.GPIOF9 = 0   //电阻切换控制


#define	start_flag			* (unsigned int *) 0x002000	//运行标志
#define	voltage_key			* (unsigned int *) 0x002001	//键盘设定的电压给定值
#define	voltage_secect		* (unsigned int *) 0x002002	//电压给定方式选择
#define	voltage_enactment	* (unsigned int *) 0x002003	//当前电压给定值
#define	voltage_real		* (unsigned int *) 0x002004	//输出电压的实际值


unsigned int  power_on_time = 0;			//控制主回路上电时间
unsigned int  resistance_off_time = 0;		//控制切换电阻时间
unsigned int  AD_times = 0;					//控制AD转换的频率
unsigned int  voltage_enactment_value = 0;	//电压给定值
unsigned int  voltage_value = 0;			//输出电压的实际值
unsigned int  CMPR_value = 0;				//由PID算法得出的比较寄存器的值
unsigned int  PID_flag = 0;					//PID计算标志
unsigned int  voltage_flag = 0;				//电压极性标志


float ADCINB0_value = 0;	//存放通道A0的AD转换值,模拟给定
float ADCINB4_value = 0;	//存放通道A1的AD转换值,测量电压

typedef struct PID 
{
	float SetPoint; 		// 设定目标Desired value
	
	float Proportion; 		// 比例常数Proportional Const
	float Integral; 		// 积分常数Integral Const
	float Derivative; 		// 微分常数Derivative Const
	
	float LastError; 		// Error[-1]
	float PrevError; 		// Error[-2]
	float SumError; 		// Sums of Errors	
} PID;


interrupt void Timer0(void);
interrupt void AD_convert(void);
void Data_exchange(void);
void Voltage_adjust(void);	
void Delay(unsigned int);
void PID_Init (PID *);
float PID_calculate(PID *, float);

void main(void)
{
	PID sPID;
	
 	InitSysCtrl();
 
 	//禁止和清除所有CPU中断
 	DINT;			
 	IER=0x0000;
 	IFR=0x0000;
 
 	
 	InitPieCtrl();		//初始化PIE控制寄存器
 	InitPieVectTable();	//初始化PIE中断向量表
 	InitGpio();			//初始化GPIO
 	InitXintf();		//初始化外部接口
 	InitSci();			//初始化串口	
 	InitEv();			//初始化事件管理器EVA
 	InitAdc();			//初始化AD转换器	
 	InitCpuTimers();	//初始化CPU定时器0
 	

 	//重新分配中断服务的中断向量,使T1UFINT、RXAINT、TINT0指向各自的服务程序
 	EALLOW;	
 	PieVectTable.TINT0   = &Timer0;
 	PieVectTable.ADCINT  = &AD_convert;
 	EDIS;
 
 	//使能PIE级定时器0的中断
	PieCtrl.PIEIER1.bit.INTx7 = 1;
 	PieCtrl.PIEIER1.bit.INTx6 = 1;		//允许AD转换中断
 	//使能CPU级INT1、INT2、INT9
 	IER=0x0103;
 	
 	EINT;   
 	ERTM;
		
	//启动定时器0,每0.02s中断一次
	ConfigCpuTimer(&CpuTimer0,150,20000);
	
	//初始化PID参数
	PID_Init (&sPID);	
	PID_flag = 0;
																								
	while(1)
	{
		KickDog();				//喂狗	
		Data_exchange();
		Voltage_adjust();
		if(PID_flag == 1)
		{
			PID_flag = 0;
			PID_calculate(&sPID,voltage_value);
		}	
  	}
}



/*********************************************************************************
**函数名称:Timer0
**功能描述:定时器0中断服务程序,0.02s中断一次
**输入参数:
**输出参数:
**全局变量:
**调用模块:
**说明:
**注意:
*********************************************************************************/
interrupt void Timer0(void)
{ 	
	AD_times++;
	power_on_time++;			
	resistance_off_time++;	
	
	if(power_on_time == 50)
	{
		power_on;
		power_on_time = 49;
	}	
	
	if(resistance_off_time == 75)
	{
		resistance_off;
		resistance_off_time = 74;
	}
	
	if(AD_times == 10)
	{
		PID_flag = 1;						//设置PID计算标志
		AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;		//软件触发,启动SEQ1
		AD_times = 0;
	}
			
  	PieCtrl.PIEACK.all |= PIEACK_GROUP1;	//写1清除中断响应标志位
}


/*********************************************************************************
**函数名称: Voltage_adjust()
**功能描述: 根据PID运算的结果,改变PWM输出的占空比,使输出电压跟随给定值
**输入参数:
**输出参数:
**全局变量:
**调用模块:
**说明:
**注意:
*********************************************************************************/
void Voltage_adjust(void)
{
	/*先判断有没有启动,没有的话封死IR2110的输出脉冲,然后退出*/
	unsigned int temp;			
	//设置数据方向从双口RAM到DSP2812
	read_RAM;				
	Delay(100);	
	//判断是否停止,如果没有直接退出	
	temp = start_flag & 0x00ff;
	if(temp != 0x0055)
	{	
		GpioDataRegs.GPADAT.bit.GPIOA4 = 1;	//封死IR2110的输出脉冲
		EvaRegs.ACTR.all = 0x0fff;			//将PWM脉冲强制拉高
		voltage_flag = 0;
		return;
	}
	
	//已经启动,使能IR2110的输出脉冲
	GpioDataRegs.GPADAT.bit.GPIOA4 = 0;
		
	EvaRegs.ACTR.all = 0x0999;
		
	//加正压
//	if((voltage_value < voltage_enactment_value) && (voltage_flag != 1))

	if(voltage_flag != 1)
	{
		//设置EVA PWM3,PWM4外设功能 PWM1,PWM2 IO方式
		EALLOW;
		GpioMuxRegs.GPAMUX.all = 0x000c;	
		GpioMuxRegs.GPADIR.bit.GPIOA0 = 1;	//输出方式
		GpioMuxRegs.GPADIR.bit.GPIOA1 = 1;	//输出方式
		EDIS;
		GpioDataRegs.GPADAT.bit.GPIOA0 = 1;	
		GpioDataRegs.GPADAT.bit.GPIOA1 = 1;	
		Delay(200);
		GpioDataRegs.GPADAT.bit.GPIOA1 = 0;	
		voltage_flag = 1;
	}
/*
	//加负压	
	else if((voltage_value > voltage_enactment_value) && (voltage_flag != 2))
	{
  		//设置EVA PWM1,PWM2外设功能 PWM3,PWM4 IO方式
		EALLOW;
		GpioMuxRegs.GPAMUX.all = 0x0003;	
		GpioMuxRegs.GPADIR.bit.GPIOA2 = 1;	//输出方式
		GpioMuxRegs.GPADIR.bit.GPIOA3 = 1;	//输出方式
		EDIS;
		GpioDataRegs.GPADAT.bit.GPIOA2 = 1;
		GpioDataRegs.GPADAT.bit.GPIOA3 = 1;
		Delay(200);
		GpioDataRegs.GPADAT.bit.GPIOA2 = 0;	
		voltage_flag = 2;
	}
*/	
	//读入按键给定的电压值
	temp = voltage_key & 0x00ff;
	
	//计算偏差	
	CMPR_value = ( temp / 100.0 ) * 7500;
	
  	//根据PID输出结果置比较器的值
  	EvaRegs.CMPR1 = CMPR_value;
 	EvaRegs.CMPR2 = CMPR_value;
}


/*********************************************************************************
**函数名称:Delay(unsigned int n)
**功能描述:延迟子程序
**输入参数:n,控制延迟时间参数
**输出参数:
**全局变量:
**调用模块:
**说明:
**注意:
*********************************************************************************/
void Delay(unsigned int n)
{ 
	unsigned int m=n;
	for(;m>0;m--);
}

	
/*********************************************************************************
**函数名称:Data_exchange()
**功能描述:DSP2812与AT89S52通过双口RAM交换数据
**输入参数:
**输出参数:
**全局变量:
**调用模块:
**说明:	系统只有在停止的情况下,才能改变电压给定方式
**注意:
*********************************************************************************/
void Data_exchange(void)
{
	unsigned int temp;

	//设置数据方向从双口RAM到DSP2812
	read_RAM;				
	Delay(100);
	
	//选择电压给定方式
	temp = voltage_secect & 0x00ff;	
	if(temp == 1)
	{
		voltage_enactment_value = ( ADCINB4_value / 2.5 ) * 100;
		if(voltage_enactment_value > 100)voltage_enactment_value = 100;
	}
	else voltage_enactment_value = voltage_key & 0x00ff;
		
	//设置数据方向从DSP2812到双口RAM
	write_RAM;				
	Delay(100);
	
	voltage_enactment = voltage_enactment_value;
	voltage_real = voltage_value;	
}


void PID_Init (PID *pp)
{	
	pp->SetPoint = 0; 		// 设定目标Desired value
	
	pp->Proportion = 0; 	// 比例常数Proportional Const
	pp->Integral = 0; 		// 积分常数Integral Const
	pp->Derivative = 0; 	// 微分常数Derivative Const
	
	pp->LastError = 0; 		// Error[-1]
	pp->PrevError = 0; 		// Error[-2]
	pp->SumError = 0; 		// Sums of Errors
}



float PID_calculate( PID *pp, float NextPoint )
{
	float dError,Error;
	pp->SetPoint = voltage_enactment_value; 	// 设定目标Desired value
	Error = pp->SetPoint - NextPoint; 			// 偏差
	pp->SumError += Error; 						// 积分
	dError = pp->LastError - pp->PrevError; 	// 当前微分
	pp->PrevError = pp->LastError;
	pp->LastError = Error;
	return (pp->Proportion * Error + pp->Integral * pp->SumError + pp->Derivative * dError );
}



interrupt void AD_convert(void)
{

	ADCINB0_value=( (float)AdcRegs.RESULT2 ) * 3.0 / 65520.0;
	ADCINB4_value=( (float)AdcRegs.RESULT3 ) * 3.0 / 65520.0;
	
	voltage_value = ( ADCINB0_value / 1.07 ) * 100;
		
	AdcRegs.ADC_ST_FLAG.bit.INT_SEQ1_CLR = 1;	//清除SEQ1的中断标志INT_SEQ1
	AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;			//排序器1复位
	
	PieCtrl.PIEACK.all |= PIEACK_GROUP1;
}






⌨️ 快捷键说明

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