This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] DRV8711:增加步进电机的扭矩

Guru**** 2353800 points
Other Parts Discussed in Thread: ENERGIA, MSP430G2553, DRV8711
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/motor-drivers-group/motor-drivers/f/motor-drivers-forum/632748/drv8711-increasing-torque-to-stepper-motor

部件号:DRV8711
主题中讨论的其他部件: EnergiaMSP430G2553

您好,

我已经编写了驱动4安培步进电机的代码。  我正在使用具有booper-drv8711的MSP430启动板。  除了没有足够的扭矩来满足我的应用,一切都运行良好。  同一电机由同一应用中的另一电机控制器驱动,没有任何困难。  借助升压驱动器8711,我看到0.2 电流RMS被驱动到电机,但电机的电流容量为4安培。  我可以使用哪些技术来增加扭矩。  我在8711寄存器中玩过各种设置,似乎没有任何变化。  我已经复制了将我当前写入的设置写入寄存器的代码以供参考。

谢谢

马特

________________________________________________________________

#define CCC_16_Enable 0x25
#define CW_16_Enable 0x27
#define CCC_16_Disable 0x24
#define CW_16_Disable 0x26

/CTRL寄存器默认值
unsigned char CTRLdataHi,CTRLdataLo;
CTRLdataHi = 0x0F;//以前为C。 F将增益更改为40以获得更多扭矩
CTRLdataLo = CW_16_Disable;//1/16已禁用
WriteSPI (CTRLdataHi,CTRLdataLo);

//扭矩默认值
无符号字符TORQUEHi,TORQUELO;
TORQUEHi = 0x13;
TORQUELO = 0x1F;
WriteSPI (TORQUEHi,TORQUELO);

//关闭默认值
unsigned char OFFHi,OFFLo;
OFFHi = 0x20;//内部索引器
//OFFHi = 0x21;//旁路索引器
OFFLo = 0xA0;
WriteSPI (OFFHi,OFFLo);

//空白默认值
unsigned char BLNKHI, BLNKLO;
BLNKHi = 0x31;
BLNKLO = 0xF0;
WriteSPI(BLNKHI, BLNKLO);

//衰减默认值
unsigned char DECAYHi,DECAYLo;
DECAYHi = 0x41;
DECAYLo = 0x10;
WriteSPI (DECAYHi,DECAYLo);

//stall默认值
无符号字符STALLHI, STALLLO;
STALLHi = 0x53;
STALLLO = 0xFF;
WriteSPI (STALLHi,STALLLLO);

//驱动器默认值
unsigned char DRIVEHI, DRIVELo;
DRIVEHi = 0x6f;//400mA峰值接收器200mA峰值源
DRIVELO = 0x5F;
WriteSPI(DRIVEHI, DRIVELo);

//状态默认值
unsigned char STATUSHI, STATUSLO;
STATUSHi = 0x70;
STATUSLO = 0x00;
结果= WriteSPI (STATUSHi,STATUSLO);

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Matt,您好!

    您是否有使用步进针脚捕获电流波形的示波器?
    步进速率是多少?
    电流感应电阻器和系统电压是多少?

    您的设置可能不正确。 假设您没有将感应电阻从50mOhm更改为166mA,则电流应限制为约166mA。 要达到4A,应根据数据表的方程式(2)增加扭矩值并减小增益。

    例如,将ISGAIN设置为00 (增益5),将扭矩设置为0x5D (93 Decimal)。 还有其他增益和扭矩组合可以接近相同的结果。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,Rick:

    感谢您的回复。 我已经尝试过将ISGAIN和扭矩弄混。 它成功地增加了电机的扭矩,但也带来了其他几个问题。
    1.马达的移动并不总是平稳的,它似乎偶尔会出现抖动。
    2. 8711在无负载运行几秒钟后,有时会立即快速故障排除。

    很显然,从状态寄存器中了解故障原因会很有帮助,但我无法读取任何寄存器的状态。 我总是得到0的回车。 我将复制下面我用来读取寄存器状态的代码,我使用函数getCurrentRegisters。 总之,我正在寻求帮助,了解如何消除列出的新问题1和2以及/或如何读取状态寄存器,以便获得解决问题的指导。

    谢谢!
    马特
    ____________________________________________
    unsigned int WriteSPI (unsigned char dataHi,unsigned char dataLo)

    无符号int结果High;
    无符号int resultLow;
    无符号int finalResult;

    digitalWrite (芯片选择,高);
    resultHigh = SPI.transfer (dataHi;
    resultLow = SPI.transfer (dataLO);
    digitalWrite (芯片选择,低);
    FinalResult =结果高<8;
    FinalResult = FinalResult & ResultLow;

    延迟(10);

    Return FinalResult (返回结果结果);

    }


    void getCurrentRegisters()

    serial.print("\n------------------ \n");
    serial.print ("CTRL寄存器");
    serial.print (WriteSPI (0x80,0x00),hex);
    serial.print("\n");

    serial.print ("扭矩寄存器");
    serial.print (WriteSPI (0x90,0x00),hex);
    serial.print("\n");

    serial.print ("off register ");
    serial.print (WriteSPI (0xA0,0x00),hex);
    serial.print("\n");

    serial.print ("空白寄存器");
    serial.print (WriteSPI (0xB0,0x00),hex);
    serial.print("\n");

    serial.print ("衰减寄存器");
    serial.print (WriteSPI (0xC0,0x00),hex);
    serial.print("\n");

    serial.print ("失速寄存器");
    serial.print (WriteSPI (0xD0,0x00),hex);
    serial.print("\n");

    serial.print ("驱动器寄存器");
    serial.print (WriteSPI (0xE0,0x00),hex);
    serial.print("\n");

    serial.print ("状态寄存器");
    serial.print (WriteSPI (0xF0,0x00),hex);
    serial.print("\n------------------ \n");
    }
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Matt,您好!

    在尝试操作电机之前,您能否捕获寄存器的读数? 驱动器寄存器是一个很好的示例,因为默认值有1和0。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,Rick:

    是的,我尝试在操作电机之前读取寄存器。 这是我所有代码的副本。 这是为Energia写的。 您会注意到getCurrentRegisters();在setup()中被调用。

    尽管如此,仍返回0。

    Thx
    马特


    #include<SPI.h>

    #include<msp430G2553.h>
    #include "HardwareSerial.h"
    #include<driverlib.h>
    Int ChipSelect = 11;
    Int DIR = 13;
    内部方向= 1;
    #定义按钮BIT3.
    Int模式= 1;
    内部制动器= 12;
    Int sensorValue;
    Int pulse_time = 100;
    Int cycle_time = 3*pulse_time;
    #define CCC_16_Enable 0x25
    #define CW_16_Enable 0x27
    #define CCC_16_Disable 0x24
    #define CW_16_Disable 0x26
    #define CCC_2_Enable 0xd
    #define CW_2_Enable 0xF
    #define CCC_2_Disable 0xc
    #define CW_2_Disable 0xe
    void setup()



    //在此处输入您的设置代码,以便运行一次:
    引脚模式(P1_6,输出);//使LED引脚输出
    PinMode (P1_0,输出);
    针模式(制动,输出);
    DigitalWrite (P1_6,低);
    DigitalWrite (P1_0,LOW);
    PinMode (芯片选择,输出);
    digitalWrite (芯片选择,高);
    PinMode (DIR,INPUT_PLEUP);
    Serial.begin(9600);
    serial.println ("bla");
    pinMode (5,input_pullup);
    SPI.begin();
    pinMode (6,输出);//睡眠模式
    PinMode (9,输出);//步进
    PinMode (8,输出);//重置
    DigitalWrite (6,高);//睡眠
    DigitalWrite (10,high);//方向
    DigitalWrite (8,LOW);//重置
    initialize();
    延迟(1);
    serial.println (TACTL0,bin);
    serial.println ("完成");
    getCurrentRegisters();
    //配置字
    //位15-10:未使用
    //位9-8:Tassel。 时钟源选择:设置为SMCLK (16MHz)
    //00 TALK
    //01 ACLK辅助 时钟
    //10 SMCLK子主时钟
    //11 INCLK
    //在下面设置为SMCLK
    //位7-6:ID位输入分隔符:设置为8
    //位5-4:模式控制:计数到TACRO并重置
    //00停止计时器停止。
    // 01向上计时器重复计数,从零到TACR0的值。 这一套
    // 10连续计时器从零到0FFFFh反复计数。
    // 11上/下计时器从零到TACR0的值反复计数,再从零到零。

    //位3:未使用
    //位2:TALR:设置为初始清除计时器系统
    //位1:启用来自TA0的中断
    //位0:中断(待处理)标志:设置为零(初始)
    TA0CTL=0b0.001万11010000;1101万;// Timer_A控件0x0160h
    TACR0=3000;// Timer_A捕获/比较0。生成1ms时基@ 16MHz,除数为8



    //TACCTL0 = BIT4;// 0x162=TACCTL0 Timer_A捕获/比较控制0
    //BIT0 CCIFG捕获/比较interupt标志
    // 0没有等待中断的中断
    // 1中断待处理
    }
    void循环()

    sensorValue = analogRead (2);//电位计

    unsigned char CTRLdataHi,CTRLdataLo;
    布尔运行标志= 0;
    //Serial.Print ("传感器值:");
    //Serial.println (sensorValue);

    //执行帐户

    IF (digitalRead (5)==低)


    IF (TACR0 > CYCLE _TIME)//400和2000

    TACTL0 ^= 1<< 4;//切换捕获/比较中断启用CCIE
    //TACCR0 = TACCR0-1;
    TACTL0 ^= 1<< 4;//切换捕获/比较中断启用CCIE
    }

    /*
    IF (运行标志= 0)//如果未运行,则启用电机


    CTRLdataHi = 0x0C;//控制寄存器
    CTRLdataLo = CW_16_Enable;
    WriteSPI (CTRLdataHi,CTRLdataLo);
    RunningFlag = 1;
    延迟(100);

    }
    */
    IF (digitalRead (DIR)==低)


    serial.println ("CW");
    开关(模式)


    案例1://注册方法。 此测试成功。
    CTRLdataHi = 0x0C;
    CTRLdataLo = CCW_16_Enable;//1/16
    WriteSPI (CTRLdataHi,CTRLdataLo);

    情况2://方向销方法。
    pinMode (10,输出);
    IF (方向= 1)

    DigitalWrite (10,0);
    }
    否则

    DigitalWrite (10,1);
    }
    }

    }
    否则

    serial.println ("ccc");
    CTRLdataHi = 0x0C;
    CTRLdataLo = CW_16_Enable;//1/2
    WriteSPI (CTRLdataHi,CTRLdataLo);
    }
    TCCTL0 = BIT4;

    }
    否则,如果(digitalRead (5)== high)//停止电机移动中断停止。

    TCCTL0 = 0;
    TACR0=3000;
    /* CTRLdataHi = 0x0C;//控制寄存器
    CTRLdataLo = CW_16_Disable;
    WriteSPI (CTRLdataHi,CTRLdataLo);
    RunningFlag =0;
    */

    }
    //将主代码放在此处,重复运行:

    }
    //此Vector语句后面的ADDRESS函数被放置在指定的位置中断Vector表中
    #pragma vector=TIMER0_A0_vector //(0x0012) 0xFFF2 Timer0_A cC0
    __interrupt void timerA0ISR(void)



    TACTL0 ^= 1<< 4;//切换捕获/比较中断启用CCIE
    DigitalWrite (9,高);
    delayMicroseconds (pulse_time);
    DigitalWrite (9,低);

    IF (TACR0 > CYCLE _TIME)//400和2000

    TACR0 = TACR0-8;
    }
    TACTL0 ^= 1<< 4;//切换捕获/比较中断启用CCIE

    }


    unsigned int WriteSPI (unsigned char dataHi,unsigned char dataLo)

    无符号int结果High;
    无符号int resultLow;
    无符号int finalResult;

    digitalWrite (芯片选择,高);
    resultHigh = SPI.transfer (dataHi;
    resultLow = SPI.transfer (dataLO);
    digitalWrite (芯片选择,低);
    FinalResult =结果高<8;
    FinalResult = FinalResult & ResultLow;

    延迟(10);

    Return FinalResult (返回结果结果);

    }
    void Initialize()

    Int结果;
    /CTRL寄存器默认值
    unsigned char CTRLdataHi,CTRLdataLo;
    CTRLdataHi = 0x0F;//以前为C。 F将增益更改为40以获得更多扭矩
    //CTRLdataLo = 0x2F;//1/32启用
    //CTRLdataLo = 0x27;//1/16启用
    CTRLdataLo = CW_16_Disable;//1/16已禁用
    //CTRLdataLo = 0x47;//1/256已启用
    //CTRLdataLo = 0x00;
    WriteSPI (CTRLdataHi,CTRLdataLo);

    //扭矩默认值
    无符号字符TORQUEHi,TORQUELO;
    TORQUEHi = 0x13;
    TORQUELO = 0x5D;
    //TORQUELo = 0x1F;
    WriteSPI (TORQUEHi,TORQUELO);

    //关闭默认值
    unsigned char OFFHi,OFFLo;
    OFFHi = 0x20;//内部索引器
    //OFFHi = 0x21;//旁路索引器
    OFFLo = 0xA0;
    WriteSPI (OFFHi,OFFLo);

    //空白默认值
    unsigned char BLNKHI, BLNKLO;
    BLNKHi = 0x31;
    BLNKLO = 0xFF;
    WriteSPI(BLNKHI, BLNKLO);

    //衰减默认值
    unsigned char DECAYHi,DECAYLo;
    DECAYHi = 0x41;
    DECAYLo = 0x10;
    WriteSPI (DECAYHi,DECAYLo);

    //stall默认值
    无符号字符STALLHI, STALLLO;
    STALLHi = 0x53;
    STALLLO = 0xFF;
    WriteSPI (STALLHi,STALLLLO);

    //驱动器默认值
    unsigned char DRIVEHI, DRIVELo;
    DRIVEHi = 0x6f;//400mA峰值接收器200mA峰值源
    DRIVELO = 0x5C;
    WriteSPI(DRIVEHI, DRIVELo);

    //状态默认值
    unsigned char STATUSHI, STATUSLO;
    STATUSHi = 0x70;
    STATUSLO = 0x00;
    结果= WriteSPI (STATUSHi,STATUSLO);
    结果= WriteSPI (STATUSHi,STATUSLO);
    serial.print ("状态:");
    serial.println (result,hex);
    digitalWrite (芯片选择,低);
    }

    void getCurrentRegisters()

    serial.print("\n------------------ \n");
    serial.print ("CTRL寄存器");
    serial.print (WriteSPI (0x80,0x00),hex);
    serial.print("\n");

    serial.print ("扭矩寄存器");
    serial.print (WriteSPI (0x90,0x00),hex);
    serial.print("\n");

    serial.print ("off register ");
    serial.print (WriteSPI (0xA0,0x00),hex);
    serial.print("\n");

    serial.print ("空白寄存器");
    serial.print (WriteSPI (0xB0,0x00),hex);
    serial.print("\n");

    serial.print ("衰减寄存器");
    serial.print (WriteSPI (0xC0,0x00),hex);
    serial.print("\n");

    serial.print ("失速寄存器");
    serial.print (WriteSPI (0xD0,0x00),hex);
    serial.print("\n");

    serial.print ("驱动器寄存器");
    serial.print (WriteSPI (0xE0,0x00),hex);
    serial.print("\n");

    serial.print ("状态寄存器");
    serial.print (WriteSPI (0xF0,0x00),hex);
    serial.print("\n------------------ \n");
    }
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Matt,您好!

    SPI事务的范围捕获将更易于调试。 这将有助于确定发送到DRV8711的内容以及DRV8711的响应方式。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Rick:

    下面是我通过示波器捕捉到的内容。  这是状态寄存器的读数。  您会注意到:

    时钟:蓝色

    SDO:红色

    SDI:棕色

    CS:绿色

    SDO高电压似乎过低。  也许这就是为什么我只收到零。  我确实已将MSP430上的SDO引脚配置为内部上拉。  我为什么会得到如此低的电压。  我是否需要外部上拉?

    关于原始问题,为什么驱动器出现故障。  从轨迹中,我看到第3位和第7位高,表示存在通道A驱动器故障,且锁定失速检测处于活动状态。  我不确定如何配置预驱动程序。  我已经尝试过IDRIVEN和IDRIVEP。  将这些值设置为其最小值对某些方面有所帮助,但我继续在电机旋转过程中遇到故障和断断续续的情况。  我确实有OCPDEG到8US。

    关于以下方面的任何想法:

    1. 为什么SDO电压这么长

    2.如何解决间歇性前置驱动器故障。

    Thx

    马特