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

📄 isrs.c.bak

📁 关于无传感器BLDC使用DSPIC现实的源码
💻 BAK
📖 第 1 页 / 共 4 页
字号:
/**********************************************************************
 *                                                                     *
 *                        Software License Agreement                   *
 *                                                                     *
 *    The software supplied herewith by Microchip Technology           *
 *    Incorporated (the "Company") for its dsPIC controller            *
 *    is intended and supplied to you, the Company's customer,         *
 *    for use solely and exclusively on Microchip dsPIC                *
 *    products. The software is owned by the Company and/or its        *
 *    supplier, and is protected under applicable copyright laws. All  *
 *    rights are reserved. Any use in violation of the foregoing       *
 *    restrictions may subject the user to criminal sanctions under    *
 *    applicable laws, as well as to civil liability for the breach of *
 *    the terms and conditions of this license.                        *
 *                                                                     *
 *    THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION.  NO           *
 *    WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING,    *
 *    BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND    *
 *    FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE     *
 *    COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL,  *
 *    INCIDENTAL OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.  *
 *                                                                     *
  **********************************************************************/

 /**********************************************************************
 *                                                                     * 
 *    Author: Smart Power Soutions, LLP                                * 
 *                                                                     *
 *    Filename:       ISRs.c          	                                *
 *    Date:           4/21/04                                         *
 *    File Version:   4.00                                             *
 *    Project:        53                                               *
 *    Drawing:        2                                                *
 *                                                                     *
 *    Tools used:    MPLAB C30 Compiler v 1.20.01                      *
 *                                                                     *
 *    Linker File:    p30f4012.gld                                   *
 *                                                                     *
 *                                                                     *
 ***********************************************************************
 *	Code Description
 *  
 *  This file contains all the interrupt service routines (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)
{
// This is the default interrupt handler.  If an interrupt
// vector is not defined, then we will go here and wait
// in an infinite loop!
DISABLE_FIRING;
while(1);	
}

void __attribute__((__interrupt__)) _AddressError(void)
{
	DISABLE_FIRING;
	
	// Clear WDT and drive LED4 at 100% Duty
	while(1)
	{
		ClrWdt();
	}
	return;
}

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

	DISABLE_FIRING;
	
	// Clear WDT and drive LED4 at 50% Duty
	while(1)
	{
		ClrWdt();
	}
	return;
}

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

	DISABLE_FIRING;

	// Clear WDT and drive LED4 at 33% Duty
	while(1)
	{
		ClrWdt();

	}
	return;
}

void __attribute__((__interrupt__)) _PWMInterrupt(void)
{
	slow_event_count++;
	medium_speed_event_count++;
	IFS2bits.PWMIF = 0;
	return;
}

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;
}

void __attribute__((__interrupt__)) _ADCInterrupt (void)
{
	// Clear off interrupt flag
	IFS0bits.ADIF = 0;

	
	// Get Results from ADC Buffer and put them into relevant variables
	// When in normal running we get one phase voltage, dc bus voltage
	// dc bus current and VR2 as simultaneous samples every pwm
	// When acquiring we need to see all three phase voltages so 
	// we continuously cycle ADC CH0 between the three phase voltages
	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;
	
	// If a fault condition exists ensure run_state is set to FAULT
	// and return at this point.
	if (trip_state)	
	{
		run_state=FAULT;
		return;
	}


	// Do over voltage and over current trip checks if not already in fault
	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;
	}
	
	// Now do current control with most up to date current sample
	// If current control is not active routine initialises some
	// variables and returns
	current_control();
	
	// Now reconfigure adc if required to sample different 
	// phase voltage feedback channel

	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 interrupts
//---------------------------------------------------------------------

void __attribute__((__interrupt__)) _U1TXInterrupt(void)
{
	IFS0bits.U1TXIF = 0;	// clear interrupt flag
}

void __attribute__((__interrupt__)) _U1RXInterrupt(void)
{
	IFS0bits.U1RXIF = 0;	// clear interrupt flag
	*RXPtr = U1RXREG;
	if (*RXPtr == CR)
		{control_flags2.CheckRX = 1;RXPtr = &InData[0];}
	else *RXPtr++;
}

#endif
  
// Timer 1 is used as a guard timer to catch missed zero
// crossing events due to excessive demag time/insufficient
// phase advance for instance. Every zero crossing detected,
// PR1 is written with double the latest time delta between
// zero crossings and TIMER1 is reset to zero. If the timer
// ever reaches PR1 causing an interrupt, then the system is
// assumed to have missed a zero crossing and enters the LOST
// trip state.

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 used as an output compare but not associated with
// an I/O line. It indicates time for a commutation.
// The ISR therefore actually does the commutation and also
// reconfigures voltage sensing channel and zero_crossing

void __attribute__((__interrupt__)) _T2Interrupt(void)
{

	// If we are acquiring using method1
	if (control_flags.ACQUIRE1)
	{
		// Set ADCCONFIG flag so that zero_crossing routine is correctly 
		// initialized next call.
		control_flags.ADCCONFIG=TRUE;
		// If we did not detect a valid zero crossing in the last
		// sector then need to initialize acquire and check counters
		// and also update the sector as this has not been done
		// by zero_crossing routine.
		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--;
			}
		}
	}

	// If this is first interrupt after ACQUIRE1 mode to be used
	if (control_flags2.ACQUIRE1_REQUEST)
	{
		control_flags2.ACQUIRE1_REQUEST=FALSE;
		control_flags.ACQUIRE1=TRUE;
		// Set ADCCONFIG flag so that zero_crossing routine is correctly 
		// initialized next call.
		control_flags.ADCCONFIG=TRUE;
		check_counter=8;	//This is 8 so that 1 elec cycle (6)
								//of tolerance checks after transition
								//to sensorless operation are ignored.
		acquire_counter=0;
		#ifdef DEBUG
			asm("bclr        LATD,#15");
			asm("bclr		  LATG,#3");
			asm("bclr		  LATG,#1");
			indx=0;
		#endif
	}
	// If swapping from acqisision mode 2 to sensorless
	// set sensorless flag and load check_counter
	// so that sensorless tolerance checks are disabled
	// for first electrical cycle as first few zero crossings
	// may violate tolerance checks due to change over transient
	if (control_flags.SWAP==TRUE)
	{
		control_flags.SENSORLESS=TRUE;
		control_flags.SWAP=FALSE;
		check_counter=6;
	}

	// Decrement the check_counter if > 0
	if (check_counter)	check_counter--;

	// If not in normal running then need to reload PR2 with
	// a new value calculated elsewhere.
	// When running sensorless the detection of a zero crossing
	// reloads PR2 and enables interrupt
	if (control_flags.SENSORLESS==FALSE)
	{
		// Load New Value Into PR2
		PR2=new_PR2;
		// Clear off TMR2 to ensure don't have issue with occasional
		// miss of TMR2=PR2 event when PR2 is written to.
		TMR2=0;
	}

	#ifdef DEBUG
	// These diagnostic signals re-create the Halls
		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
	
	// This is the main switch statement that actually
	// does the commutation. It also sets up which is the
	// next vph channel to look at for zero crossing. This
	// is used to configure CH0 S+H input channel.
	switch (sector)
	{
		case 0: 	OVDCON=SECTOR0_OVERRIDE;
					adc_channel_config=VPH_BLUE;

⌨️ 快捷键说明

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