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.

[参考译文] DRV8836:使用 DRV8836DSSR (12引脚)驱动3.7V 空心杯电机时出现问题

Guru**** 2468460 points
Other Parts Discussed in Thread: DRV8836, TMS320F28035

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

https://e2e.ti.com/support/motor-drivers-group/motor-drivers/f/motor-drivers-forum/1278160/drv8836-there-is-a-problem-driving-3-7v-hollow-cup-motor-with-drv8836dssr-12-pin

器件型号:DRV8836
主题中讨论的其他器件: TMS320F28035

大家好、

要求:用 DRV8836DSSR 芯片来驱动空心杯电机、但现在有一些问题、如下所示:

所用的主控制芯片是 TMS320F28035 (56引脚)芯片、主控制芯片和 DRV8836芯片的硬件原理图如下:

从原理图可以清楚地看到主控制芯片和 DRV8836的连接关系。

CCS 使用 EPWM1和 EPWM2调节 DRV8836的完整代码如下:

第一个是 main.c 文件:

#include "Config.h"
extern Uint16 RamfuncsLoadSize;

void main(void)
{
    InitSysCtrl();
    DINT;
    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable();
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (Uint32)&RamfuncsLoadSize);
    LED_Init();              // 初始化LED-
    InitMotor();            // 初始化电机-
    Timer0_init();         // 定时器0初始化,1ms周期中断-
    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
    EINT;
    ERTM;

    while(1)
        {
        int f=900;
    /* 实现的任务1(10ms为一个周期):
    * 调控电机油门或转向*/
            if(timer0Base.loop100HzCnt >= 10)
            {
                timer0Base.loop100HzCnt = 0;
                LED2_TOGGLE;
                DELAY_US(200*1000);
                MotorPwmFlash(f,2);
                LED3_TOGGLE;
            }
        }
}

MOTO.c 文件:

#include "stdio.h"
#include "Moto.h"
uint8_t Turningmodeselection=Noturn;
uint16_t MOTO1_PWM=0;

/*******************************************************************************
* 函 数 名:	     void InitMotor(void)
* 函数功能:	     DRV8836双通道驱动电路初始化
*******************************************************************************/
void InitMotor(void)
{
	EALLOW;
	nSLEEPMUX = 0; nSLEEPDIR = 1;  //GPIO模式;输出模式
	MODEMUX = 0; MODEDIR = 1;
	AIN1MUX = 0; AIN1DIR = 1;
	AIN2MUX = 0; AIN2DIR = 1;
	BIN1MUX = 0; BIN1DIR = 1;
	BIN2MUX = 0; BIN2DIR = 1;
	EDIS;
	nSLEEPLOW();   // DRV8836关闭模式
	MODELOW();     // DRV8836为IN/IN模式
	AIN1LOW(); AIN2LOW();  // BSDC1关闭
	BIN1LOW(); BIN2LOW();  // BSDC2关闭
	InitEPWM_AQ_DB();    // PWM 初始化函数
	nSLEEPON();            // 唤醒Drv8836
	printf("\r\nPWM(DRV8836) init...OK");
}

/*******************************************************************************
* 函 数 名:	     void InitEPWM_AQ_DB(void)
* 函数功能:	     PWM1/2初始化
*******************************************************************************/
void InitEPWM_AQ_DB(void)
{
	char i;
	volatile struct EPWM_REGS *PWMDef[] = {&EPwm1Regs,&EPwm1Regs,&EPwm2Regs,&EPwm3Regs,&EPwm4Regs,&EPwm5Regs,&EPwm6Regs};
	EALLOW;
	SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC =0;  //失能时基模块时钟
	SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK =1; //时钟启用
	SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK =1; //时钟启用
	EDIS;
	InitEPwmGpio();  //开启时钟及初始化配置
	EALLOW;
	PieVectTable.EPWM1_INT = &epwm1_isr;
	PieVectTable.EPWM2_INT = &epwm2_isr;
	EDIS;
	for(i=1;i<4;i++)
	{
		EALLOW;
		PWMDef[i]->TBCTL.bit.CTRMODE = TB_COUNT_UP;   // 递增计数模式
		PWMDef[i]->TBPRD = EPWM_TIMER_TBPRD;          // 设置定时器周期
		PWMDef[i]->TBCTL.bit.PHSEN = TB_DISABLE;      // 禁止相位加载
		PWMDef[i]->TBPHS.half.TBPHS = 0x0000;         // 时基相位寄存器的值赋值0
		PWMDef[i]->TBCTR = 0x0000;                    // 时基计数器清零,时基计数器为16 位, 读该寄存器的值可以得到时基计数器 (TBCTR) 的值。 写该寄存器可以设置时基计数器的值。
		PWMDef[i]->TBCTL.bit.HSPCLKDIV = HTB_DIV1;    // SYSCLKOUT=60M HZ
		PWMDef[i]->TBCTL.bit.CLKDIV = TB_DIV64;       // 设置时基时钟速率
	
		PWMDef[i]->CMPCTL.bit.SHDWAMODE = CC_SHADOW;   //设置影子
		PWMDef[i]->CMPCTL.bit.SHDWBMODE = CC_SHADOW;
		PWMDef[i]->CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; //设置加载模式,0加载
		PWMDef[i]->CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

	    // 设置比较寄存器的值
		PWMDef[i]->CMPA.half.CMPA = 0;                 // 清零
		PWMDef[i]->CMPB = 0;                           // 清零

		// 设置动作限定;首先默认为转动方向为正转,这时只有PWMiA输出占空比;
		PWMDef[i]->AQCTLA.bit.ZRO = AQ_SET;            // 计数到0时PWMxA输出高电平
		PWMDef[i]->AQCTLA.bit.CAU = AQ_CLEAR;          // 递增计数时,发生比较寄存器A匹配时清除PWMxA输出
		PWMDef[i]->AQCTLB.bit.ZRO = AQ_CLEAR;          // 计数到0时PWMxB输出低电平
		PWMDef[i]->AQCTLB.bit.CBU = AQ_CLEAR;          // 递增计数时,发生比较寄存器A匹配时清除PWMxB输出


		// 1次0匹配事件发生时产生一个中断请求;
		PWMDef[i]->ETSEL.bit.INTSEL = ET_CTR_ZERO;     // 选择0匹配事件中断
		PWMDef[i]->ETSEL.bit.INTEN = 1;                // 使能事件触发中断
		PWMDef[i]->ETPS.bit.INTPRD = ET_1ST;           // 1次事件产生中断请求
		EDIS;
	}

	EALLOW;
	SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC =1;
	EDIS;


	IER |= M_INT3;  //中断初始化
	PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
	PieCtrlRegs.PIEIER3.bit.INTx2 = 1;
}

/*******************************************************************************
* 函 数 名:	    interrupt void epwm1_isr(void)
* 函数功能:	    控制尾翼电机的转速
*******************************************************************************/
interrupt void epwm1_isr(void)
{
 	switch (Turningmodeselection){
 	case Noturn:
 	   //保证下面EPWMA和EPWMB相互切换同时输出0电平;
     	EPwm1Regs.CMPA.half.CMPA = 0;//改变脉宽
     	EPwm1Regs.CMPB = 0;          //改变脉宽
 		break;
 	case Turnleft:
 	   //保证下面EPWMA和EPWMB相互切换同时输出0电平;
     	EPwm1Regs.CMPA.half.CMPA = 0;//改变脉宽
     	EPwm1Regs.CMPB = 0;          //改变脉宽


 		EPwm1Regs.AQCTLA.bit.ZRO = AQ_CLEAR;          // 计数到0时PWM1A输出低电平
 		EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // 递增计数时,发生比较寄存器A匹配时清除PWM1A输出

 		EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET;            // 计数到0时PWM1B输出高电平
 		EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;          // 递增计数时,发生比较寄存器A匹配时清除PWM1B输出
 		EPwm1Regs.CMPA.half.CMPA = Vertailmotor_PWM;
 	    EPwm1Regs.CMPB = Vertailmotor_PWM;
 		break;
 	case Turnright:
 	   //保证下面EPWMA和EPWMB相互切换同时输出0电平;
     	EPwm1Regs.CMPA.half.CMPA = 0;//改变脉宽
     	EPwm1Regs.CMPB = 0;          //改变脉宽


 		EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;            // 计数到0时PWM1A输出高电平
 		EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // 递增计数时,发生比较寄存器A匹配时清除PWM1A输出
 		EPwm1Regs.AQCTLB.bit.ZRO = AQ_CLEAR;          // 计数到0时PWM1B输出低电平
 		EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;          // 递增计数时,发生比较寄存器A匹配时清除PWM1B输出
 	    EPwm1Regs.CMPA.half.CMPA = Vertailmotor_PWM;
 	    EPwm1Regs.CMPB = Vertailmotor_PWM;
 		break;
    default:
        break;}	// end switch
	EPwm1Regs.ETCLR.bit.INT = 1;             // 清除中断标志位
	PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;  // 清除PIE应答寄存器
}

/*******************************************************************************
* 函 数 名:	    interrupt void epwm2_isr(void)
* 函数功能:	    控制机翼电机的转速
*******************************************************************************/
interrupt void epwm2_isr(void)
{
	if(MOTO1_PWM>=CMPX_MAX)	MOTO1_PWM = CMPX_MAX;
	if(MOTO1_PWM<=CMPX_MIN)	MOTO1_PWM = CMPX_MIN;
	EPwm2Regs.CMPA.half.CMPA = MOTO1_PWM;
	EPwm2Regs.ETCLR.bit.INT = 1;             // 清除中断标志位
	PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;  // 清除PIE应答寄存器
}

/*******************************************************************************
* 函 数 名:	    void MotorPwmFlash(int16_t MOTO1_PWM,int16_t MOTO2_DELAY,uint8_t Turningmodeselection)
* 函数功能:	    更新主翼电机占空比和尾翼转向
*******************************************************************************/
void MotorPwmFlash(int16_t MOTO1_PWM2,uint8_t Turningmodeselecting)
{
	MOTO1_PWM=MOTO1_PWM2;
	Turningmodeselection=Turningmodeselecting;
}

Moto.h:

#ifndef INC_MOTO_H_
#define INC_MOTO_H_

#include "extern_variable.h"

#define PWM_FRE 600000
#define EPWM_TIMER_TBPRD  999

/* 电机档位定义*/
#define CMPX_MIN         0
#define CMPX_HALF        500
#define CMPX_MAX         999
#define Vertailmotor_PWM 300
extern uint8_t Turningmodeselection;
extern uint16_t MOTO1_PWM;
enum {Noturn = 0,Turnleft,Turnright};
#define nSLEEP GPIO5
#define nSLEEPMUX GpioCtrlRegs.GPAMUX1.bit.nSLEEP
#define nSLEEPDIR GpioCtrlRegs.GPADIR.bit.nSLEEP
#define nSLEEPTOGGLE()  GpioDataRegs.GPATOGGLE.bit.nSLEEP = 1
#define nSLEEPON()  GpioDataRegs.GPASET.bit.nSLEEP =1
#define nSLEEPLOW() GpioDataRegs.GPACLEAR.bit.nSLEEP =1
#define MODE GPIO4
#define MODEMUX GpioCtrlRegs.GPAMUX1.bit.MODE
#define MODEDIR GpioCtrlRegs.GPADIR.bit.MODE
#define MODETOGGLE()  GpioDataRegs.GPATOGGLE.bit.MODE = 1
#define MODEON()  GpioDataRegs.GPASET.bit.MODE =1
#define MODELOW()  GpioDataRegs.GPACLEAR.bit.MODE =1
#define BIN2 GPIO0
#define BIN2MUX GpioCtrlRegs.GPAMUX1.bit.BIN2
#define BIN2DIR GpioCtrlRegs.GPADIR.bit.BIN2
#define BIN2TOGGLE()  GpioDataRegs.GPATOGGLE.bit.BIN2 = 1
#define BIN2ON()  GpioDataRegs.GPASET.bit.BIN2 =1
#define BIN2LOW()  GpioDataRegs.GPACLEAR.bit.BIN2 =1
#define BIN1 GPIO1
#define BIN1MUX GpioCtrlRegs.GPAMUX1.bit.BIN1
#define BIN1DIR GpioCtrlRegs.GPADIR.bit.BIN1
#define BIN1TOGGLE()  GpioDataRegs.GPATOGGLE.bit.BIN1 = 1
#define BIN1ON()  GpioDataRegs.GPASET.bit.BIN1 =1
#define BIN1LOW()  GpioDataRegs.GPACLEAR.bit.BIN1 =1
#define AIN2 GPIO2
#define AIN2MUX GpioCtrlRegs.GPAMUX1.bit.AIN2
#define AIN2DIR GpioCtrlRegs.GPADIR.bit.AIN2
#define AIN2TOGGLE()  GpioDataRegs.GPATOGGLE.bit.AIN2 = 1
#define AIN2ON()  GpioDataRegs.GPASET.bit.AIN2 =1
#define AIN2LOW()  GpioDataRegs.GPACLEAR.bit.AIN2 =1
#define AIN1 GPIO3
#define AIN1MUX GpioCtrlRegs.GPAMUX1.bit.AIN1
#define AIN1DIR GpioCtrlRegs.GPADIR.bit.AIN1
#define AIN1TOGGLE()  GpioDataRegs.GPATOGGLE.bit.AIN1 = 1
#define AIN1ON()  GpioDataRegs.GPASET.bit.AIN1 =1
#define AIN1LOW()  GpioDataRegs.GPACLEAR.bit.AIN1 =1

/* 包含头文件*/
void InitMotor(void);
void InitEPWM_AQ_DB(void);
void MotorPwm1Flash(int16_t MOTO1_PWM);
interrupt void epwm1_isr(void);
void MotorPwm2Flash(uint8_t Turningmodeselection);
interrupt void epwm2_isr(void);
void MotorPwmFlash(int16_t MOTO1_PWM,uint8_t Turningmodeselection);

#endif /* INC_MOTO_H_ */

这段代码可以正常运行、我个人认为这段代码没有问题、但电机无法正常旋转、所以我不知道问题出在哪里。

当代码正常运行时,我希望图片显示出额定电压为3.7V 的空心杯马达可以正常旋转。

但实际情况是电机根本不旋转、CCS 软件接口跳转到一个奇怪的接口、如下图所示。

空心杯电机的两根电线正确连接到(AOUT1、AOUT2)或(BOUT1、BOUT2)接口、电机不仅无反应、而且软件将进入上面的接口。

尽管空心杯马达的额定电压为3.7V,但它可以通过连接到马达的1.5V 电压进行旋转。

我给 DRV8836的电源电压在1S 锂电池分压后对于整个电路是3.3V、我没有直接将1S 锂电池接至 DRV8836 (VCC 和 GND)。

在我的测试中、我发现在正常运行情况下、当我连接(AOUT1直接连接到 AOUT2)或(BOUT1直接连接到 BOUT2)时、也会出现上图中的 CCS 接口。

我使用 EPWM2A 连接 AIN2和 EPWM2B 来连接 AIN1、给定的占空比为80%。 我通过示波器正确观察到了波形。 根据预期计算,AOUT1和 AOUT2引脚的电压输出为3.3V*0.8=2.64V,足以驱动空心杯电机,但电机在插入后不移动,且软件停止调试。

1.代码有问题吗?

2.硬件电路有问题(1S 锂电池应该直接连接到8836的 VCC 和 GND 吗?)

3、CCS 为什么有一个不熟悉的接口? (我正在使用 XDS100V1仿真器)

4.如何配置中空杯马达以使其正常运行?

您能帮助检查这个问题吗? 谢谢。

此致、

切里

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

    您好 Cherry:

    我会仔细研究您的问题、并尽快与您联系。

    此致、

    巴勃罗·阿梅特

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

    您好 Cherry:

    相关的教程。 请向 CCS 团队咨询、因为我不是这方面的专家。 但是、我可以帮助解决电机和 DRV 相关问题。

    Unknown 说:
    2. 硬件电路有问题(1S 锂电池是否应直接连接到8836的 VCC 和 GND?)

    这应该不是问题。 我的确注意到、VCC 线路上没有大容量电容器。 它在原理图中的其他某个位置吗? 我们建议最小10uF 的大容量电容和0.1uF 的去耦电容。  

    根据预期的计算,AOUT1和 AOUT2引脚的电压输出为3.3V*0.8=2.64V,足以驱动空心杯电机,但电机在插入后不会移动且软件停止调试。[/引述]

    当软件停止 Debug 时。 输入信号是否会变为低电平?

    此致、

    巴勃罗·阿梅特

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

    尊敬的  Pablo Armet:

    感谢您的支持。

    我的 CCS 代码应该没有问题、因为我使用了示波器来观察符合预取指令的 ePWM 波形。

    在我的测试后中空杯马达没有问题。

    1. DRV8836芯片的使用应该存在问题。 DRV8836的数据手册未详述。 例如、未详细指定应输入哪些信号 AIN1和 AIN2。

    您能向我提供 DRV8836用例吗? 包含所用的 C 语言代码和硬件原理图

    请参考数据手册、在 DRV8836的 VCC 处连接一个10uF 电容器。 请参阅下面的硬件原理图。

    3.当软件停止调试时,以下情况将首先出现在 CCS 界面上,然后没有信号输入到 DRV8836的 AIN1\AIN2和 BIN1\BIN2。 如果将直流有刷空心杯电机插入 DRV8836的 XOUT1和 XOUT 端口(X=A 或 B)、则会触发故障。

    4.猜猜可能出现的问题:由于 DRV8836封装很小,它是否与我的焊接有关?

    5.猜测可能的问题:我在软件类型中配置了 DRV8836,但只进行了简单的配置,我不知道是否正确。

    谢谢。此致、

    切里

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

    您好 Cherry:

    1. DRV8836芯片的使用应该存在问题。 DRV8836的数据手册未详述。 例如,没有详细指定应输入的信号 AIN1和 AIN2。

    对于满量程步进、输入应该如下面所示(当处于 PWM 模式时)

    2.i 请参考数据手册、并在 DRV8836的 VCC 处连接一个10uF 电容器。 请查看下面的硬件原理图。

    建议添加一个与10uF 并联的0.1uF 电容器。

    当软件停止调试时、以下情况将首先出现在 CCS 接口上、然后没有信号输入到 DRV8836的 AIN1\AIN2和 BIN1\BIN2。 如果将直流有刷空心杯电机插入 DRV8836的 XOUT1和 XOUT 端口(X=A 或 B)、则将触发故障。[/报价]

    这是 CCS 问题还是电机驱动器问题? 看起来有些东西会导致 CCS 程序停止、输入没有信号导致电机停止。 您能否提供输入信号的波形?

    4. 猜猜可能出现的问题:由于 DRV8836封装很小,它是否与我的焊接有关?

    让我们首先尝试了解 DRV8836是否触发了故障。  

    问题1:此问题是否始终发生、或者电机是否成功旋转了一段时间、然后停止?

    Q2:在不将电机连接到输出的情况下、OUTx 信号是否遵循数据表中的控制逻辑表? 本质上、OUTx 电压是否基于提供的 INx 信号而符合预期?

    Q3:连接电机并尝试驱动电机后、可以使用电流探头检查电机电流吗? 它是否超出 OCP 限制?

    Q4:您能否提供一个波形来显示驱动时和电机停止时的 OUTx 电压?

    5. 猜测可能的问题:我在软件类型中配置了 DRV8836,但仅进行了简单的配置,我不知道它是否正确。

    您能否提供从 uC 到 DRV8836的输入信号? 我可以确认。

    此致、

    巴勃罗·阿梅特

    [/quote]