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

📄 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 var_init(void);
void speed_pid_ini(void);
void cur_pid_ini(void);
void led_shine();

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

/*=================================================================== */
/* 定义全局变量 */
WORD  nor_flag=0,speed_counter=0,test_counter=250;
WORD  current_counter=0;
WORD  capt;        				//hall位置值,脉冲的占空比值
unsigned char direction_flag=0;
int temp_counter=0,temp_counter1=0,temp_counter2=0,temp1=0;
float temp2=0;
float  n_feed=0,pulse_counter=0;    //必须双精度数
float  adc_comp=0;                  //必须双精度数
extern int process_point, set_point,dead_band;  
extern float p_gain, i_gain, d_gain, integral_val,new_integ,result; 
extern    struct _pid warm,*pid; 
extern unsigned int sci_buff[2];

struct _Speed_pid  speed_pid;
struct _Current_pid current_pid; 
int u=0;

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

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


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

main()
{
   disable();                                   //中断屏蔽
   sytem_init();                                //系统时钟建立
   spi_init();                                  //SPI初始化
   io_init();                                   //I/O口初始化
   var_init();                                  //变量初始化
   ev_init();                                   //事件管理器初始化
   sci_init();                                  //串口初始化
   adc_init();
   
   current_counter = CUR_COUNTER_CON;           //电流PI循环次数
   speed_counter = SPEED_COUNTER_CON;           //速度PI循环次数
   
   *T1CON = *T1CON | 0x0040;   					//开启定时器1 
   enable();                                    //中断使能
   
   *ADCTRL2 = 0x2000;                           //软件启动ADC

   while(1)
   {
   }
}


/* ================================================================= */
/* 速度调节器变量装载子程序 */
void speed_pid_ini(void)
{ 
   p_gain = speed_pid.SPEED_KP_CON;
   i_gain = speed_pid.SPEED_KI_CON;
   d_gain = speed_pid.SPEED_KD_CON;
   dead_band = speed_pid.SPEED_DEAD_BAND;
   integral_val = speed_pid.SPEED_INTER_VAR;  
}

/* ================================================================= */
/* 电流调节器变量装载子程序 */
void cur_pid_ini(void)
{  
   p_gain = current_pid.CUR_KP_CON;
   i_gain = current_pid.CUR_KI_CON;
   d_gain = current_pid.CUR_KD_CON;
   dead_band = current_pid.CUR_DEAD_BAND;
   integral_val = current_pid.CUR_INTER_VAR;  
}

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

   adc_ia = *RESULT0 >> 6;   					//是周期中断,电流采样
   adc_ia += adc_ia_ref;     					//修正电流参数
   adc_comp = (float)adc_ia-512;            

   *ADCTRL2 = 0x4000;                               //ADC指针复位
   *ADCTRL2 = 0x2000;                               //软件立即启动ADC
}

/* ==================================================================*/
/* 定时器1周期中断子程序 */
void interrupt t1_perint()        				   //定时器1周期中断----测试用
{
   WORD flag;
   int temp_value;
   KICK_DOG;
   cur_sample();    
   
   speed_counter--; 
   if (speed_counter ==0)
   {
      temp_counter1 = *T2CNT;
      temp_counter=temp_counter1-temp_counter2;
      temp_counter2=temp_counter1;
      //*T2CNT = 0;
      pulse_counter = (float)temp_counter;       
      n_feed = pulse_counter*1000*60/4096;         //计算反馈的转速
     
      }
      
/*   u++;
   if(u>100)
   {
   *SCITXBUF=((int)(adc_comp))>>8;
   u=0;
   }*/
   if (speed_pid.n_ref >=0) direction_flag=0;      //正转标志
   else if (speed_pid.n_ref <0) direction_flag=1;  //反转标志   
    
   flag = *EVAIFRA & 0x0080;
   if (flag != 0x0080)            				   //如果不是周期中断,退出
   {
      enable();
      return;     
   }   
   
   temp_value=(sci_buff[0]*256)+sci_buff[1];       //串口发送的值
   speed_pid.n_ref = (float)temp_value;            //速度给定值




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

   //speed_counter--; 
   if (speed_counter==0)
   {
      //temp_counter1 = *T2CNT;
     // temp_counter=temp_counter1-temp_counter2;
     // temp_counter2=temp_counter1;
     
     // pulse_counter = (float)temp_counter;       
     // n_feed = pulse_counter*1000*60/4096;         //计算反馈的转速
       speed_counter = SPEED_COUNTER_CON;          //赋初值
     
                     //脉冲计数变量清0
      
      
      speed_pid_ini();                          //速度调节器初始化
      pid_tune(&warm, p_gain,i_gain,d_gain,dead_band); 
       
      process_point = n_feed;        
      set_point = speed_pid.n_ref;
      pid_init(&warm, process_point, set_point); 
      
//      pid_setinteg(&warm,0.0);                  //pid_setinteg(&warm,30.0);
      pid_bumpless(&warm);      
               
      pid_calc(&warm);
      speed_pid.speed_pid_out = result;
      
      if ( direction_flag ==0)    //正转
      {
         if(speed_pid.speed_pid_out > 500) speed_pid.speed_pid_out = 500;
         else if (speed_pid.speed_pid_out < 0) speed_pid.speed_pid_out = 0;
      }

      else if ( direction_flag ==1)  //反转
      {
         if(speed_pid.speed_pid_out >0) speed_pid.speed_pid_out = 0;
         else if (speed_pid.speed_pid_out < -500) speed_pid.speed_pid_out = -500;
      }
     
//      speed_pid.n_feedback = n_feed; 
//      temp_speed_out = speed_pid.speed_pid_out;
       
       
            
      
//      *CMPR1 = 500-speed_pid.speed_pid_out;           //更新占空比
//      *CMPR2 = 500-speed_pid.speed_pid_out;
   }

//----------------- 速度计算PID调节部分结束   -----------------------  

/*--------------- 电流采样PID调节部分开始   ------------------------ */ 

   current_counter--; 
   if (1)
   {
      current_counter = CUR_COUNTER_CON;           //赋初值
                                  //电流采样计算
   
      cur_pid_ini();                               //电流调节器参数初始化
      pid_tune(&warm, p_gain,i_gain,d_gain,dead_band);  
//      set_point =speed_pid.n_ref; 
      process_point = adc_comp;  
      set_point = speed_pid.speed_pid_out;

      pid_init(&warm, process_point, set_point);
   
//   pid_setinteg(&warm,0.0);                     
      pid_bumpless(&warm);
   
      pid_calc(&warm);
      current_pid.cur_pid_out = result;
   
      if (direction_flag == 0)            //正转
      {
         if(current_pid.cur_pid_out > 500) current_pid.cur_pid_out = 500;
         if (current_pid.cur_pid_out < 0) current_pid.cur_pid_out = 0;
      }
      else if (direction_flag ==1)        //反转
      {
         if (current_pid.cur_pid_out > 0) current_pid.cur_pid_out = 0;
         if (current_pid.cur_pid_out <- 500) current_pid.cur_pid_out = -500;    
      }
   
//   current_pid.cur_feedback = adc_comp;        //电流反馈值
      

       temp1=current_pid.cur_pid_out;
       if (current_pid.cur_pid_out>=0)
       {
        temp2=(current_pid.cur_pid_out-temp1)+temp2;
        if(temp2>1)
        {
        current_pid.cur_pid_out=current_pid.cur_pid_out-1;
        temp2=temp2-1;
        }
       }
       else 
       {
        temp2=temp1-current_pid.cur_pid_out+temp2;
        if(temp2>1)
        {
        current_pid.cur_pid_out=current_pid.cur_pid_out-1;
        temp2=temp2-1;;
        }
       }
       
      *CMPR1 = 500-current_pid.cur_pid_out;           //更新占空比
      *CMPR2 = 500-current_pid.cur_pid_out;
     
 } 

//--------------- 电流采样PID调节部分结束  -------------------------    

//   data_save_dram();                            //数据保存至双口RAM中    
//   led_shine();                                 //闪灯子程序,作测试用!!!

   *EVAIFRA = 0X0080;   				//清中断标志,以进行下次中断
   enable();
   return;
}

/* =================================================================== */
/* 空中断子程序 */

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


/* =================================================================== */
/* 变量初始化子程序 */
void var_init(void)                          
{
  
   speed_pid.n_ref = 0;
   speed_pid.n_feedback = 0;
   capt = 0;
   current_pid.cur_pid_out = 0;
   p_gain = (float)0;
   i_gain = (float)0;
   d_gain = (float)0;
   integral_val = (float)0;
   new_integ = 0;    
//   speed_pid.SPEED_KP_CON = (float) 0.15;
//   speed_pid.SPEED_KI_CON = (float) 0.0003;
   speed_pid.SPEED_KP_CON = (float) 0.1;
   speed_pid.SPEED_KI_CON = (float) 0.01;
   speed_pid.SPEED_KD_CON = (float) 0.18;
   speed_pid.SPEED_INTER_VAR = (float) 0.01;
   speed_pid.SPEED_DEAD_BAND = 0;
   speed_pid.SPEED_PID_OUT_MAX_CON = 0X0080;
   speed_pid.SPEED_PID_OUT_MIN_CON = 0XFF80;


   current_pid.CUR_KP_CON = (float) 0.1; 
   current_pid.CUR_KI_CON = (float) 0.0003;
   current_pid.CUR_KD_CON = (float) 0.18; 
//   current_pid.CUR_KP_CON = (float) 0.15;
//   current_pid.CUR_KI_CON = (float) 0.0003;
//   current_pid.CUR_KD_CON = (float) 0.18;    
   current_pid.CUR_INTER_VAR = (float) 0.01;
   current_pid.CUR_DEAD_BAND = 0;
   current_pid.CUR_PID_OUT_MAX_CON = 0X4B0;
   current_pid.CUR_PID_OUT_MIN_CON =0XFB50;   
   
}

/* ==================================================================== */
/* 闪灯子程序,测试用!!!! */
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 + -