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

📄 bldcsensor.c

📁 TI公司的DSP(LF2407A)编写的有霍尔位置传感器的无刷直流电机控制程序,内含子程序说明
💻 C
字号:
/* ====================================================
System Name:  BLDCSensor(BLDC有位置传感器)
 ====================================================*/
#include <bldcSensor.h>

void RstSystem(void);
void rtmon_init(void);
void interrupt c_int03();
void interrupt phantom(void);
void GetSpeed(void);
// Global variables used in this system
int SpeedRef = 0x669;           		// 转速设定300rpm (pu)
int CurrentSet = 0x096;					//电流设定,上限;1/20

int VirtualTimer = 0;
int ILoopFlag = FALSE;
int SpeedLoopFlag = FALSE;
int DFuncDesired = 0x2fff;      		// Desired duty cycle (Q15)
long speedtime=0;
int speedcount;
/*-----------------------------电机转子位置输出表-------------------------------*/
//表电机控制器换向表,电路板输出为低电平导通,高电平截至
unsigned int ACTRX1[]={0X0FFF,0X0F3E,0X03FE,0X03EF,0X0FE3,0X0EF3,0X0E3F,0X0FFF};  	//电动运行换向表:AB->AC->BC->BA->CA->CB->AB					
unsigned int ACTRX[]={0X0FFF,0X0FFB,0X0FFB,0X0FBF,0X0FBF,0X0BFF,0X0BFF,0X0FFF}; 	//发电运行换向表
//自定义变量2007-6-2
		unsigned int  disp_refresh=0;
		int runled=0x0ffff;
        unsigned int  COM=0x0ff00;
		int keycounter=0;
		int key=0;   	//6-7-2007添加,定义并初始化KEY变量 
		int HallValue;
		int TabShift=0;
		int duty;
// System settings
#define WAIT_STATES     0x00C0

//Instance the WATCHDOG Interface.
        WATCHDOG wdog = WATCHDOG_DEFAULTS;
// Instance PID regulator to regulate the DC-bus current and speed
		PID2 pid1_idc = PID2_DEFAULTS;
		PID2 pid1_spd = PID2_DEFAULTS;
// Instance a PWM driver instance
		PWMGEN pwm1 = PWMGEN_DEFAULTS;
// Create an instance of the ADC driver
		ADCVALS adc1 = ADCVALS_DEFAULTS;		
// Instance a Hall effect driver
		HALL3 hall1 = HALL3_DEFAULTS;
// Instance a ramp controller to smoothly ramp the frequency
		RMPCNTL rc1 = RMPCNTL_DEFAULTS;
// Instance a RAMP2 Module
		RMP2 	rmp2 = RMP2_DEFAULTS;
// Instance a MOD6 Module
		//MOD6CNT mod1 = MOD6CNT_DEFAULTS;
// Instance a SPEED_PR Module
		SPEED_MEAS_CAP speed1 = SPEED_MEAS_CAP_DEFAULTS;
/*-----------------------------------------------------------------------------
    Instance the ISR checking variable
-----------------------------------------------------------------------------*/
        int	isr_ticker;

void main()
{
/*-----------------------------------------------------------------------------
    Return system to a sane condition
-----------------------------------------------------------------------------*/
    RstSystem();
// Initialize PWM module
    pwm1.DutyFunc = DFuncDesired;                            // DutyFunc = Q15 
    pwm1.init(&pwm1);         								 /* pwm driver initialization */
// Initialize ADC module
    adc1.ChSelect = 0x6666;   		//母线电流通道AD06
	adc1.init(&adc1);
// Initialize the SPEED_PR module (150 MHz, N = 1 event period/rev)
 	speed1.InputSelect = 0;			//?
 	speed1.BaseRpm = 6000;			//120*(BASE_FREQ/P);
 	speed1.SpeedScaler = 400;		//(Uint32)(ISR_FREQUENCY/(1*BASE_FREQ*0.001));BASE_FREQ=100;ISR_FREQUENCY=40(K)
	speed1.motorpairs= 23;
// Initialize RMPCNTL module
    rc1.RampDelayMax = 0x00ff;
    rc1.RampLowLimit = 0x8000;		//_IQ(0);
    rc1.RampHighLimit = 0x7FFF;		//_IQ(1);
// Initialize Hall module   
    //hall1.DebounceAmount = 5;
    //hall1.Revolutions = -10;		//?
    hall1.init(&hall1);
// Initialize RMP2 module
	rmp2.Out = DFuncDesired;
	rmp2.Ramp2Delay = 50;
    rmp2.Ramp2Max = 0x7FF0;
    rmp2.Ramp2Min = 0x000F;
// Initialize the PID2 module for dc-bus current
    pid1_idc.k0_reg2 = 0x0200; 		//Q9,_IQ(1);                  
	pid1_idc.k1_reg2 = 0x0e0; 		//Q13,_IQ(T/0.003);			
 	pid1_idc.kc_reg2 = 0x0506; 		//Q13,_IQ(0.2);
    pid1_idc.max_reg2 = 0x7fff;   // Q15  D=100% ,_IQ(0.99);
    pid1_idc.min_reg2 = 0x0000; 	//_IQ(0); 
// Initialize the PID2 module for speed
    pid1_spd.k0_reg2 = 0x0800;		//_IQ(2);
	pid1_spd.k1_reg2 = 0x40;//0x0740;	//_IQ(T/0.1);()0.002
 	pid1_spd.kc_reg2 = 0x0506;		//_IQ(0.2);
    pid1_spd.max_reg2 = 0x7fff;	//// Q15  D=100%;
    pid1_spd.min_reg2 = 0;	// _IQ(10%); 

    T2PR = SYSTEM_INT_PERIOD;  /* Initialize period register ,time base from T2 underflow interrupt (i.e. period)*/
    T2CNT = 0x0000;
    T2CON = 0x9040;		   // Count up, x1, internal clk, disable compare, use own period

/*-----------------------------------------------------------------------------
    Initialise the Real time monitor
-----------------------------------------------------------------------------*/
#if (REAL_TIME == TRUE)
        rtmon_init();      /* Call the monitor init function  */
#endif /* REAL_TIME==TRUE */

// Enable global Interrupts and higher priority real-time debug events:
        asm("  CLRC	INTM ");      /* set off the system running */

/*-----------------------------------------------------------------------------
    LCD显示程序
----------------------------------------------------------------------------*/
 			LCD_disp1();
//			COM=PFDATDIR;
//        	PFDATDIR=COM;
//  		PFDATDIR=PFDATDIR|0x0020; 
/*-------------------------------------------------------------------------*/
// IDLE loop. Just sit and loop forever:	
        while(1)             /* Nothing running in the background at present */
        {
/*------------------------运行灯闪烁------------------------*/
        	keycounter++;
			disp_refresh++;
			if(disp_refresh>=40000)//1s刷新一次LCD显示
			{	
				disp_refresh=0;
//			PFDATDIR=(PFDATDIR|0x2020)&((~runled)|0x0ffdf);
//			COM=PFDATDIR;
			Iref_disp();			//电流给定值显示
			Ifb_disp();				//电流实际值显示
			Vref_disp();			//转速给定值显示
			Vfb_disp();				//转速实际值显示
			fpwm_disp();			//PWM斩波频率显示
			Dpwm_disp();			//PWM占空比显示
			mod6_disp();			//换向的状态,0~5中的一个.St显示
			Hmap_disp();			//换向表
			prop_int();
//			PFDATDIR=COM;
			}
/*-------------6-7-2007--按键设定用s1来增加,s2来减少---------*/
		   if(keycounter>=400)    //10ms处理一次按键
	  		{	keycounter=0;
				key=Keys1s8();
    	  	 switch(key)
    	  	 {
 				case 1:	{SpeedRef = SpeedRef+56;break;} //设定+步长10RPM
	 			case 2: {SpeedRef = SpeedRef-56;break;} //设定-步长10RPM
	 			case 3: {pid1_spd.k0_reg2 = pid1_spd.k0_reg2+0x010;break;}		//_IQ(2);
	 			case 4: {pid1_spd.k0_reg2 = pid1_spd.k0_reg2-0x010;break;}		//_IQ(2);
	 			case 5: {pid1_spd.k1_reg2 = pid1_spd.k1_reg2+0x01;break;}		//_IQ(2);
	 			case 6: {pid1_spd.k1_reg2 = pid1_spd.k1_reg2-0x01;break;}		//_IQ(2);
				case 7: {duty = duty + 0x1000;break;}
				case 8: {TabShift = TabShift+1;break;}
				default:;
		 	 }
		    }
/*------------------------------------------------------------------------------*/
/************************************************************************
GetSpeed,通过使用每个机械周期内中的值确定电机的精确速度。
*************************************************************************/
/*		if (HallValue == 3) // 如果位于区间1
		{
			HallValue = 0xFF; // 强制一个新值作为区间值
			if (++speedcount == speed1.motorpairs) // 对于23对极电机,将此代码段执行23 个电周期(即1 个 机械周期)
			{
			  //Timer3 = TMR3;// 读tmr3 的最新值
			  //TMR3 = 0;
			  //Count = 0;
			  GetSpeed();// 确定速度
			}
		}*/
     } /* Main system background loop */

} /* End: main() */

void interrupt c_int03()
{
//        asm("      CLRC     XF ");
        isr_ticker++;

/*-----------------------------------------------------------------------------*/
        EVAIFRB=0x0ffff;          /* Clear all EV1 Group A EV interrupt flags*/
// ------------------------------------------------------------------------------
//    Call the ADC04U_DRV read function.
// ------------------------------------------------------------------------------
//	  adc1.read(&adc1);
// ------------------------------------------------------------------------------
//    Connect inputs of the RMP module and call the Ramp control
//    calculation function.
// ------------------------------------------------------------------------------
      rc1.TargetValue = SpeedRef;
      rc1.calc(&rc1);
// ------------------------------------------------------------------------------
//    Connect inputs of the HALL module and call the Hall sensor
//    read function.
// ------------------------------------------------------------------------------
      hall1.read(&hall1);
// ------------------------------------------------------------------------------
//    Connect inputs of the MOD6 module and call the Modulo 6 counter
//    calculation function.
// ------------------------------------------------------------------------------
      //mod1.TrigInput = hall1.CmtnTrigHall;
      //mod1.Counter = hall1.HallMapPointer; 
      //mod1.calc(&mod1);
// ------------------------------------------------------------------------------
//    Connect inputs of the RMP2 module and call the Ramp control 2
//    calculation function.
// ------------------------------------------------------------------------------
      rmp2.DesiredInput = DFuncDesired;
      rmp2.calc(&rmp2);
// ------------------------------------------------------------------------------
//    Connect inputs of the PID_REG3 module and call the PID speed controller
//    calculation function.
// ------------------------------------------------------------------------------  
      pid1_spd.ref_reg2 = rc1.SetpointValue;
      pid1_spd.fb_reg2 = (int)(speed1.Speed);
      pid1_spd.calc(&pid1_spd);
// ------------------------------------------------------------------------------
//    Set the speed closed loop flag once the speed is built up to a desired value. 
// ------------------------------------------------------------------------------
      if (rc1.EqualFlag == 0x7FFF)  {
//         SpeedLoopFlag = TRUE; 
         rc1.RampDelayMax = 300;  
      }
// ------------------------------------------------------------------------------
//    Connect inputs of the PWM_DRV module and call the PWM signal generation
//    update function.
// ------------------------------------------------------------------------------
   // Switch from fixed duty-cycle or controlled Speed duty-cycle by SpeedLoopFlag variable
      if (SpeedLoopFlag == FALSE)
         pwm1.DutyFunc = (rmp2.Out+duty)&0x07fff;           // fixed duty-cycle
      else 
         pwm1.DutyFunc = pid1_spd.out_reg2;   	// controlled Speed duty-cycle

      //pwm1.CmtnPointer = hall1.tab;
	  HallValue=hall1.tab;
	  ACTRB=ACTRX1[(hall1.tab+TabShift)&6];
      pwm1.update(&pwm1);

// ------------------------------------------------------------------------------
//    Connect inputs of the SPEED_PR module and call the speed calculation 
//    function.
// ------------------------------------------------------------------------------  
      if (HallValue == 3) {
		HallValue = 0xFF; // 强制一个新值作为区间值
		if (++speedcount == speed1.motorpairs) // 对于23对极电机,将此代码段执行23 个电周期(即1 个 机械周期)
	 	{
        	 speed1.TimeStamp = VirtualTimer;
        // speed1.calc(&speed1);
      }
//      if (speed1.InputSelect == 0)  
	   //{
	     	 speed1.OldTimeStamp = speed1.NewTimeStamp;
	    	 speed1.NewTimeStamp = speed1.TimeStamp; 
	    	 speed1.EventPeriod = speed1.NewTimeStamp - speed1.OldTimeStamp; 
   
 	    	if (speed1.EventPeriod < 0)
 	      	speed1.EventPeriod += 32767;   // 0x7FFF = 32767
 	   //}
        	speed1.calc(&speed1);
/*	  	 SpeedTemp = (speed1.SpeedScaler*speed1.BaseRpm)/(speed1.EventPeriod*speed1.motorpairs);
 	 	 speed1.SpeedRpm =(int)SpeedTemp; 
		 speed1.Speed = ((long)speed1.SpeedRpm<<15)/((long)speed1.BaseRpm);
*/
	}
// ------------------------------------------------------------------------------
//    Increase virtual timer and force 15 bit wrap around
// ------------------------------------------------------------------------------
	VirtualTimer++;
	VirtualTimer &= 0x7FFF;
	speedtime++;
	speedtime &= 0x7FFFFFFF;

// asm("      SETC     XF ");//SCSR2中/BOOT EN.BOOT使能位,这一位反映XF引脚在复位时的状态,它可以被软件改变.XF=0硎臼鼓芤

⌨️ 快捷键说明

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