步进电机使用总结

步进电机使用总结

1、步进电机励磁顺序

 步进电机使用总结_第1张图片

2、驱动电路

步进电机使用总结_第2张图片

 

 

3、步进电机驱动芯片

UPA1759G 为NMOS。

步进电机使用总结_第3张图片

4、需要注意的几点:

       1) 我们使用的步进电机 800pps为最佳。

       2) 使用定时器定时880pps即1250us执行一拍

3) 步进电机为共阳极,驱动器为NMOS的UPA1759G。软件处理时需要反向驱动处理

       4) 步进电机的执行一次尽量整步(8拍的倍数)执行

       5) 步进电机正反向转动时,不应清除当前8拍计数值,而是进行正向加,反向减。

 

5、步进电机驱动程序

/**********************************************************************

* step_motor.c

* 步进电机执行模块

*  模块功能:按照调用执行相应步进电机的相应步数

*                                保存各个步进电机当前的状态(当前所走步数、是否达到目标位置)

*********************************************************************/

#include

#include

#include

 

/**********需要修改的部分 start******************************************************/

// 步进电机旋转方向

#define VALVE_ONE_MOTOR_POS_AS_CLOCK_WISE 1

#define VALVE_TWO_MOTOR_POS_AS_CLOCK_WISE 0

#define NOZZLE_MOTOR_POS_AS_CLOCK_WISE 0

 

#define HIGH        1  // 表示高低电平

#define LOW         0

 

/**********需要修改的部分 end******************************************************/

#define MOTOR_INTERVAL_US 1250 // 1300 //500 // 370 // 700 // 1300     // 步进电机每步间隔时间 64us的整数倍1280us

 

/* 步进电机时序 */

static const uint8 _pos_mode[8] ={0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01}; // positive eightbeat

static const uint8 _neg_mode[8] ={0x01,0x03,0x02,0x06,0x04,0x0C,0x08,0x09};   // negative eightbeat

  

#if(VALVE_ONE_MOTOR_POS_AS_CLOCK_WISE == 1)

static const uint8 *valve_one_motor_pos=  _pos_mode;

#else

static const uint8 *valve_one_motor_pos=  _neg_mode;

#endif

 

 

#if(VALVE_TWO_MOTOR_POS_AS_CLOCK_WISE == 1)

static const uint8 *valve_two_motor_pos=  _pos_mode;

#else

static const uint8 *valve_two_motor_pos=  _neg_mode;

#endif

 

#if(NOZZLE_MOTOR_POS_AS_CLOCK_WISE == 1)

static const uint8 *nozzle_motor_pos =  _pos_mode;

#else

static const uint8 *nozzle_motor_pos =  _neg_mode;

#endif

 

/*******************************************************************************************/

//让外部检测步进电机是否已经达到目标位置

struct _motors_ok

{

       unsignedvalve_one_motor_ok: 1;

       unsignedvalve_two_motor_ok: 1;

       unsignednozzle_motor_ok:   1;

};

 

static struct _motors_ok motors = {

       1,

       1,

       1,

};

 

uint8 is_valve_one_motor_ok(void)

{

       returnmotors.valve_one_motor_ok;

}

 

uint8 is_valve_two_motor_ok(void)

{

       returnmotors.valve_two_motor_ok;

}

 

uint8 is_nozzle_motor_ok(void)

{

       returnmotors.nozzle_motor_ok;

}

 

static void waiting_for_motors_ok(void)

{

       overlay    uint8 i = 0;

       while(!motors.valve_one_motor_ok||

                            !motors.valve_two_motor_ok||

                                   !motors.nozzle_motor_ok)

              for(i= 0; i < 200; i++) feed_wdt();

}

/*******************************************************************************************/

 

/*******************************************************************************************/

// 实时记录每个步进电机的步数和拍数

static int16 valve_one_motor_current   = 0;

static int16 valve_one_motor_target    = 0;

static uint8 valve_one_motor_step_count     = 0;

 

static int16 valve_two_motor_current = 0;

static int16 valve_two_motor_target    = 0;

static uint8 valve_two_motor_step_count    = 0;

 

static int16 nozzle_motor_current               = 0;

static int16 nozzle_motor_target                =0;

static uint8 nozzle_motor_step_count   = 0;

 

/**************************************************************************************/

void valve_one_motor_begin(int16 target)

{

//     if(target== 0) // 退回到原位, 那么需要多退回一点

       //     target = -100;

               

       interrupt_disable();

       valve_one_motor_target       = target;

//     valve_one_motor_step_count= 0;

       motors.valve_one_motor_ok               = 0;

      

       if(valve_one_motor_current< 0) {

              valve_one_motor_current= 0;

       }    

       interrupt_enable();

       VALVE_ONE_MOTOR_IOS_OUTPUT;

      

//     open_timer_4(MOTOR_INTERVAL_US,1,1,1);

       open_timer_4(MOTOR_INTERVAL_US,1,0,1);

}

 

static void valve_one_motor_ok_end(void)

{

       VALVE_ONE_MOTOR_IOS_OUTPUT;

       VALVE_ONE_MOTOR_1(LOW);

       VALVE_ONE_MOTOR_2(LOW);

       VALVE_ONE_MOTOR_3(LOW);

       VALVE_ONE_MOTOR_4(LOW);

      

       if(valve_one_motor_current< 0) {

              valve_one_motor_current= 0;

              valve_one_motor_target= 0;

       }

      

       motors.valve_one_motor_ok= 1;

}

/**************************************************************************************/

void valve_two_motor_begin(int16 target)

{

       interrupt_disable();

       valve_two_motor_target       = target;

//     valve_two_motor_step_count= 0;

       motors.valve_two_motor_ok        = 0;

       if(valve_two_motor_current< 0) {

              valve_two_motor_current= 0;

       }

      

       interrupt_enable(); 

       VALVE_TWO_MOTOR_IOS_OUTPUT;

//     open_timer_4(MOTOR_INTERVAL_US,1,1,1);

       open_timer_4(MOTOR_INTERVAL_US,1,0,1);

}

 

static void valve_two_motor_ok_end(void)

{

       VALVE_TWO_MOTOR_IOS_OUTPUT;

      

       VALVE_TWO_MOTOR_4(LOW);

       VALVE_TWO_MOTOR_3(LOW);

       VALVE_TWO_MOTOR_2(LOW);

       VALVE_TWO_MOTOR_1(LOW);

             

       if(valve_two_motor_current< 0) {

              valve_two_motor_current= 0;

              valve_two_motor_target= 0;

       }    

       motors.valve_two_motor_ok= 1;

}

 

/**************************************************************************************/

void nozzle_motor_begin(int16 target)

{

       interrupt_disable();

       nozzle_motor_target     = target;

//     nozzle_motor_step_count= 0;

       motors.nozzle_motor_ok              = 0;

       if(nozzle_motor_current< 0) {

              nozzle_motor_current= 0;

       }

      

       interrupt_enable(); 

       NOZZLE_MOTOR_IOS_OUTPUT;

//     open_timer_4(MOTOR_INTERVAL_US,1,1,1);

       open_timer_4(MOTOR_INTERVAL_US,1,0,1);

}

 

static void nozzle_motor_ok_end(void)

{

       NOZZLE_MOTOR_IOS_OUTPUT;

       NOZZLE_MOTOR_4(LOW);

       NOZZLE_MOTOR_3(LOW);

       NOZZLE_MOTOR_2(LOW);

       NOZZLE_MOTOR_1(LOW);

             

       if(nozzle_motor_current< 0) {

              nozzle_motor_current= 0;

              nozzle_motor_target= 0;

       }    

       motors.nozzle_motor_ok= 1;

}

 

uint16 nozzle_motor_position(void)

{

       if(nozzle_motor_current< 0)

              return0;

       else

              return(uint16)nozzle_motor_current;

}

 

/**************************************************************************************/

//  换向阀速度比喷管速度快,大约换向阀的电机每拍750us, 喷管电机每拍1100US

static union __timer{

       struct  {

              unsignedcounter_0: 1;

              unsignedcounter_1: 2;

       };

       uint8counter;

}timer;

 

// 步进电机中断函数

void step_motors_intr_func(void)

{

/*    staticuint8 *rotation_mode_valve_one = 0;

       staticuint8 *rotation_mode_valve_two = 0;

       staticuint8 *rotation_mode_nozzle = 0;

*/

       timer.counter++;

      

       //三个换向阀 位置都到达了目标位置,停止定时器

       if(valve_one_motor_target == valve_one_motor_current &&

              valve_two_motor_target== valve_two_motor_current &&

              nozzle_motor_target== nozzle_motor_current) {

                                  

              valve_one_motor_ok_end();

              valve_two_motor_ok_end();

              nozzle_motor_ok_end();

              close_timer_4();

 

       }else {

       //     if(timer.counter_0 == 0) {

                     //换向阀1目标位置与当前位置不相等

                     if(valve_one_motor_target != valve_one_motor_current) {                           

                           

       //                   overlay uint8*rotation_mode_valve_one = (uint8 *)valve_one_motor_pos;

       //                   rotation_mode_valve_one =(uint8 *)valve_one_motor_pos;

                    

       //                   interrupt_disable();

                    

                            //正向转             

                            if(valve_one_motor_target< valve_one_motor_current)

                            {

       //                          rotation_mode_valve_one= (uint8 *)valve_one_motor_neg;

                                   valve_one_motor_current--;

 

                                   if(valve_one_motor_step_count> 0) {

                                          valve_one_motor_step_count--;

                                   } else {

                                          valve_one_motor_step_count= 7;

                                   }

                                  

                            }else {

                                   valve_one_motor_current++;

 

                                   if(valve_one_motor_step_count< 7) {

                                          valve_one_motor_step_count++;

                                   }else {

                                          valve_one_motor_step_count= 0;

                                   }

                            }

                           

                           

                            if(valve_one_motor_step_count  < 8) {

                                   VALVE_ONE_MOTOR_1((valve_one_motor_pos[valve_one_motor_step_count] & 0x01));

                                   VALVE_ONE_MOTOR_2(((valve_one_motor_pos[valve_one_motor_step_count]& 0x02) >> 1));

                                   VALVE_ONE_MOTOR_3(((valve_one_motor_pos[valve_one_motor_step_count]& 0x04) >> 2));

                                   VALVE_ONE_MOTOR_4(((valve_one_motor_pos[valve_one_motor_step_count]& 0x08) >> 3));

                                                                                   

                            }

                           

              //            interrupt_enable();

                           

                     }else {

                            valve_one_motor_ok_end();

                     }

       //     }

             

       //     if(timer.counter_0 == 0) {

                     //换向阀2目标位置与当前位置不相等

                     if(valve_two_motor_target != valve_two_motor_current) {                          

              //            rotation_mode_valve_two = (uint8*)valve_two_motor_pos;

                           

              //            interrupt_disable();

                            //正向转             

                            if(valve_two_motor_target< valve_two_motor_current)

                            {

              //                   rotation_mode_valve_two= (uint8 *)valve_two_motor_neg;

                                   valve_two_motor_current--;

                                  

                                   if(valve_two_motor_step_count> 0) {

                                          valve_two_motor_step_count--;

                                   }else {

                                          valve_two_motor_step_count= 7;

                                   }

                            }else {

                                   valve_two_motor_current++;

 

                           

 

                                   if(valve_two_motor_step_count< 7) {

                                          valve_two_motor_step_count++;

                                   }else {

                                          valve_two_motor_step_count= 0;

                                   }

                            }

                           

                            if(valve_two_motor_step_count  < 8) {

                                   VALVE_TWO_MOTOR_1((valve_two_motor_pos[valve_two_motor_step_count] & 0x01));

                                   VALVE_TWO_MOTOR_2(((valve_two_motor_pos[valve_two_motor_step_count]& 0x02) >> 1));

                                   VALVE_TWO_MOTOR_3(((valve_two_motor_pos[valve_two_motor_step_count]& 0x04) >> 2));

                                   VALVE_TWO_MOTOR_4(((valve_two_motor_pos[valve_two_motor_step_count]& 0x08) >> 3));     

                            }

                    

                           

              //            interrupt_enable();

                           

                     }else {

                            valve_two_motor_ok_end();

                     }

       //     }

             

       //     if(timer.counter_0 == 0) {    

       //     if(timer.counter == 3 || timer.counter ==6) {

                     //喷管目标位置与当前位置不相等

                     if(nozzle_motor_target != nozzle_motor_current) {                       

                     //     rotation_mode_nozzle = (uint8*)nozzle_motor_pos;

                           

                            interrupt_disable();

                            //反向转        

                            if(nozzle_motor_target

                            //     rotation_mode_nozzle= (uint8 *)nozzle_motor_neg;

                                   nozzle_motor_current--;

 

                                  

                                   if(nozzle_motor_step_count > 0){

                                          nozzle_motor_step_count--;

                                   } else {

                                          nozzle_motor_step_count =7;

                                   }

                                  

                            } else {

                                   nozzle_motor_current++;

 

                                   if(nozzle_motor_step_count < 7){

                                          nozzle_motor_step_count++;

                                   } else {

                                          nozzle_motor_step_count =0;

                                   }

 

                                  

                            }

                           

                            if (nozzle_motor_step_count < 8) {

                                   NOZZLE_MOTOR_1((nozzle_motor_pos[nozzle_motor_step_count] & 0x01));

                                   NOZZLE_MOTOR_2(((nozzle_motor_pos[nozzle_motor_step_count]& 0x02) >> 1));

                                   NOZZLE_MOTOR_3(((nozzle_motor_pos[nozzle_motor_step_count]& 0x04) >> 2));

                                   NOZZLE_MOTOR_4(((nozzle_motor_pos[nozzle_motor_step_count]& 0x08) >> 3));

                            }

                           

                            interrupt_enable();

                           

                     }else {

                            nozzle_motor_ok_end();

                     }

              }

//     }

 

 

       if(timer.counter>= 6)

              timer.counter= 0;

}

 

/**************************************************************************************/

// 初始化函数

static void step_motors_io_init(void)

{

       //io init

       //valve one step motor ios

       VALVE_ONE_MOTOR_IOS_OUTPUT;

       VALVE_ONE_MOTOR_1(LOW);

       VALVE_ONE_MOTOR_2(LOW);

       VALVE_ONE_MOTOR_3(LOW);

       VALVE_ONE_MOTOR_4(LOW);

       //valve two step motor ios   

       VALVE_TWO_MOTOR_IOS_OUTPUT;

       VALVE_TWO_MOTOR_1(LOW);

       VALVE_TWO_MOTOR_2(LOW);

       VALVE_TWO_MOTOR_3(LOW);

       VALVE_TWO_MOTOR_4(LOW);

      

       //nozzle_motor step motor ios

       NOZZLE_MOTOR_IOS_OUTPUT;

       NOZZLE_MOTOR_1(LOW);

       NOZZLE_MOTOR_2(LOW);

       NOZZLE_MOTOR_3(LOW);

       NOZZLE_MOTOR_4(LOW);

      

       valve_one_motor_current    = 4200;

       valve_one_motor_target      =4200;

       valve_one_motor_step_count = 0;

      

       valve_two_motor_current    = 4200;

       valve_two_motor_target      =4200;

       valve_two_motor_step_count      = 0;

      

       nozzle_motor_current         = 0;

       nozzle_motor_target            =0;

       nozzle_motor_step_count    = 0;

}

 

void valve_motors_init(void)

{

       overlay    uint16 i =0, j = 0;

       step_motors_io_init();

      

       valve_one_motor_begin(-100);

       valve_two_motor_begin(-100);

}

 

 

/*********************************************************/

// 初始化函数

void step_motors_module_init(void)

{

       overlay    uint16 i =0, j = 0;

      

       step_motors_io_init_1();

 //while(1){   

       nozzle_motor_begin(3000);

       valve_one_motor_begin(4200);

       valve_two_motor_begin(4200);   

       waiting_for_motors_ok();

      

       //开始电磁阀进水,水泵出水

       for(j= 0; j < 5; j++ )

              for(i= 0; i < 30000; i++)

              feed_wdt();

      

       nozzle_motor_begin(-100);

       valve_one_motor_begin(-100);

       valve_two_motor_begin(-100);

       waiting_for_motors_ok();    

       for(j=0; j < 5; j++ )

              for(i= 0; i < 30000; i++)

              feed_wdt();

 //}

}

 

/**************************************************************************************/

// FILE END

你可能感兴趣的:(STM32,LPC1788,驱动模块,单片机)