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

📄 bldc.c

📁 无刷电机DSP2407控制程序
💻 C
字号:
/*;========================================================================*
* File name : bldc.c *
* Author: Davidlee *
* Data: 2007.05.17*
* Version: 2.0 *
* Organization: Tianhuang Technology Co.ltd
* Description : Brushless DC motor drive using TMS320LF2407.SCI communication 
* uses to control the Brushless DC motor's running direction.Also, the 
* potentiometer in "A/D conversional unit" uses to control the Brushless 
* DC motor's rotating speed. 
;==========================================================================*
*/
#include "F2407_c.H" 	//the header file

 	    asm(" .word   #0ffffh ");
	    asm(" .word   #0ffffh ");
	    asm(" .word   #0ffffh ");
	    asm(" .word   #0ffffh ");

void system_init();
void EVA_init();
void SCI_init();
void ADC_init();
void KICK_DOG();
void rising1();
void falling1();
void rising2();
void falling2();
void rising3();
void falling3();
unsigned int read_phase(); //读相位控制字
void interrupt nothing();
void interrupt EVA_timer1_isr();
void interrupt SCI_INT();
 
       int temp1,temp2,i,j;
       unsigned int IntCount;
       unsigned int AD[8];
       unsigned int sum;
       unsigned int cmpr;
       unsigned int phase;
       unsigned int direction;
       unsigned int flag;
	   unsigned int ph_data;

main()
{       system_init();
   
        EVA_init();
        SCI_init();
        ADC_init();

        IntCount=0x0;
        direction=1;
        cmpr=500;
   
        while(1)
        {  phase=read_phase();
  		
  		   if(cmpr<30)
  			   cmpr=0;        //AD采样最小值时停掉电机
  		   if(direction==0)   //反转(顺时针)
  			 switch(phase)
  			 {
  				case 1:rising2() ;break;
  				case 2:falling2();break;
  				case 3:falling1();break;
  				case 4:rising1() ;break;
  				case 5:falling3();break;
  				case 6:rising3() ;break;
  				default:break;
  			 }
  		   else			  //正转(逆时针)
  			 switch(phase)
  			 {
  				case 1:rising3() ;break;
  				case 2:falling3();break;
  				case 3:rising1() ;break;
  				case 4:falling1();break;
  				case 5:falling2();break;
  				case 6:rising2() ;break;
  				default:break;
  			 }
         }
}

void  system_init()          /*系统初始化子程序*/
{       
        asm(" SETC  INTM");          //屏蔽中断
        asm(" CLRC  SXM ");          //符号位不作扩展    
        asm(" SETC  OVM ");          //正常溢出
        asm(" CLRC  CNF ");          //B0设置为数据存储区
        
        temp1=0x0;
        asm(" OUT _temp1,0FFFFh ");  //设置整体延时为0   
        SCSR1=0x0FC;                 //使能ADC,SCI,SPI,CAN,EVB,EVA时钟
        
        WDCR=0x6F;
        KICK_DOG();                  //看门狗不使能
        
        IFR=0x0FFFF;                 //清除全部中断标志,"写1清0"
        IMR=0x012;
        
        MCRA=0xFFC3;   //设置复用口SCITXD,SCIRXD,PWM1~PWM6为普通功能口 IOPA3,IOPA4,IOPA5为I/O管脚
        MCRB=0xFFFD;   //设置仿真口
        PADATDIR=0x0;  //所有I/O口均置为输入状态
        PBDATDIR=0x0;
        PCDATDIR=0x0;
        PDDATDIR=0x0;
        PEDATDIR=0x0;
        PFDATDIR=0x0;
        
        temp2=0x0FFFF;
        asm(" OUT _temp2,2000H");
        asm(" OUT _temp2,6000H");
}

void  EVA_init()           /*EVA初始化子程序,T1作为全局定时器,定时周期20us,晶振20MHz*/
{
        EVAIMRA=0x100;
        EVAIMRB=0x0;
        EVAIMRC=0x0;
        EVAIFRA=0xFFFF;
        EVAIFRB=0xFFFF;
        EVAIFRC=0xFFFF;
        GPTCONA=0x41;
        T1CON=0x1046;
        T1PR=0x470;
        T2PR=0x0;
        T1CNT=0x0;
        T2CNT=0x0;
        CMPR1=0x400;
        CMPR2=0x400;
        CMPR3=0x100;
        COMCONA=0xAE00;
        ACTRA=0x999;
        DBTCONA=0xFE0;
        ACTRA=0xFE3;
        asm(" CLRC INTM");          //允许中断
}

void  SCI_init()             /*SCI通信初始化子程序*/
{      
        SCICCR=0x27;
        SCICTL2=0x2;
        SCIHBAUD=0x0;
        SCILBAUD=0x2A;
        SCIPRI=0x20;
        SCICTL1=0x23;
}

void  ADC_init()             /*A/D转换初始化子程序*/
{        
        ADCTRL1=0x4000;
        ADCTRL1=0x3000;
        
        MAX_CONV=0x7;
        CHSELSEQ1=0x3333;
        CHSELSEQ2=0x3333;
         
        ADCTRL2=0x4000;
}

void  KICK_DOG()            /*复位看门狗密钥*/
{ 
        WDKEY=0x5555;
        WDKEY=0xAAAA;
}

void rising1()
{
	    ACTRA=0xF3E;
	    CMPR1=cmpr;
	    CMPR2=cmpr;
	    CMPR3=0;
}

void falling1()
{
	    ACTRA=0xFE3;
	    CMPR1=cmpr;
	    CMPR2=cmpr;
	    CMPR3=0;
}

void rising2()
{
	    ACTRA=0x3EF;
	    CMPR2=cmpr;
	    CMPR3=cmpr;
	    CMPR1=0;
}

void falling2()
{
	    ACTRA=0xEF3;
	    CMPR1=cmpr;
	    CMPR3=cmpr;
	    CMPR2=0;
}

void rising3()
{
	    ACTRA=0xE3F;
	    CMPR2=cmpr;
	    CMPR3=cmpr;
	    CMPR1=0;
}

void falling3()
{
	    ACTRA=0x3FE;
	    CMPR1=cmpr;
	    CMPR3=cmpr;
	    CMPR2=0;
}

unsigned int read_phase()
{	
	   MCRA=0xFFC3;
	   PADATDIR=0xC700;
	   ph_data=(PADATDIR>>3)&0x7;
	
	   return(ph_data);	
}

//=======================================================
//该中断服务程序主要是为了防止干扰,不作任何其他操作
//=======================================================
void interrupt nothing()
{
       return;                   //中断直接返回
}

//=======================================================
//定时器比较中断1,AD转换改变PWM脉冲占空比,从而改变电机的转速
//=======================================================
void interrupt EVA_timer1_isr()
{
    
    IntCount++;
   	if(IntCount>10)
   	{
   	    ADCTRL2=0x4000;               //软件启动A/D转换
        ADCTRL2=0x2000;
   		
   		IntCount=0;
   		
   loop: if(j==1)
        {j=ADCTRL2&0x8;               //等待AD转换完成
         goto loop;
        }
        asm(" CLRC  SXM ");
        AD[0]=RESULT0>>6;             //把AD转换的结果右移6位后存入规定的数组
        AD[1]=RESULT1>>6;
        AD[2]=RESULT2>>6;
        AD[3]=RESULT3>>6;
        AD[4]=RESULT4>>6;
        AD[5]=RESULT5>>6;
        AD[6]=RESULT6>>6;
        AD[7]=RESULT7>>6;
        
        for(i=0;i<8;i++)
        {                       
           sum=sum+AD[i];               
        }
		cmpr=sum>>3;           //取8次采样的平均值

    	sum=0;
    }	
    	EVAIMRA=0x100;
    	EVAIFRA=0xFFFF;      //清除定时器1周期中断标志
        asm(" CLRC INTM");
}

//=======================================================
//SCI通信,上位机发送55或AA控制电机转向
//=======================================================
void  interrupt SCI_INT()
{      // int j;
         
          j=SCIRXBUF&0xFF;
        
        if(j==0xAA)
          {
            direction = 1; //正转(逆时针)
          }
         else if(j==0x55)
          {
            direction = 0; //反转(顺时针)
          }
         else
          {
            asm(" CLRC INTM ");
            return;
          }
            IFR=0xFFFF;
            asm(" CLRC INTM ");    
}
//=======================================================
//结束
//=======================================================

⌨️ 快捷键说明

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