STM32
直播中

无厘头

13年用户 546经验值
擅长:基础元器件
私信 关注
[问答]

TB5128 + Arduino UNO如何控制步进电机?

TB5128 + Arduino UNO如何控制步进电机?

回帖(1)

乔占宽

2021-12-22 15:24:26
关于TB5128 步进驱动芯片:
1. 概述
    TB5128 是一种采用 PWM 斩波的两相双极步进电机驱动器。内置时钟解码器。
    本驱动器采用 BiCD 工艺制造,额定输出为 50 V/5.0 A(电机电源电压 = 44 V)。
2. 特点
 BiCD 工艺集成式单片 IC。
 可控一台双极步进电机。
 由 PWM 控制的恒流驱动。
 低导通电阻(高压侧+低压侧 = 0.25Ω(典型值))
 MOSFET 输出级。
 允许全步、半步、四分之一步、1/8 步、1/16 步、1/32 步、1/64 步、1/128步
 高效电机电流控制机构(ADMD:高级动态混合衰减)
 内置无电流检测电阻威廉希尔官方网站 控制结构(ACDS:高级电流检测系统)
 高电压和电流(有关规格请参考绝对最大额定功率和工作范围)
 多故障检测功能(热关断(TSD)、过流保护(ISD)、上电复位(POR 故障检测(TSD / ISD / OPD)信号输出功能
 内置 VCC 调节器供内部威廉希尔官方网站 使用
 通过外部电阻和电容可以调节电机的斩波频率。
 带有散热焊盘的小型封装
    TB5128:P-VQFN48-0707-0.50-004
详细文档可以网络搜索……  


                                                                                        ( 图1)
        本次测试目的,是Arduino UNO与TB5128扩展板的基本操作。实现自动循环正反转,根据脉冲数量来控制电机转动的角度。每次填充的脉冲数量计数完毕,程序中会自动切换方向,然后再次填充同样数量的脉冲。程序中,细分和衰减都有相应的函数去设置,方便调用。脉冲是通过软件定时,取反IO实现。脉冲频率的调整,可以在宏(CLK_F)中修改对应的数值。注意,因为没有加减速,所以在低细分数时,频率不要太高了。一般转速在1转/秒左右,基本可以正常转动。再快的就要看电机的高频特性、驱动电压和负载情况了。另外TB5128的报警输出和Mo的端口还没在程序中实现检测……
        图1中亮着的绿色的LED灯,是在电机转动时才会亮,电机停止转动时,会自动熄灭。TB5128的细分、衰减、ST、TQ这几个功能都是用74HC595去扩展IO控制的,每次需要改变其中任何一个功能设置时,都要调用hc595Write(data);这样才会刷新输出,改变各档功能的设置状态。在电机停止过程中,电机电流会自动调整为半流输出(通过调整TQ(TORQE)端实现,也可以改变VREF电压来实现自动调整锁相电流功能)。在参数更新后,脉冲准备输出前,会先恢复成设置的工作电流,然后会进入下一个循环。
拔码开关SW设置功能:(默认设置成全低)


  • GAIN_SEL(放大比例选择,可以选择5或10,对应电流计算公式:IO=VREF / GAIN / RS采样电阻)
  • EDG_SEL(触发边沿选择,CLK是上升沿触发或者选择双边沿触发)
  • IF_SEL(设置控制模式,本测试中是CLK模式,就是脉冲和方向直接控制,另外还有串行控制模式,待续)

其它设置:图1标记有VREF字样处的插针(SEL4),是用来选择外部电阻分压生成VREF或者是UNO板输出PWM通过RC滤波生成VREF电压。 RS_SEL(板背面,用来设置采样模式)是通过短路焊点设置为外部采样模式。其它如: SEL2、SEL3都由UNO板控制。TE1(对应SEL1,设置TB5128的RESET)也是在板上短路为UNO控制。
        其中UNO5128.c文件完全与UNO5128.ino文件一样,复制成C文件格式,方便没有装Arduino软件的网友也能直接打开查看。HC595.h并不是单纯的头文件,包括595控制的相关函数都在里面

第一折腾Arduino UNO,虽然已经在板上测试过,但是程序可能存在不完善的地方……


代码部分:



#include "UNO5128.h"
#include "HC595.h"


/*  驱动步进电机时,没有加减速控制,启动频率过调时可能会出现在启动时堵转,只听见电机有高频噪音而不转动 */
#define  CLK_F  200  // 用来延时生成输出脉冲,数字越大,频率相对越低。大于8细分时,可以用100以上的数字,小于8细分,建议大于400


unsigned char  a = 0;      // 用于自动换向的标志位
unsigned int   c = 0;      // 设定输出的脉冲数量


void PIN_INIT()
{
    pinMode(EN,OUTPUT);         // Enable
    pinMode(CLK,OUTPUT);        // Step
    pinMode(DIR,OUTPUT);        // Dir

    pinMode(PWMVREF,OUTPUT);    //  PWM=>RC滤波生成VREF
    pinMode(RES5128,OUTPUT);    //  TB5128复位引脚
    pinMode(RUN_ON,OUTPUT);     //  运行状态指示,外接LED
     
    pinMode(MO,INPUT);          // TB5128   
    pinMode(L0,INPUT);          // TB5128   
    pinMode(L1,INPUT);          // TB5128   

    digitalWrite(EN,LOW);       // Set Enable LOW //关闭TB5128的功率级输出
    digitalWrite(DIR,HIGH);     // Set DIR HIGH      RUN_ON
    digitalWrite(CLK,LOW);      // Set CLK LOW

    digitalWrite(RES5128,HIGH);  // TB5128 复位脚拉高
    TCCR1B=TCCR1B & B11111000 | 0x01 ; //修改定时器1分频比,PWM模块默认64分频 //提高PWMVREF的频率
}

void HC595_INIT()
{
    pinMode(DS,OUTPUT);         // DS引脚为74HC595串行输入引脚,即 DATA 输出端
    pinMode(HCP,OUTPUT);        // SHCP引脚为时钟引脚
    pinMode(TCP,OUTPUT);        // STCP引脚为锁存引脚   

    digitalWrite(TCP,HIGH);      // Set Enable HIGH
    digitalWrite(HCP,LOW);       // Set CLK LOW   

    smdmode(4);    // 设置衰减, 共4档衰减可调整 // 1=37.5% 快衰减, 2=50% 快衰减, 3=100% 快衰减, 4 = ADMD(智能衰减)
    TQ_LOW;                 //  输出电流为设定值的 100%   // TQ_HIGH;     //  50% 的设定电流
    microStep(8);           //  设置8细分
    ST_HIGH;                //  工作状态,TB5128正常输出   // ST_LOW;      //  待机状态
    hc595Write(data_595);   //  把数据写入到HC595            
}

void setup()                    // put your setup code here, to run once:
{                  
    PIN_INIT();      
    HC595_INIT();

    delay(10);                  // 10mS延时
    digitalWrite(RES5128,LOW);  // TB5128的RESET=0,进入工作状态 RES5128
    analogWrite(PWMVREF,60);    // 设定TB5128的VREF电压,调整输出电流 // PWM通过RC滤波生成VREF电压
// TB5128的VREF=PWM =>R->C->R->C==VREF= 19.53*60=1.1V左右,8位的PWM,5V的幅值,5000/256=19.53 //误差与5.000V的精度有关系
}

void loop()    // put your main code here, to run repeatedly:
{  
    if(c>0)                        // 通过软件延时来取反端口电平,实现脉冲输出
    {        
        digitalWrite(RUN_ON,LOW);  // 开启LED指示灯                         // 2a
        digitalWrite(CLK,HIGH);
        delayMicroseconds(CLK_F);  // 适合8细分或更高细分 转动 // 参考宏定义说明
        digitalWrite(CLK,LOW);
        delayMicroseconds(CLK_F);  // CLK_F 延时值的大于影响输出脉冲的频率
        c--;                       // 每次计数,CLK端输出一个完整的脉冲
        digitalWrite(RUN_ON,HIGH); // 关闭LED指示灯                         // 2a
    }
    else  // c = 20480;              // 输出脉冲数量达到设定值后,重新设定脉冲数量,并改变电机方向
    {
        c = 32000;                 // C=(200*M)*N; M为设定的细分数,括号内是每圈的脉冲数量。 N=转动的圈数
        if(a>0)
        {
            a=0x00;
            digitalWrite(EN,LOW);     // 非必要操作 // EN端清零,关闭TB5128功率级 //会影响电机锁相,进入脱机状态
            digitalWrite(DIR,HIGH);   // 切换电机转动方向
            delayMicroseconds(5);     // 改变方向后,延时一段时间再发脉冲
            digitalWrite(EN,HIGH);    // Set Enable HIGH  // 开启TB5128功率输出 // *
        //digitalWrite(RUN_ON,HIGH); //  关闭LED指示灯                         // 1a
            TQ_HIGH;                  //  50% 的设定电流
            hc595Write(data_595);     // 把数据写入到HC595 // 数据更改后,必须要调用hc595Write(data_595)来刷新输出
            delay(2000);              // 半流锁相2秒左右 // 方便观察电源端电流的变化
            TQ_LOW;                   // 输出电流为设定值的 100%  // 恢复设定电流输出
            hc595Write(data_595);     // 把数据写入到HC595
        //digitalWrite(RUN_ON,LOW); //  开启LED指示灯                         // 1a
        }
        else
        {
            a=0x01;
            digitalWrite(EN,LOW);     // 非必要操作 // EN端清零,关闭TB5128功率级 //会影响电机锁相,进入脱机状态
            digitalWrite(DIR,LOW);    // 切换电机转动方向
            delayMicroseconds(5);     // 改变方向后,延时一段时间再发脉冲
            digitalWrite(EN,HIGH);    // Set Enable HIGH  // 开启TB5128功率输出  // *   
        //digitalWrite(RUN_ON,HIGH); // 关闭LED指示灯                          // 1a  
            TQ_HIGH;                  // 50% 的设定电流
            hc595Write(data_595);     // 把数据写入到HC595
            delay(2000);              // 半流锁相2秒左右 // 方便观察电源端电流的变化
            TQ_LOW;                   // 输出电流为设定值的 100%  // 恢复设定电流输出
            hc595Write(data_595);     // 把数据写入到HC595   
        //digitalWrite(RUN_ON,LOW); //  开启LED指示灯                          // 1a
        }
    }   
}
/*
* 控制主板: Arduino UNO
* 驱动板 : TB5128 步进驱动芯片(匹配UNO的驱动模块)  NO.1 (2019-09-11)
*
* 部分函数和端口功能控制说明(函数在HC595.h 文件)
*
* microStep(step):
*     设置TB5128细分数的函数, step=细分数, 需要用到什么细分就写入对应的数字, 函数中自动设置对应状态输出
*     
* smdmode(fdt):  
*     设置衰减的函数, fdt有4档 // 1=37.5% 快衰减 // 2=50% 快衰减 // 3=100% 快衰减 // 4 = ADMD(智能衰减)
*     
*     TQ_HIGH; 对应TORQE = HIGH;   // TQ_LOW; 对应TORQE = LOW   // 宏定义中已对应
*     ST_HIGH; 对应STANDBY = HIGH; // ST_LOW; 对应STANDBY = LOW // 宏定义中已对应
*     
*     1.8度的电机,整步转一圈需要的脉冲数= 360/1.8 = 200个脉冲
*     8细分时转一圈需要的脉冲数= 200 * 8=1600个脉冲,当脉冲频率=1.6KHZ时,速度=每秒转一圈
*     
*     RES5128 控制TB5128的RESET引脚 , 由UNO板直接控制   
*     
*     PWMVREF 用来调整VREF,用到定时器1的PWM ,通过RC滤波生成直流电压,从而设定TB5128的输出电流
*     TCCR1B=TCCR1B & B11111000 | 0x01 ; //修改定时器1分频比,PWM模块默认64分频 //提高PWMVREF的频率
*     
*     输出电流IO= VREF / GAIN / RS(采样电阻的阻值) // GAIN可以在板上通过拔码开关设定为10或者5,外部设定
*/


HC595.h 部分,关于HC595的控制相关(主要是用函数设置TB5128的细分和衰减方式)


#ifndef _HC595_h_
#define _HC595_h_

#include "UNO5128.h"
//#include


#define  HCP   5   //  74HC595  SHCP引脚为时钟引脚
#define  TCP   6   //  74HC595  STCP引脚为锁存引脚
#define  DS    7   //  74HC595  DS引脚为串行输入引脚
/* 74HC595D的输出用来设置TB5128的细分和衰减, 待机端和TQ端 可选择595设置或者外部开关设置*/

byte data_595 = 0;   //  保存设定的 细分数 + 衰减方式 + ST + TQ ,用来刷新74HC595的输出状态

#define ST_HIGH data_595 |=0x02  // ST端口为高  芯片进入待机状态          // 0xFF // data_595 第1位 是控制TB5128的 ST端   
#define ST_LOW  data_595 &=0xFC  // ST端口为低  芯片进入待机状态          // 0xFD // data_595 第1位 是控制TB5128的 ST端
#define TQ_HIGH data_595 |=0x20  // TQ端口为高 输出电流为设定值的 50%    // 0xFF // data_595 第5位是控制TB5128的 TORQE端
#define TQ_LOW  data_595 &=0xDF  // TQ端口为低, 输出电流为设定值的 100%  // 0xDF // data_595 第5位是控制TB5128的 TORQE端


void hc595Write(unsigned char data)           // 刷新HC595的数据
{
    for (unsigned char i = 0; i < 8; i++)
    {
        digitalWrite(TCP, LOW);               // 将ST_CP口上加低电平让芯片准备好接收数据
        shiftOut(DS, HCP, MSBFIRST, data);    // shiftOut() 串行移位函数  MSBFIRST(数据高位在前)、LSBFIRST(数据低位在前)
        digitalWrite(TCP, HIGH);              // 将ST_CP这个针脚恢复到高电平
        delayMicroseconds(1);                 //  
    }   
}

void microStep(unsigned char M)     //  设置细分数
{                                   
    data_595 = data_595 | 0x1C;     //  把设置细分的位全部置1 // B000 111 00; // =0x1C;
   
    switch(M)      //  micro_step = 0b111 SSS 11; 其中 S S S 位是设置细分数, 0b111 M0 M1 M2 11; // 2,3,4设置细分数
    {
        case   1:  data_595 &= 0xE3; break;    // B11100011;  break;  // 1   细分      B111 000 11;  // 0xE3
        case   2:  data_595 &= 0xF3; break;    // B11110011;  break;  // 2   细分      B111 100 11;  // 0xF3
        case   4:  data_595 &= 0xEB; break;    // B11101011;  break;  // 4   细分      B111 010 11;  // 0xEB
        case   8:  data_595 &= 0xFB; break;    // B11111011;  break;  // 8   细分      B111 110 11;  // 0xFB
        case  16:  data_595 &= 0xE7; break;    // B11100111;  break;  // 16  细分      B111 001 11;  // 0xE7
        case  32:  data_595 &= 0xF7; break;    // B11110111;  break;  // 32  细分      B111 101 11;  // 0xF7
        case  64:  data_595 &= 0xEF; break;    // B11101111;  break;  // 64  细分      B111 011 11;  // 0xEF
        case 128:  data_595 &= 0xFF; break;    // B11111111;  break;  // 128 细分      B111 111 11;  // 0xFF
        default:                     break;
    }
}

void smdmode(unsigned char FDT)    //  6,7位是衰减设置     
{
    data_595 = data_595 | 0xC0;   //  把设置细分的位全部置1 // B11 000000;  // = 0xC0;

    switch(FDT)                             //  fdt_set = 0bTT111111;其中 T T 位是设置衰减模式, 0bFDT0 FDT1 111111;
    {
        case 1: data_595 &= 0x3F;  break;   // fdt = B00111111;  break;  // 37.5%  快衰减       // 0x3F        
        case 2: data_595 &= 0xBF;  break;   // fdt = B10111111;  break;  // 50%    快衰减       // 0xBF                       
        case 3: data_595 &= 0x7F;  break;   // fdt = B01111111;  break;  // 100%   快衰减   // 0x7F                  
        case 4: data_595 &= 0xFF;  break;   // fdt = B11111111;  break;  // ADMD   智能衰减 // 0xFF                       
        default:            break;
    }
}

#endif
/*
*
* 用途: Arduino UNO 通过74HC595扩展 IO端口输出
*
* 74HC595 输出端口对应变量 data_595 :
*
* B  7bit  6bit   5bit  4bit    3bit    2bit    1bit     0bit
*
* B  FDT0  FDT1  TORQE  MODE0  MMODE1  MMODE2  STANDBY   X(NC)  
*  
*    //  MODE0 = M0;  MMODE1 = M1;  MMODE2 = M2;  // STANDBY = ST;
*/





剩下UNO5128.h


#ifndef _UNO5128_h_
#define _UNO5128_h_


#define L0       2   //  TB5128 LO0 芯片内部报警端
#define L1       3   //  TB5128 LO1 芯片内部报警端
#define MO       4   //  TB5128 MO  芯片状态指示输出,根据输入脉冲数来反馈

//#define BANK_EN  8   //  串行模式时为BANK_EN端
#define RES5128  8   //  并行控制时是TB5128的复位脚
#define PWMVREF  9   //  可选择用PWM通过RC滤波生成TB5128的VREF电压,从而设定驱动输出电流


#define EN      10   //  TB5128 EN   控制使能
#define CLK     11   //  TB5128 CLK  输出脉冲
#define DIR     12   //  TB5128 DIR  控制方向

#define RUN_ON  A2   //  运行状态指示

#define VREFIN  A0
#define KEYIN   A1  // KEY IN  按键值输入检测,用来确认触发的按键


#endif
/*
* 控制主板: Arduino UNO
* 驱动板 : TB5128 步进驱动芯片(匹配UNO的驱动模块)
*         
* TB5128参数:  1~128细分,7~40V工作电压范围,芯片峰值电流5A,本模块工作电流1.2A以内,参数可调
*
* 其它芯片: 74HC595。串转并输出。用于TB5128的细分设置端口、衰减设置端口、ST端号和TORQE端号的扩展控制
*
* 在驱动模块上,TB5128的ST端、TORQE端可以由板上的拔动开关设置。 RESET端和VREF端可通过UNO来控制,由拔动开关选择外部控制或者UNO控制。
*
* 其它功能: UNO的 串口 单独引出针座。 另外IIC端口+2个ADC端口+逻辑电源 通过一个6位针座引出,方便外部ADC按键和显示的使用
*/


带电机测试图(实现自动循环正反转)






程序部分已经全部开源,相关威廉希尔官方网站 板资料方面,请网络搜索TB5128……
TB5128匹配UNO接口的威廉希尔官方网站 图


举报

更多回帖

发帖
×
20
完善资料,
赚取积分