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

📄 a_dc.c

📁 无刷直流电机驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ===================================================================== */
/* 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,speed_err_old;
extern int current_err,current_uref,current_err_old;
extern int speed_kp,speed_ki,speed_kd,speed_sum;
extern int current_kp,current_ki,current_kd,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;
int pos_change=20;
/* =============================================================== */
int  adc_ia_ref=0,adc_ib_ref=0,adc_vdc_ref=0;
int  current_sam_count=0,current_sam_flag=0;
int  adc_comp_a_2=0,adc_comp_b_2=0,adc_vdc_2=0;
int  adc_comp_a_1=0,adc_comp_b_1=0,adc_vdc_1=0;
int  adc_temp=0;

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

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


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

main()
{
   KICK_DOG;
   *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;
   speed_kd=2;
   current_kd=2;                       
   current_sum=0;  
   speed_pi_error1=0;
   speed_pi_error=0;
   current_pi_error=0;
   current_pi_error1=0;  
   speed_err_old=0;
   current_err_old=0;
   

   *MCRA=*MCRA&0xffc7;
   Motor_position=*PADATDIR&0x0038;
   Motor_position=Motor_position>>3;                      
    
   *MCRA=*MCRA|0x0038;     

   Double_ram_ini();          //初始化,往设定参数页地址置初值                                
   while(1)
   {
      KICK_DOG;               //watchdog,must require!!!
   
      var_query_dram();
    
      var_set_dram();
   }
}

/* ================================================================= */
/* 电流采样子程序*/ 
void cur_sample(void)
{
    if(current_sam_flag==1)
     { 
      adc_comp_a_1 = *RESULT0 >> 6;   					//是周期中断,电流采样   					
      adc_comp_a_1 = adc_comp_a_1-adc_ia_ref; 
   
      adc_comp_b_1 = *RESULT1 >> 6;   					//是周期中断,电流采样   					
      adc_comp_b_1 = adc_comp_b_1-adc_ib_ref; 

      adc_vdc_1 = *RESULT2 >> 6;   					//是周期中断,电流采样   					
      adc_vdc_1 = adc_vdc_1-adc_vdc_ref; 
      
      *ADCTRL2 = 0x4000;                           //ADC指针复位
      *ADCTRL2 = 0x2000;  
      }
      adc_vdc=(adc_vdc_1+adc_vdc_2)>1;
      
      if(current_uref>500)
          {
           adc_comp_a=adc_comp_a_2;
           adc_comp_b=adc_comp_b_2;
           }
      else
          {
           adc_comp_a=adc_comp_a_1;
           adc_comp_b=adc_comp_b_1;
          }
   /* 
   switch(Motor_position)
   {
      case 1:
         if(direction_flag==0)         
            adc_comp=adc_comp_a;
         else                          
            adc_comp=-adc_comp_a;
      break;

      case 2:

         if(direction_flag==0)         
            adc_comp=-adc_comp_a; 
         else                          
            adc_comp=adc_comp_a;
      break;

      case 3:

         if(direction_flag==0)         
            adc_comp=-adc_comp_b;
         else                          
            adc_comp=adc_comp_b;
      break;

      case 4:
         if(direction_flag==0)         
            adc_comp=adc_comp_b;
         else                          
            adc_comp=-adc_comp_b;
      break;
  
      case 5:

         if(direction_flag==0)         
            adc_comp=adc_comp_a; 
         else                          
            adc_comp=-adc_comp_a;
      break;
                                                             
      case 6:
         if(direction_flag==0)         
            adc_comp=adc_comp_b;  
         else                          
            adc_comp=-adc_comp_b;  
      break;

      default:

         adc_comp=1000;
      break;
   }*/
//=============================================
//正转1 3 2 6 4 5 ,采样时尽量选不是换相的相
//=============================================   
   switch(Motor_position)
   {
      case 1:
         if(direction_flag==0)         //2,5
            adc_comp=-adc_comp_a;
         else                          //
            adc_comp=-adc_comp_a;
      break;

      case 2:

         if(direction_flag==0)         //1,4
            adc_comp=-adc_comp_b; 
         else                          //
            adc_comp=adc_comp_a;
      break;

      case 3:

         if(direction_flag==0)         //4,5
            adc_comp=-adc_comp_b;
         else                          //
            adc_comp=-adc_comp_b;
      break;

      case 4:
         if(direction_flag==0)         //3,6
            adc_comp=adc_comp_b;
         else                          //
            adc_comp=adc_comp_b;
      break;
  
      case 5:

         if(direction_flag==0)         //2,3
            adc_comp=adc_comp_b; 
         else                          //
            adc_comp=-adc_comp_a;
      break;
                                                             
      case 6:
         if(direction_flag==0)         //1,6
            adc_comp=adc_comp_a;  
         else                          //
            adc_comp=adc_comp_a;  
      break;

      default:break;
   }
                                                                                                        //软件立即启动ADC
}

/* ==================================================================*/
/* 定时器1周期中断子程序 */
void interrupt t1_perint()        				   //定时器1周期中断----测试用
{
   int flag;
   flag = *EVAIFRA & 0x0280;
   if (flag == 0x0200)            				   //如果不是周期中断,退出
   {
     if(current_sam_flag==1)
     { 
      adc_comp_a_2 = *RESULT0 >> 6;   					//是周期中断,电流采样   					
      adc_comp_a_2 = adc_comp_a_2-adc_ia_ref; 
   
      adc_comp_b_2 = *RESULT1 >> 6;   					//是周期中断,电流采样   					
      adc_comp_b_2 = adc_comp_b_2-adc_ib_ref; 

      adc_vdc_2 = *RESULT2 >> 6;   					//是周期中断,电流采样   					
      adc_vdc_2 = adc_vdc_2-adc_vdc_ref; 
      
      *ADCTRL2 = 0x4000;                           //ADC指针复位
      *ADCTRL2 = 0x2000;  
      }
      else
      {    
       current_sam_count++;
       if(current_sam_count>2000)
       {
         if(current_sam_count>2008)
           {
            adc_ia_ref=adc_ia_ref>>3;
            adc_ib_ref=adc_ib_ref>>3;
            adc_vdc_ref=adc_vdc_ref>>3;
            current_sam_count=0;
            current_sam_flag=1;
           }
          else
           {
            adc_temp = *RESULT0 >> 6;   					//是周期中断,电流采样   					
            adc_ia_ref = adc_ia_ref+adc_temp; 
   
            adc_temp = *RESULT1 >> 6;   					//是周期中断,电流采样   					
            adc_ib_ref = adc_ib_ref+adc_temp; 
      
            adc_temp = *RESULT2 >> 6;   					//是周期中断,电流采样   					
            adc_vdc_ref = adc_vdc_ref+adc_temp; 
      
            *ADCTRL2 = 0x4000;                           //ADC指针复位
            *ADCTRL2 = 0x2000;  
            }  
         }
      }
     *EVAIFRA = 0X0200;    
   }   

   else
   {
   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;  //反转标志   

/* 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(pos_change>5)
        {
        current_err=current_given-adc_comp;
        current_cal_pi(); 
        }
    else

⌨️ 快捷键说明

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