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

📄 a_dc.c

📁 无刷直流电机驱动程序
💻 C
字号:
/* ===================================================================== */
/* File name : DC.C   */
/* Author: JZMING       */
/* Data: 2006.8.20      */
/* Version: 1.0         */
/* Organization: DSP MOTO CONTROL PROGROM 
/*               Zhejiang Tianhuang Techonology Industry Ltd., */
/* Description : C-PROGRAM TO CONTROL A DC USE F2407A        */ 
/* ================================================================== */
/*  头文件  */
#include "TYPEDEFS.H"
#include "F2407_c.H"
#include "CONSTANT.H"
#include "self_define.h"
#include <stdio.h> 
#include <math.h> 

/* ================================================================== */
/* 函数申明  */
void delay (WORD ms);
void led_shine();

/* ================================================================== */
/* 加密区  */
asm("	.word    #0ffffh");
asm("	.word    #0ffffh");
asm("	.word    #0ffffh");
asm("	.word    #0ffffh");

/*=================================================================== */
/* 定义全局变量 */
WORD  nor_flag=0,speed_counter=0;
WORD  current_counter=0;
unsigned char direction_flag=0;
int  adc_comp=0,adc_comp_a=0,adc_comp_b=0,adc_vdc=0;                   //必须双精度数 
int  n_ref_c=0;
extern unsigned int sci_buff[2];
extern int n_ref,speed_count,t23;
extern int speed_err,current_given;
extern int current_err,current_uref;
extern int speed_kp,speed_ki,speed_sum;
extern int current_kp,current_ki,current_sum;
extern int speed_pi_error1,speed_pi_error;
extern int current_pi_error,current_pi_error1;
extern int temp;
int u=0;

int Motor_position=0;
/* =============================================================== */
/* 中断屏蔽子程序 */         
void inline disable()
{
   asm("	setc INTM");
}

/* =============================================================== */
/* 中断使能子程序 */
void inline enable()
{
   asm("	clrc INTM");
}


/* =============================================================== */
/* 主函数 */

main()
{
   *ACTRA   = 0x0fff;
   disable();                                   //中断屏蔽
   sytem_init();                                //系统时钟建立
   spi_init();                                  //SPI初始化
   io_init();                                   //I/O口初始化
   ev_init();                                   //事件管理器初始化
   sci_init();                                  //串口初始化
   adc_init();
   cap_init();                                  //cap初始化
   
   current_counter = CUR_COUNTER_CON;           //电流PI循环次数
   speed_counter = SPEED_COUNTER_CON;           //速度PI循环次数
   
   *T1CON = *T1CON | 0x0040;   					//开启定时器1 
   enable();                                    //中断使能
   
   *ADCTRL2 = 0x2000;                           //软件启动ADC
   n_ref=0;
   speed_count=15000;         //Q8  1500=6000,58.59375
   speed_kp=100;
   speed_ki=40; 
   speed_sum=0;
   current_kp=10;
   current_ki=5;                      
   current_sum=0;  
   speed_pi_error1=0;
   speed_pi_error=0;
   current_pi_error=0;
   current_pi_error1=0;  

	    *MCRA=*MCRA&0xffc7;
	    Motor_position=*PADATDIR&0x0038;
	    Motor_position=Motor_position>>3;                      
    
        *MCRA=*MCRA|0x0038;     
            
   Double_ram_ini();          //初始化,往设定参数页地址置初值  
                
   while(1)
   {
   
   var_query_dram();
    
   var_set_dram();
   }
}

/* ================================================================= */
/* 电流采样子程序 */
void cur_sample(void)
{
   WORD adc_ia,adc_ib;

   adc_ia = *RESULT0 >> 6;   					//是周期中断,电流采样
   adc_ia += adc_ia_ref;     					//修正电流参数
   adc_comp_a = adc_ia-512; 
   
   adc_ib = *RESULT1 >> 6;   					//是周期中断,电流采样
   adc_ib += adc_ib_ref;     					//修正电流参数
   adc_comp_b = adc_ib-512;            

   adc_vdc=*RESULT2 >> 6;  
   
   *ADCTRL2 = 0x4000;                           //ADC指针复位
   *ADCTRL2 = 0x2000;       
   
   switch(Motor_position)
        {
        case 1:
              {
               if(direction_flag==0)         //6-pwm   1/6
                    adc_comp=adc_comp_a;
               else                          //2-pwm   2/5
                    adc_comp=-adc_comp_a;
               break;
               }
          case 2:
              {
               if(direction_flag==0)         //2-pwm   2/3
                   adc_comp=adc_comp_b; 
               else                          //4-pwm   1/4
                   adc_comp=adc_comp_a;
               break;
               }
         case 3:
              {
               if(direction_flag==0)         //3-pwm   3/6
                   adc_comp=adc_comp_b;
               else                          //5-pwm   4/5
                   adc_comp=-adc_comp_b;
               break;
               }
        case 4:
              {
               if(direction_flag==0)         //4-pwm  4/5
                   adc_comp=-adc_comp_b;
               else                          //6-pwm   3/6
                   adc_comp=adc_comp_b;
               break;
               }   
         case 5:
              {
               if(direction_flag==0)         //1-pwm   1/4
                   adc_comp=-adc_comp_b; 
               else                          //3-pwm    2/3
                   adc_comp=-adc_comp_a;
               break;
               }                                                               
         case 6:
              {
               if(direction_flag==0)         //5-pwm   2/5
                   adc_comp=-adc_comp_a;  
               else                          //1-pwm   1/6
                   adc_comp=adc_comp_a;  
               break;
               }
         default:
               {
                adc_comp=1000;
                break;
               }
         }
                                                                                                          //软件立即启动ADC
}

/* ==================================================================*/
/* 定时器1周期中断子程序 */
void interrupt t1_perint()        				   //定时器1周期中断----测试用
{
   WORD flag;
   int temp_value;
//   KICK_DOG;
   cur_sample();   
   
/*   u++;
   if(u>100)
   {
   *SCITXBUF=((int)n_feed);
   u=0;
   }*/
   
   
   
   if (n_ref>=0) direction_flag=0;      //正转标志
   else if (n_ref <0) direction_flag=1;  //反转标志   
    
   flag = *EVAIFRA & 0x0080;
   if (flag != 0x0080)            				   //如果不是周期中断,退出
   {

      asm( " clrc INTM");
      return;     
   }   
   
/*  temp_value=(sci_buff[0]*256)+sci_buff[1];       //串口发送的值
   n_ref_c = temp_value;            //速度给定值
   n_ref=n_ref_c;*/


// -------------- 速度计算PID调节部分开始  -------------------------

   speed_counter--; 
   if (speed_counter ==0)
   {
      t23=*T4CNT;
      speed_counter = SPEED_COUNTER_CON;          //赋初值
      speed_pi_on();  
      

   }

//----------------- 速度计算PID调节部分结束   -----------------------   
/*--------------- 电流采样PID调节部分开始   ------------------------ */ 

   if (1)
   {
                                      
      current_err=current_given-adc_comp;
    
      current_cal_pi();
   
 
 } 
//--------------- 电流采样PID调节部分结束  ------------------------- 

  

//   data_save_dram();                            //数据保存至双口RAM中    
//   led_shine();                                 //闪灯子程序,作测试用!!!
    *MCRA=*MCRA&0xffc7;
	Motor_position=*PADATDIR&0x0038;
	Motor_position=Motor_position>>3;
    *MCRA=*MCRA|0x0038; 
    
    sequence();
	
   *EVAIFRA = 0X0080;   				//清中断标志,以进行下次中断
   asm( " clrc INTM");
   return;
}

//============================================
//采用了PWM_ON调制策略
//============================================
sequence()
{
    switch(Motor_position)
         {
          case 1:
              {
               if(direction_flag==0)         //6-pwm   1/6
                   {
                    *ACTRA=*ACTRA&0xf000|0x0bfc;
                    *CMPR3=current_uref;
                   }
               else
                   {
                    *ACTRA=*ACTRA&0xf000|0x0cfb;
                    *CMPR1=current_uref;      //2-pwm   2/5
                    }
               break;
               }
          case 2:
              {
               if(direction_flag==0)         //2-pwm   2/3
                   {
                    *ACTRA=*ACTRA&0xf000|0x0fcb;
                    *CMPR1=current_uref;
                   }
               else
                   {
                    *ACTRA=*ACTRA&0xf000|0x0fbc;
                    *CMPR2=current_uref;      //4-pwm   1/4
                    }
               break;
               }
         case 3:
              {
               if(direction_flag==0)         //3-pwm   3/6
                   {
                    *ACTRA=*ACTRA&0xf000|0x03ef;
                    *CMPR2=current_uref;
                   }
               else
                   {
                    *ACTRA=*ACTRA&0xf000|0x0e3f;
                    *CMPR3=current_uref;      //5-pwm   4/5
                    }
               break;
               }
        case 4:
              {
               if(direction_flag==0)         //4-pwm  4/5
                   {
                    *ACTRA=*ACTRA&0xf000|0x0cbf;
                    *CMPR2=current_uref;
                   }
               else
                   {
                    *ACTRA=*ACTRA&0xf000|0x0bcf;
                    *CMPR3=current_uref;      //6-pwm   3/6
                    }
               break;
               }   
         case 5:
              {
               if(direction_flag==0)         //1-pwm   1/4
                   {
                    *ACTRA=*ACTRA&0xf000|0x0f3e;
                    *CMPR1=current_uref;
                   }
               else
                   {
                    *ACTRA=*ACTRA&0xf000|0x0fe3;
                    *CMPR2=current_uref;      //3-pwm    2/3
                   }
               break;
               }                                                               
         case 6:
              {
               if(direction_flag==0)         //5-pwm   2/5
                   {
                    *ACTRA=*ACTRA&0xf000|0x0ef3;
                    *CMPR3=current_uref;
                   }
               else
                   {
                    *ACTRA=*ACTRA&0xf000|0x03fe;
                    *CMPR1=current_uref;      //1-pwm   1/6
                    }
               break;
               }
         default:
               {
                *ACTRA=0x0fff;
                break;
               }
         }
}
//==================================
//霍尔元件捕获中断
//==================================
void interrupt capint()
{
        int temp=0,temp_2=0;
        temp=*PIVR;
        switch(temp)
            {
             case 0x33:
                {
                 *EVAIFRC=*EVAIFRC;
                 temp_2=*CAP1FBOT;
                 *T2CNT=0;
                 if(temp_2>11)
                    {
                     *MCRA=*MCRA&0xffc7;
                  	 Motor_position=*PADATDIR&0x0038;
                 	 Motor_position=Motor_position>>3; 
                     *MCRA=*MCRA|0x0038; 
        	
                    sequence();
                    }
                 *CAPFIFOA=0x1500;
                 break;
                }
             case 0x34:
                {
                 *EVAIFRC=*EVAIFRC;
                 temp_2=*CAP2FBOT;
                 *T2CNT=0;
                 if(temp_2>11)
                    {
                     *MCRA=*MCRA&0xffc7;
                  	 Motor_position=*PADATDIR&0x0038;
                 	 Motor_position=Motor_position>>3; 
                     *MCRA=*MCRA|0x0038; 
        	
                    sequence();
                    }
                 *CAPFIFOA=0x1500;
                 break;
                }   
             case 0x35:
                {
                 *EVAIFRC=*EVAIFRC;
                 temp_2=*CAP3FBOT;
                 *T2CNT=0;
                 if(temp_2>11)
                    {
                     *MCRA=*MCRA&0xffc7;
                  	 Motor_position=*PADATDIR&0x0038;
                 	 Motor_position=Motor_position>>3; 
                     *MCRA=*MCRA|0x0038; 
        	
                    sequence();
                    }
                 *CAPFIFOA=0x1500;
                 break;
                }
             default:break;
             }
             
        asm( " clrc INTM");
        return;
}   
 
/*=================================================================== */
/* 空中断子程序 */

void interrupt nothing()
{
   enable();
   return;
}

/* ==================================================================== */
/* 闪灯子程序,测试用!!!! */
void led_shine()
{
   nor_flag = ~nor_flag;     
   if (nor_flag)
   {
      asm( " clrc xf");
      delay(100);
   }
   else 
   {
      asm( " setc xf");
      delay(100);
   } 
}

/* ==================================================================== */
/* 延时子程序,测试用!!!!! */
void delay (unsigned int ms)
{  
   WORD i,j,k;
   KICK_DOG;
   for (i=0;i<=ms;i++)
   {
      for(j=0;j<200;j++)
      {
         k++;
      }
   }
}

⌨️ 快捷键说明

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