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

📄 isrs.c

📁 用C语言写的用于微新公司数字信号控制器30F6014的
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********************************************************************
 *	程序说明
 *  
 *  该文件包含所有的中断服务程序(ISRs)
 **********************************************************************/

#include "general.h"
#include "hardware.h"
#include "defs.h"
#include "extern_globals.h"

void check_zero_crossing(void);
static void current_control(void);
static void acquire_position(void);

void __attribute__((__interrupt__)) _DefaultInterrupt(void)
{
// 该中断为缺省中断,如果中断向量没有定义,则程序跳转到这里执行
	DISABLE_FIRING;
	while(1);	
}

void __attribute__((__interrupt__)) _AddressError(void)
{
	DISABLE_FIRING;
	
	//清看门狗WDT
	while(1)
	{
		ClrWdt();
	}
	return;
}

void __attribute__((__interrupt__)) _StackError(void)
{
	unsigned char i;

	DISABLE_FIRING;
	
	//清看门狗WDT
	while(1)
	{
		ClrWdt();
	}
	return;
}

void __attribute__((__interrupt__)) _MathError(void)
{
	unsigned char i;

	DISABLE_FIRING;

	//清看门狗WDT
	while(1)
	{
		ClrWdt();

	}
	return;
}

//PWM中断服务程序
void __attribute__((__interrupt__)) _PWMInterrupt(void)
{
	slow_event_count++;
	medium_speed_event_count++;
	IFS2bits.PWMIF = 0;
	return;
}

//故障A中断服务程序
void __attribute__((__interrupt__)) _FLTAInterrupt (void)
{
	if (run_state == STARTING)
		{IFS2bits.FLTAIF = 0; return;}
	if (fault_count++ < MAXFAULT)
		{IFS2bits.FLTAIF = 0; return;}
	DISABLE_FIRING;
	run_state=FAULT;
	if (!trip_state)	trip_state=HARDWARE_TRIP;
	IFS2bits.FLTAIF = 0;
	return;
}

//ADC中断服务程序
void __attribute__((__interrupt__)) _ADCInterrupt (void)
{
	//清中断标志
	IFS0bits.ADIF = 0;
	
	// 从ADC缓冲取得结果,并把它们付给相应的变量;
	// 可以得到测量值为单相电压,DC总线电压,DC总线电流和VR2的值;	
	if (control_flags.ACQUIRE2==TRUE)
	{
		switch (ADCHS)
		{
			case VPH_RED :		vph_red=ADCBUF0;
									ADCHS=VPH_YELLOW;
									break;

			case VPH_YELLOW : vph_yellow=ADCBUF0;
									ADCHS=VPH_BLUE;
									break;

			case VPH_BLUE	 : vph_blue=ADCBUF0;
									ADCHS=VPH_RED;
									break;

			default :			ADCHS=VPH_RED;
									break;
		}
	}
	else
	{
		vph=ADCBUF0;
	}
	vdc=ADCBUF1;  
	ibus=ADCBUF2;
	pot=ADCBUF3;
	
	// 如果存在故障,则设定run_state为FAULT,并返回。
	if (trip_state)	
	{
		run_state=FAULT;
		return;
	}

	//如果有故障,检查是否是过压和过流
	if ((ibus>current_trip) && (run_state != INITIALIZING))
	{
		DISABLE_FIRING;
		run_state=FAULT;
		trip_state=OVER_CURRENT;
		return;
	}

	if ((vdc>voltage_trip) && (run_state != INITIALIZING))
	{
		DISABLE_FIRING;
		run_state=FAULT;
		trip_state=OVER_VOLTAGE;
		return;
	}
	
	//根据最新的采样值作电流控制
	current_control();
	
	//若须采样不同相的电压,要重新配置ADC
	if (control_flags.ADCCONFIG==TRUE)
	{
		ADCHS = adc_channel_config;
	}

	if ((control_flags.ACQUIRE2==TRUE) && (run_state!=INITIALIZING))
	{
		acquire_position();
	}

	if ((control_flags.SENSORLESS) || (control_flags.ACQUIRE1))
	{
		check_zero_crossing();
	}
	return;
}

#ifdef DEVELOPMODE
//UART 中断服务子程序
void __attribute__((__interrupt__)) _U1TXInterrupt(void)
{
	IFS0bits.U1TXIF = 0;	//清中断标志
}

void __attribute__((__interrupt__)) _U1RXInterrupt(void)
{
	IFS0bits.U1RXIF = 0;	//清中断标志
	*RXPtr = U1RXREG;     //取值
	if (*RXPtr == CR)
		{control_flags2.CheckRX = 1;RXPtr = &InData[0];}
	else *RXPtr++;
}

#endif
  
// Timer 1中断服务程序,用于检测过零事件
void __attribute__((__interrupt__)) _T1Interrupt(void)
{
	DISABLE_FIRING;
	run_state=FAULT;
	if (!trip_state)	trip_state=LOST;
	IEC0bits.T1IE = 0;	// Disable interrupt so don't get
								// unnecessary calls
	IFS0bits.T1IF = 0;	// Clear off interrupt flag
	return;
}

//Timer 2中断服务程序,用于作输出比较,配置电压测量和过零
void __attribute__((__interrupt__)) _T2Interrupt(void)
{

	// 采用方法1获得	
	if (control_flags.ACQUIRE1)
	{
		
		//设定ADCCONFIG标志位,以便过零程序初始化
		control_flags.ADCCONFIG=TRUE;
		
		//如果在上一次sector没有侦测到合法得过零点,重新初始化acquire和check
		if (control_flags.ZERO_CROSS==FALSE)
		{
			acquire_counter=0;
			check_counter=8;
			if (control_flags.DIR==FORWARDS)
			{
				if (sector==5) sector=0;
				else 				sector++;
			}
			else
			{
				if (sector==0) sector=5;
				else 				sector--;
			}
		}
	}

	//ACQUIRE1模式使用后得首次中断
	if (control_flags2.ACQUIRE1_REQUEST)
	{
		control_flags2.ACQUIRE1_REQUEST=FALSE;
		control_flags.ACQUIRE1=TRUE;
		//设定ADCCONFIG标志位,以便下一次过零程序初始化
		control_flags.ADCCONFIG=TRUE;
		check_counter=8;	
		acquire_counter=0;
		#ifdef DEBUG
			asm("bclr        LATD,#15");
			asm("bclr		  LATG,#3");
			asm("bclr		  LATG,#1");
			indx=0;
		#endif
	}

	//从获取模式2到无刷模式(sensorless),设定无刷标志并给check_counter赋值。
	if (control_flags.SWAP==TRUE)
	{
		control_flags.SENSORLESS=TRUE;
		control_flags.SWAP=FALSE;
		check_counter=6;
	}

	//如果check_counter大于0,check_counter减1
	if (check_counter)	check_counter--;

	//如果不是正常无刷状态运行,给PR2赋值。
	if (control_flags.SENSORLESS==FALSE)
	{
		//给PR2赋新值
		PR2=new_PR2;	
		//清TMR2,以保证在写PR2时不会忽略TMR2=PR2事件产生
		TMR2=0;
	}

	#ifdef DEBUG
		switch (sector)
		{
			case 0: 	asm(" bclr	LATD,#14");
						break;

			case 1: 	asm(" bset	LATD,#12");
						break;

			case 2: 	asm(" bclr	LATD,#6");
						break;

			case 3: 	asm(" bset	LATD,#14");
						break;

			case 4: 	asm(" bclr	LATD,#12");
						break;

			case 5: 	asm(" bset	LATD,#6");
						break;

			default : sector=0;
		}
	#endif
	
	//设定下一个vph通道并查看过零
	switch (sector)
	{
		case 0: 	OVDCON=SECTOR0_OVERRIDE;
					adc_channel_config=VPH_BLUE;
					break;

		case 1: 	OVDCON=SECTOR1_OVERRIDE;
					adc_channel_config=VPH_YELLOW;
					break;

		case 2: 	OVDCON=SECTOR2_OVERRIDE;
					adc_channel_config=VPH_RED;
					break;

		case 3: 	OVDCON=SECTOR3_OVERRIDE;
					adc_channel_config=VPH_BLUE;
					break;

		case 4: 	OVDCON=SECTOR4_OVERRIDE;
					adc_channel_config=VPH_YELLOW;
					break;

		case 5: 	OVDCON=SECTOR5_OVERRIDE;
					adc_channel_config=VPH_RED;
					break;
	}

	//确定sector值,以使系统能正确转向
	if (control_flags.SENSORLESS==FALSE)
	{
		if (control_flags.ACQUIRE1==FALSE)
		{
			if (control_flags.DIR==FORWARDS)
			{
				if (sector==5) sector=0;
				else 				sector++;
			}
			else
			{
				if (sector==0) sector=5;
				else 				sector--;
			}
		}
	}

  //设定ADCCONFIG标志位,以便配置ADC找到正确得vph通道,并初始化相应得变量;然后禁止T2中断
	else
	{
		control_flags.ADCCONFIG=TRUE;
		IEC0bits.T2IE = 0;
	}
	IFS0bits.T2IF = 0;
	return;
}

//Timer 3 中断服务程序,用作制动开关,中断产生时开关关闭
void __attribute__((__interrupt__)) _T3Interrupt(void)
{
	IFS0bits.T3IF = 0;
	IEC0bits.T3IE = 0;
	return;
}

//过零检测子程序,用于检测相电压过零(当BEMF过vdc/2)
void check_zero_crossing(void)
{
	static unsigned int previous_sample;
	static unsigned char level_counter;
	static unsigned char blanking_counter;

	static unsigned int half_vdc=0;
	
	unsigned int new_timestamp;
	
  // 如果有换向发生,须清以前得采样(previous_sample)和幅值数(level_counter)
  // 同时清相应得标志位;放置新的blanking counter值,确定是否是上升(RISING)还是下降(FALLING)沿
	if (control_flags.ADCCONFIG==TRUE)
	{
		control_flags.ADCCONFIG=FALSE;
		previous_sample=0;
		level_counter=0;
		control_flags.LEVEL=FALSE;
		control_flags.ZERO_CROSS=FALSE;
		blanking_counter=(unsigned char)user_parameters[32];
		//是否是上升(RISING)还是下降(FALLING)沿
		if (control_flags.DIR==FORWARDS)
		{
			if ((sector % 2) == 0)	control_flags2.FALLING_EDGE=TRUE;
			else							control_flags2.FALLING_EDGE=FALSE;
		}
		else
		{
			if ((sector % 2) == 0)	control_flags2.FALLING_EDGE=FALSE;
			else							control_flags2.FALLING_EDGE=TRUE;
		}
		return;
	}
		
	if (blanking_counter > 0)
	{
		blanking_counter--;
		return;
	}

  // 防止产生第二次过零
	if (control_flags.ZERO_CROSS==TRUE)
		return;

	half_vdc = ((half_vdc + (vdc>>1)) >> 1);

  // 用level_counter变量及标志位保证过零侦测准确,
  // 在实际的过零检测之前,vph必须是在上面(下降沿)或下面(上升沿)
	if (level_counter==(unsigned char)user_parameters[33])
	{
		control_flags.LEVEL=TRUE;
	}

	if (control_flags2.FALLING_EDGE)
	{ 
		if ((level_counter < (unsigned char)user_parameters[33]) && (vph > half_vdc))
		{
			level_counter++;
		}
		if ((level_counter > 0) && (vph <= half_vdc))
		{
			level_counter--;
		}
	}
	else
	{
		if ((level_counter < (unsigned char)user_parameters[33]) && (vph < half_vdc))
		{
			level_counter++;
		}
		if ((level_counter > 0) && (vph >= half_vdc))
		{
			level_counter--;
		}
	}

	//三相定义如下:
	// Index 0 = 红
	// Index 1 = 黄
	// Index 2 = 蓝
	// Sector 0,3 = 蓝相过零
	// Sector 1,4 = 黄相过零
	// Sector 2,5 = 红相过零
	if (control_flags.LEVEL==TRUE) 
	{

		//合法得过零点
		if (((control_flags2.FALLING_EDGE) && (previous_sample <= half_vdc)\
				&& (vph <= half_vdc)) || \
			((control_flags2.FALLING_EDGE==FALSE) && (previous_sample >= half_vdc)\
				&& (vph >= half_vdc)))
		{
			//取得QEI的值
			new_timestamp=POSCNT;

			if (control_flags.DIR == FORWARDS)
			{
				switch (sector)
				{
					case 0:
					case 3:	latest_delta=new_timestamp-previous_timestamps[0];
								break;
					case 1:
					case 4:	latest_delta=new_timestamp-previous_timestamps[2];
								break;
					case 2:
					case 5:	latest_delta=new_timestamp-previous_timestamps[1];
								break;
				}
			}
			else 
			{
				switch (sector)
				{
					case 0:
					case 3:	latest_delta=new_timestamp-previous_timestamps[1];
								break;
					case 1:
					case 4:	latest_delta=new_timestamp-previous_timestamps[0];
								break;
					case 2:
					case 5:	latest_delta=new_timestamp-previous_timestamps[2];
								break;
				}
			}

			//计算测量周期,用于速度反馈。
			if (sector==0)
			{
				period_measurement=new_timestamp-previous_timestamps[2];
				stall_counter=0;
			}
	
			commutation_time=((latest_delta)/2) - phase_advance;
			if (commutation_time < 1) commutation_time=1;
			check_value=(latest_delta*100)/previous_delta;
			
			if (((check_value > upper_tol) \
				|| (check_value < lower_tol))	\
				&& (check_counter==0))
			{
				//如果无刷模式失败,进入获取模式2
				DISABLE_FIRING;
				IEC0bits.T2IE=FALSE;
				control_flags.SENSORLESS=FALSE;
				if (user_parameters[31])
				{
					control_flags.ACQUIRE2=TRUE;
					control_flags.ADCCONFIG=TRUE;
					control_flags2.RETRY_FLAG=FALSE;
				}
				else
				{
					run_state=FAULT;
					trip_state=LOST;
				}
				return;
			}
			else//合法过零检测
			{
				//更新sector
				if (control_flags.DIR==FORWARDS)
				{
					if (sector==5) sector=0;
					else 				sector++;
				}
				else
				{
					if (sector==0) sector=5;
					else 				sector--;
				}
				
				if (control_flags.ACQUIRE1==FALSE)
				{
					PR2 = (unsigned int) commutation_time;
					TMR2=0;
					IFS0bits.T2IF = 0;
					IEC0bits.T2IE = 1;
					PR1=latest_delta<<1;
					TMR1=0;
					IFS0bits.T1IF = 0;
					IEC0bits.T1IE = 1;
				}
				else
				{
					// acquire counter加1表示合法得零点产生
					acquire_counter++;
					#ifdef DEBUG
						asm("btg        LATD,#15");
					#endif
					if (acquire_counter > 1) 
					{	
						IEC0bits.T2IE = 0;

						//设置标志位表明运行于无刷状态
						control_flags.ACQUIRE1=FALSE;
						control_flags.SENSORLESS=TRUE;
						run_state=RUNNING;

						check_counter=6;
						//设置T2使中断在合适得时候产生
						PR2 = (unsigned int) commutation_time;
						TMR2=0;
						//清中断标志并使能中断
						IFS0bits.T2IF = 0;
						IEC0bits.T2IE = 1;
						#ifdef DEBUG
							asm("btg        LATG,#1");
						#endif
					}
				}
			}
			if (control_flags.DIR==FORWARDS)
			{
				switch (sector)
				{
					case 0:	
					case 3:	previous_timestamps[0] = new_timestamp;
								break;
					case 1:	
					case 4:	previous_timestamps[2] = new_timestamp;
								break;
					case 2:	
					case 5:	previous_timestamps[1] = new_timestamp;
								break;
				}
			}
			else
			{
				switch (sector)
				{
					case 0:	
					case 3:	previous_timestamps[1] = new_timestamp;
								break;
					case 1:	
					case 4:	previous_timestamps[0] = new_timestamp;
								break;
					case 2:	
					case 5:	previous_timestamps[2] = new_timestamp;
								break;
				}	
			}
			previous_delta=latest_delta;	
			control_flags.ZERO_CROSS=TRUE;
			level_counter=0;
			control_flags.LEVEL=FALSE;

⌨️ 快捷键说明

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