www.pudn.com > dsPIC_Advprog_Answer.rar > ex6.c, change:2011-05-11,size:10150b


// *********************************************************************** 
// File : dsPIC30F6010B.C 
// Purpose : 使用 Motor Control PWM 送出 60 Hz 的  sin wave  於 PWM1L/H 
// *********************************************************************** 
 
#define __dsPIC30F4011__ 
 
#include 	<timer.h> 
#include 	<math.h> 
#include 	<p30F4011.h> 
#include	"APP009V2_LCD.h" 
 
#define	pi	3.1415926  
#define	FCY	7372800 * 2		// XT-PLL*8  
 
#define	MAX_DUTY	230		// Max Duty is 360 
 
 
//--------------------------------------------------------------------------- 
// Configuration bits 
 
//   _FOSC(CSW_FSCM_OFF & EC_PLL4);   //XT with 4xPLL oscillator, Failsafe clock off 
//   _FWDT(WDT_OFF);                  //Watchdog timer disabled 
//   _FBORPOR(PBOR_OFF & MCLR_EN);    //Brown-out reset disabled, MCLR reset enabled 
//   _FGS(CODE_PROT_OFF);             //Code protect disabled 
 
#define	LED13		LATDbits.LATD0 
#define	LED14		LATDbits.LATD1 
#define	LED15		LATFbits.LATF0  
#define	LED16		LATFbits.LATF1  
 
#define	DIR_LED13	TRISDbits.TRISD0 
#define	DIR_LED14	TRISDbits.TRISD1 
#define	DIR_LED15	TRISFbits.TRISF0 
#define	DIR_LED16	TRISFbits.TRISF1 
 
#define	AD_S1		0x2B4 
#define	AD_S2		0x259 
#define	AD_S3		0x1FB 
#define	AD_S4		0x13B 
#define	ADC_MAX		0x3FF 
 
 
void	Initial_Timer1( void ) ; 
void 	DelayNmSec(unsigned int ) ; 
void 	InitADC10(void); 
void 	CN5to7_Initial(void) ; 
void	MotPWM_Initial(void) ; 
void	S1_Process(void) ; 
void	S2_Process(void) ; 
void	S3_Process(void) ; 
void	S4_Process(void) ; 
 
unsigned int	ValuePDC ; 
int				T1IF_Flag ; 
int				T1IF_Counter ; 
int				HALL_Position; 
int				S1_Counter ; 
int				S2_Counter ; 
int				S3_Counter ; 
int				S4_Counter ; 
int				NoS_Counter ; 
int				ADC_Value ; 
int				SpeedCommand ; 
int				PreSpeedCommand ; 
int				TargetDuty ; 
 
union 
	{ 
		unsigned int	Value ; 
 
		struct 
			{ 
				unsigned MotorRun ; 
				unsigned KeyPressed: 1 ; 
				unsigned AccFlag: 1 ; 
				unsigned DeAccFlag: 1 ; 
				unsigned WaitStopFlag: 1 ; 
			};	 
	}Flags ; 
 
// 
// Driver Table for Hi Switching Clockwise Direction 
// 
unsigned int 	SW_HiTable[] = {	0x0000, 0x2001, 0x0204, 0x2004, 
									0x0810, 0x0801, 0x0210, 0x0000 }; 
 
 
void __attribute__((__interrupt__)) _T1Interrupt(void) 
{ 
 
	T1IF_Counter += 1 ; 
 
	if (T1IF_Counter > 600) 
		{ 
			T1IF_Counter = 0 ; 
			T1IF_Flag = 1 ; 
 
			if ( Flags.MotorRun ) 
			{ 
				if ( Flags.WaitStopFlag ) 
				{ 
 
				 			ValuePDC -= 3 ; 
 
							if ( ValuePDC < 5 )	 
							{ 
								ValuePDC = TargetDuty ; 
								setcurLCD(0,1) ; 
								putrsLCD("MOTOR STOP      ") ;	 
 
									Flags.MotorRun = 0 ; 
									OVDCON = 0x00 ; 				// Turn OFF PWM  !!	 
									Flags.WaitStopFlag = 0 ; 
 
								setcurLCD(13,0) ; 
								puthexLCD(0) ; 
 
								LED13 = 0 ; 
								LED14 = 0 ; 
							} 
							else 
							{ 
								PDC1 = ValuePDC ; 
								PDC2 = ValuePDC ; 
								PDC3 = ValuePDC ; 
							} 
 
				} 
 
				if ( Flags.AccFlag ) 
				{ 
					if ( ValuePDC <= TargetDuty ) 
					{ 
				 		ValuePDC += 2 ; 
 
						if ( ValuePDC > TargetDuty )	ValuePDC = TargetDuty ; 
 
						PDC1 = ValuePDC ; 
						PDC2 = ValuePDC ; 
						PDC3 = ValuePDC ; 
					} 
					else	Flags.AccFlag = 0 ; 
				} 
 
				else if ( Flags.DeAccFlag ) 
					{ 
						if ( ValuePDC > TargetDuty ) 
						{ 
				 			ValuePDC -= 1 ; 
 
							if ( ValuePDC < TargetDuty )	ValuePDC = TargetDuty ; 
 
							PDC1 = ValuePDC ; 
							PDC2 = ValuePDC ; 
							PDC3 = ValuePDC ; 
						} 
							else	Flags.DeAccFlag = 0 ; 
				} 
				  
			} 
		}  
 
	IFS0bits.T1IF = 0 ; 
 
} 
 
void __attribute__((__interrupt__)) _PWMInterrupt(void) 
{ 
 
		IFS2bits.PWMIF = 0 ; 
} 
 
void __attribute__((__interrupt__)) _CNInterrupt(void) 
{ 
 
		IFS0bits.CNIF = 0 ; 
		HALL_Position = ( (PORTB & 0x0038) >> 3 ); 
 
		if ( Flags.MotorRun ) 
			OVDCON = SW_HiTable[HALL_Position] ; 
} 
 
int	main( void ) 
 
{ 
 
	OpenLCD( ) ; 
	Initial_Timer1( ) ; 
	InitADC10( ) ; 
 
		CN5to7_Initial( ) ; 
		MotPWM_Initial( ) ; 
		Ports_Initial( ) ; 
		Vars_Initial( ) ; 
 
		//	OVDCON = SW_HiTable[HALL_Position] ; Turn PWM until Run Pressed !! 
 
		putrsLCD("TGT:     OUT:   ") ; 
		setcurLCD(0,1) ; 
		putrsLCD("MOTOR STOP      ") ; 
 
 while (1)  
	{ 
		while ( T1IF_Flag == 0 ) ; 
 
			T1IF_Flag = 0 ; 
 
			IFS0bits.T1IF = 0 ; 
 
				ADCHS = 0x0008 ; 
 				IFS0bits.ADIF = 0 ; 
 				ADCON1bits.SAMP = 0;			//	start Converting 
				while (!IFS0bits.ADIF); 		// conversion done? 
 				ADC_Value = ADCBUF0;			// yes then get ADC value 
		 
		if ( Flags.KeyPressed ) 
				{ 
					if ( ADC_Value > ADC_MAX-20) 
						{ 
							NoS_Counter+= 1 ; 
							if ( NoS_Counter >= 3 ) 
							{ 
								Flags.KeyPressed = 0 ; 
								NoS_Counter = 0 ; 
							} 
						} 
				} 
		else 
		{	 
			if ( ( ADC_Value < AD_S1+10 ) && ( ADC_Value > AD_S1-10) ) 
					 
					S1_Process( ) ; 
					 
			else if ( ( ADC_Value < AD_S2+10 ) && ( ADC_Value > AD_S2-10) ) 
 
					S2_Process( ) ; 
 
			else if ( ( ADC_Value < AD_S3+10 ) && ( ADC_Value > AD_S3-10) ) 
 
					S3_Process( ) ; 
 
			else if ( ( ADC_Value < AD_S4+10 ) && ( ADC_Value > AD_S4-10) ) 
					 
					S4_Process( ) ;		 
		}	 
 
				ADCHS = 0x0007 ; 
 				IFS0bits.ADIF = 0 ; 
 				ADCON1bits.SAMP = 0;			//	start Converting 
				while (!IFS0bits.ADIF); 		// conversion done? 
 				SpeedCommand = ADCBUF0 >> 2;	// yes then get ADC value 
 
				if ( SpeedCommand != PreSpeedCommand ) 
					{ 
						setcurLCD(4,0) ; 
						puthexLCD((unsigned char) SpeedCommand ) ; 
						PreSpeedCommand = SpeedCommand ; 
					} 
 
					if ( Flags.MotorRun ) 
						{ 
						  if ( TargetDuty != SpeedCommand ) 
						  	{ 
								if (    TargetDuty > SpeedCommand ) 
 
								 	Flags.DeAccFlag = 1 ; 
								else  
									Flags.AccFlag = 1 ; 
 
								TargetDuty = SpeedCommand ; 
						   	} 
 
							if ( Flags.DeAccFlag || Flags.AccFlag ) 
								{	 
									setcurLCD(13,0) ; 
									puthexLCD((unsigned char) ValuePDC ) ; 
								}	 
 
							LED13 = ! LED13 ; 
							LED14 = ! LED14 ;		 
						}		 
	} 
} 
 
void	S1_Process(void) 
{ 
		S1_Counter += 1 ; 
		S2_Counter = 0 ; 
		S3_Counter = 0 ; 
		S4_Counter = 0 ; 
		NoS_Counter = 0 ; 
 
			if ( S1_Counter >= 3 ) 
				{ 
					S1_Counter = 0 ; 
					Flags.KeyPressed = 1 ; 
 
					setcurLCD(0,1) ; 
					putrsLCD("MOTOR RUN       ") ; 
 
					Flags.MotorRun = 1 ; 
					TargetDuty = PreSpeedCommand ; 
 
					if ( TargetDuty < 30 ) 
						{ 
						  	ValuePDC = TargetDuty ; 
							Flags.AccFlag = 0 ; 
						} 
					else 
						{ 
							ValuePDC = 30 ; 
							Flags.AccFlag = 1 ; 
						} 
 
						PDC1 = ValuePDC ; 
						PDC2 = ValuePDC ; 
						PDC3 = ValuePDC ; 
						LED13 = 1 ; 
						LED14 = 0 ; 
	 
						OVDCON = SW_HiTable[HALL_Position] ; // Turn ON PWM  !!	 
				 
				}	 
} 
 
void	S2_Process(void) 
{ 
		S2_Counter += 1 ; 
		S1_Counter = 0 ; 
		S3_Counter = 0 ; 
		S4_Counter = 0 ; 
		NoS_Counter = 0 ; 
 
			if ( S2_Counter >= 3 ) 
				{ 
					S2_Counter = 0 ; 
					Flags.KeyPressed = 1 ; 
 
					Flags.WaitStopFlag = 1 ; 
					TargetDuty = 0 ; 
					 
				}	 
} 
 
void	S3_Process(void) 
{ 
		S3_Counter += 1 ; 
		S1_Counter = 0 ; 
		S2_Counter = 0 ; 
		S4_Counter = 0 ; 
		NoS_Counter = 0 ; 
 
			if ( S3_Counter >= 3 ) 
				{ 
					S3_Counter = 0 ; 
					Flags.KeyPressed = 1 ;						 
				}	 
} 
 
void	S4_Process(void) 
{ 
		S4_Counter += 1 ; 
		S1_Counter = 0 ; 
		S2_Counter = 0 ; 
		S3_Counter = 0 ; 
		NoS_Counter = 0 ; 
 
			if ( S4_Counter >= 3 ) 
				{ 
					S4_Counter = 0 ; 
					Flags.KeyPressed = 1 ;						 
				}	 
} 
 
void Ports_Initial(void) 
{ 
 
		TRISD &= 0x00ff ; 
 
		DIR_LED13 = 0 ; 
		DIR_LED14 = 0 ; 
 
		DIR_LED15 = 0 ; 
		DIR_LED16 = 0 ; 
 
			LED13 = 1 ; 
			LED14 = 0 ; 
 
} 
 
void	Vars_Initial(void) 
{ 
		T1IF_Flag = 0 ; 
		T1IF_Counter = 0 ; 
		PreSpeedCommand = 0x00 ; 
		SpeedCommand = 0x00 ; 
		TargetDuty = 0 ; 
		Flags.Value = 0 ; 
} 
 
void MotPWM_Initial(void) 
{ 
		IEC2bits.PWMIE = 0 ; 
		IEC2bits.FLTAIE = 0 ; 
 
		OVDCON = 0x00 ;			// Inactive all PWM OUTPUT !! 
 
		TRISE = 0xffc0 ;		 
		PTCON = 0xa006 ;		// Configure as 0b1010000000000110  
								// PWM Time Base OFF , PWM Time Base OP in free running Mode  
		PWMCON1 = 0x0077 ;		// Configure as 0b0000000000010001 
								// PWM I/O in complementary Mode and only PWM1L/H as PWM output  
		PWMCON2 = 0x0000 ;		// Configure as 0b0000000000000000  
 
		DTCON1 = 0x0101 ;		// Configure as 0b0000001000000010 ; 
 
		FLTACON = 0x0000 ; 
 
		IPC9bits.PWMIP = 6 ; 
 
		// --------------------------------------------------------------------------------- 
		// The Switching Frequency !! 
		// 7372800 * 2 / 4( PWM prescale ) / 16K = 230  ... 230/2 = 115 ( Central Alignment ) 
		// --------------------------------------------------------------------------------- 
		PTPER = 115 ;			// PWM Time Base Period Register  
		ValuePDC = 200 ; 
 
			PDC1 = ValuePDC ; 
			PDC2 = ValuePDC ; 
			PDC3 = ValuePDC ;		 
} 
 
void CN5to7_Initial(void) 
{ 
	// initialize CN5 , CN6 , CN7 
 
	TRISBbits.TRISB3 = 1 ; 
	TRISBbits.TRISB4 = 1 ; 
	TRISBbits.TRISB5 = 1 ; 
	CNPU1 = 0X0038 ; 
	CNEN1bits.CN5IE = 1 ; 
	CNEN1bits.CN6IE = 1 ; 
	CNEN1bits.CN7IE = 1 ; 
	IEC0bits.CNIE = 1 ; 
	IPC3bits.CNIP = 7 ; 
	IFS0bits.CNIF = 0 ; 
	HALL_Position = ( (PORTB & 0x0038) >> 3 );			// Read PORTB back after Initial ..... 
} 
 
void DelayNmSec(unsigned int N) 
{ 
unsigned int j; 
while(N--) 
 	for(j=0;j < 1000;j++); 
} 
 
 
void	Initial_Timer1( void ) 
{ 
		ConfigIntTimer1( T1_INT_PRIOR_7 & T1_INT_ON ) ; 
		OpenTimer1( T1_ON & T1_IDLE_STOP & T1_GATE_OFF & T1_PS_1_1 & T1_SYNC_EXT_OFF & T1_SOURCE_INT , 
					683 ) ; 
} 
 
 
void InitADC10(void) 
{ 
 
 	ADPCFG = 0xFE7F;				// all PORTB = Digital; RB8 & RB7 = analog 
 	ADCON1 = 0x2006;				// 0b0010 0000 0000 0110 
									// SAMP bit = 0 ends sampling ..and starts converting 
 	ADCHS =  0x0008;				// Connect RB8/AN8 as CH0 input  .. 
									// in this example RB0/AN0 is the input 
 	ADCSSL = 0; 
 	ADCON3 = 0x040f;				// Manual Sample, Tad = internal 2 Tcy 
 	ADCON2 = 0x0000; 
 
	IFS0bits.ADIF = 0 ; 
	IEC0bits.ADIE = 0 ; 
	IPC2bits.ADIP = 0 ; 
  
 	ADCON1bits.ADON = 1;			// turn ADC ON 
}