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

📄 main.dsp

📁 非常实用的AD和pwm的ad公司21990dsp芯片的控制源代码
💻 DSP
字号:
/****************************************************************************************
*										       								*
*  Application: ADC block initialisation and usage: Generate three-phase sinewaves 						       *

* File: Main.dsp								       						*
*										       								*
* Description: main program file						       				*
* Purpose    : 									       						*
* 										       								*
* Author     : JC								       						*
* Version    : 1.0								       						*
* Date       : Mar 2002                                                     *
* Modification History:    none							       				*
*										       								*
* Embedded Control Systems							     					*
* Analog Devices Inc.								       					*
****************************************************************************************/

/****************************************************************************************
* Include General System Parameters and Libraries                                      *
****************************************************************************************/

#include <main.h>;
#include <pwm.h>;

/****************************************************************************************
* Constants defined in this code                                      *
****************************************************************************************/

#define Two_PI      	     65536		
#define Two_PI_Over_Three    Two_PI / 3		
#define Fundamental_freq    60						//Desired fundamental frequency [Hz]
#define Theta_Increment   Fundamental_freq*Two_PI/PWM_freq   

/****************************************************************************************
* Global Routines defined in this code                                      *
****************************************************************************************/
.global	start;

/****************************************************************************************
* Global Variables defined in this code                                      *
****************************************************************************************/
/*None*/

/****************************************************************************************
* Local Variables defined in this code                                      *
****************************************************************************************/

.section/data seg_dmdata;

.VAR Theta = 0;// current phase angle [from -pi to pi]
.VAR Amplitude_factor =0x7fff;// scaling factor of amplitude
.VAR PWM_TM_maxvalue;
.VAR Scaled_amplitude;
.extern divdee;
/****************************************************************************************
* Local Variables defined in this code                                      *
****************************************************************************************/


.section/pm	seg_pmcode;

.VAR PI_Coef32[2] =0xE101, 0x2000; //kp=.25, wpi=50Hz

.section/data seg_dmdata;

.VAR PI_Delay32[3] =0x0000, 0x0000, 0x0000;	//[Ik, Uk_M, Uk_L]

.VAR TMP;

.VAR TX_DATA[8] =0x007E, 0x0000, 0x0000, 0x0005, 0x0005, 0x0005, 0x008D, 0x007F ;	//
//.VAR Theta = 0;             // current phase angle [from -pi to pi]
.VAR Amplitude_factor =0x7fff;// scaling factor of amplitude
.VAR PWM_TM_maxvalue;
.VAR ISET;
.VAR IFDATA;
.VAR VSET;
.VAR VFDATA;

.VAR Scaled_amplitude;
.VAR JUDGE; 
.VAR ZERO;
.VAR PWMOUT;
.VAR counter_int5 = 0;
.VAR Timer__Flag_Polarity; 

.VAR SPORT_REC_Polarity;
.VAR PWM_Flag_Polarity=0x0000;
.VAR RX_DATA_LWORD[8]= 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000;
.VAR RX_DATA_HWORD;
.VAR RX_DATA;
.VAR WORD_JUDGE;
.VAR Wirefeed_val;
.VAR ERROR;
.VAR WIRE_V;

.VAR hundred_coeff_I;                  //100*KI
.VAR decade_coeff_I;                   //10*KI
.VAR hundred_coeff_V;                  //100*KV
.VAR decade_coeff_V;                   //10*KV
.VAR VFDATA_FIX;
.VAR IFDATA_FIX;

.VAR SEND_START_I=0x007E;
.VAR SEND_TARGET_I;
.VAR SEND_TYPE_I;
.VAR hundred_I;                  //HUNDRED OF I TO BE DISPLAYED
.VAR decade_I;                   //DECADE OF I TO BE DISPLAYED
.VAR single_I;                   //SINGLE OF I TO BE DISPLAYED
.VAR SEND_CHECK_I;
.VAR SEND_END_I=0x007F;

.VAR SEND_START_V=0x007E;
.VAR SEND_TARGET_V;
.VAR SEND_TYPE_V;
.VAR hundred_V;                  //HUNDRED OF V TO BE DISPLAYED
.VAR decade_V;                   //DECADE OF V TO BE DISPLAYED
.VAR single_V;                   //SINGLE OF V TO BE DISPLAYED
.VAR SEND_CHECK_V;
.VAR SEND_END_V=0x007F;

.VAR FLAGC_VAL=0x0000;
.VAR FLAGS_VAL=0x0000;
.VAR FIO_DATA_IN_VAL;

.VAR AR_STACK;
.VAR iopg_STACK;
.VAR AX0_STACK;
.VAR AY0_STACK;
.VAR SR0_STACK;
.VAR SR1_STACK;
.VAR MR1_STACK;
.VAR MR0_STACK;
.VAR MX0_STACK;
.VAR MY0_STACK;
.VAR SE_STACK;
/****************************************************************************************
* Start of program code                                      *
****************************************************************************************/
.section/pm	seg_pmcode;

start:

	dmpg1 = 0;					// setting data memory indirect access to accessing internal memory, i.e. page 0
	dmpg2 = 0;
	ijpg  = 0;					// setting indirect jump page to accessing internal memory, i.e. page 0

	ar = 0;
	DM(Theta) = ar;				// reset angle

	dis int;					//disable interrupts

//////////////////////////////////////////////////////////////////////////////////    
    
PREPARE_HEX_BIN:

//    MX0= 0x0041;                //IT'S coeff KI OF I_AD(HEX) TURN INTO I(reality)
//    MY0= 0x0064;                //IT'S coeff OF 100
//    MR = MX0*MY0(UU);               //=100*KI
    AR=0x1964;
    DM(hundred_coeff_I) = AR;   //MR0;


//    MX0= 0x0041;                //IT'S coeff KI OF I_AD(HEX) TURN INTO I(reality)
//    MY0= 0x000A;                //IT'S coeff OF 10
//    MR = MX0*MY0(UU);               //=10*KI
    AR = 0x028A;
    DM(decade_coeff_I) = AR;    //MR0;
    
///////////////////////////////////////////////////////////////////////////////////////    


I_HEX_BIN:

    AR = DM(IFDATA);
    AR = AR+0x7FFF;                 //ADJUST IFDATA FROM 8001-7FFF TO 0-FFFF
    DM(IFDATA_FIX)=AR;

    AR=DM(hundred_coeff_I);
    AY0=DM(IFDATA_FIX);
    AY1=0;
    call divdee;                    //(IFDATA_FIX)/(hundred_coeff_I)       
    DM(hundred_I)=AR;               //HUNDRED OF I TO BE DISPLAYED

///////////////////////////////////////////////////////////////////

    AX0=DM(IFDATA_FIX);
    MX0=DM(hundred_coeff_I);
    MY0=DM(hundred_I);
    MR = MX0*MY0(UU);                   //(hundred_coeff_I)*(hundred_I)
    AY0=MR1;                        
    AR=AX0-AY0;                     //(IFDATA_FIX)-[(hundred_coeff_I)*(hundred_I)]

    AY1=AR;
    AY0=0;
    AR=DM(decade_coeff_I);
    call divdee;                    

//{(IFDATA_FIX)-[(hundred_coeff_I)*(hundred_I)]}/(decade_coeff_I)    
    DM(decade_I)=AR;                   //DECADE OF I TO BE DISPLAYED

///////////////////////////////////////////////////////////////////////////////////////

    AX0=DM(IFDATA_FIX);
    MX0=DM(hundred_coeff_I);
    MY0=DM(hundred_I);
    MR = MX0*MY0(UU);                   //(hundred_coeff_V)*(hundred_V)
    AY0=MR1;                        
    AR=AX0-AY0;                     //(VFDATA_FIX)-[(hundred_coeff_V)*(hundred_V)]

    AR =AX0;
    MX0=DM(decade_coeff_I);
    MY0=DM(decade_I);
    MR =MX0*MY0(UU);                   //(decade_coeff_V)*(decade_V)
    AY0=MR1;                        
    AR=AX0-AY0;                      //(VFDATA_FIX)-[(hundred_coeff_V)*(hundred_V)]-(decade_coeff_V)*(decade_V)    
    
    DM(single_I)=AR;                   //SINGLE OF I TO BE DISPLAYED	
PWM_Init(PWM_Trip_Isr, PWM_Sync_Isr); //initialize PWM blocks and setting up ADC end of conversion (instead of PWMSYnc) and PWM trip interrupts

ADC_Init(ADC_Number_of_samples, ADC_EOC_Isr);//Initialise ADC interrupt and calculate the offset values and assign ADC EOC interrupt to USR2

	iopg= PWM0_Page;	
	ar = IO(PWM0_TM);			// calculate the maximum duty cycle value, from (-PWMTM/2-PWMDT) to (PWMTM/2 + PWMDT)
	sr = lshift ar by -1 (LO);	// divide PWMTM by 2
	ax0 = IO(PWM0_DT);
	ar = sr0 + ax0;
	DM(PWM_TM_maxvalue) = ar;	// store maximum duty cycle value

	ar =0;
	IRPTL = ar;					// clear pending interrupts

	ar = IMASK;
	ay0=0xFFDF;
	ar=ar and ay0; 			//disable USR1
	ay0 = 0x0050;			/* enable USR0 and USR2*/
	ar = ar or ay0;
	IMASK = ar;

	ena int; 					//enable interrupts


Main:

	jump Main;

/****************************************************************************************
*ADC_EOC interrupt service routine                                      *
****************************************************************************************/

ADC_EOC_Isr:

	iopg=ADC_Page;			//write 1 to clear ADC EOC interrupt
	ar=0x0100;
	IO(ADC_STAT)=ar;

	ADC_Read(ADC_DATA0, Offset_0to3);	//read amplitude factor from ADC VIN0, result stored in ar
	DM(Amplitude_factor)=ar;
	my0=DM(PWM_TM_maxvalue);
	mr=ar*my0(ss);				// scale the amplitude, 0with amplitude_factor = (PWMTM/2-PWMDT)/(PWMTM/2+PWMDT) maximum scaling without overmodulation
	DM(Scaled_amplitude)=mr1;
	
	iopg = PWM0_Page;
	Set_DAG_registers_for_trigonometric;
	
	ax0 = DM(Theta);			// load current angle

	ay0 = Theta_Increment;		// Theta is saved in ax0 so may just increment angle now
	ar = ax0 + ay0;
	DM(Theta) = ar;				// store for next cycle
	Sin(ax0); 					// phase A (result in ax1)

	my0 = DM(Scaled_amplitude);	// contains maximum value for dutycycle registers (PWMTM/2+Deadtime)xamplitude_factor 
	mr = ax1 * my0 (SS);		//calculate duty cycle for channel A
	IO(PWM0_CHA)= mr1;			// load duty in channel A 


	ay0 = Two_PI_Over_Three;	// phase B
	ar = ax0 - ay0;
	Sin(ar); 					// phase B (result in ax1)
	my0 = DM(Scaled_amplitude);	// contains maximum value for dutycycle registers (PWMTM/2+Deadtime)xamplitude_factor 
	mr = ax1 * my0 (SS);		//calculate duty cycle for channel B
	IO(PWM0_CHB)= mr1;			// load duty in channel B 


	ay0 = Two_PI_Over_Three;	// phase C
	ar = ax0 - ay0;
	Sin(ar); 					// phase C (result in ax1)
	my0 = DM(Scaled_amplitude);	// contains maximum value for dutycycle registers (PWMTM/2+Deadtime)xamplitude_factor 
	mr = ax1 * my0 (SS);		//calculate duty cycle for channel C
	IO(PWM0_CHC)= mr1;			// load duty in channel C 
 
	rti;

/****************************************************************************************
*PWMSYNC interrupt service routine                                      *
****************************************************************************************/

PWM_Sync_Isr:
/*  this PWM SYNC interrupt service routine is not enabled here
	user can enable it by enabling USR1 in the IMASK register*/

//	iopg = PWM0_Page;	//set io page to PWM page, remove the // sign of these 3 lines if PWM_Sync interrupt is enabled
//	ar = 0x0200;		// Write 1 to clear interrupt  
//	IO(PWM0_STAT) = ar;
rti;


/****************************************************************************************
*PWMTRIP interrupt service routine                                      *
****************************************************************************************/

PWM_Trip_Isr:
	
	iopg = PWM0_Page;//set io page to PWM page

	ar = 0x0100;		// W1 to clear PWMTRIP interrupt status  
	IO(PWM0_STAT) = ar;
	nop;// user can implement the PWM trip interrupt in this routine, here no operation is implemented.

	rti;



⌨️ 快捷键说明

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