【工作笔记】DW7888 马达驱动芯片待机模式漏电流过高的问题

发现问题

客户反馈说我们的硬件关机漏电流很大,但是拔掉电池之后再上电(仍处于关机状态)就会恢复为 16~20uA 左右。这让我也讶异,因为亲自测试过,漏电流只有 MCU 的休眠电流 16~20uA 左右 (包含一些电子元器件),远远低于项目要求的 <100uA。

观看客户的复现步骤,发现客户每次在关机之前,都会通过触摸触发设备一些功能,而我的测试是开机之后,等上位机运行正常就直接关机(未驱动电机转动)。

分析问题

触摸触发的功能其中最直观的是让电机转动,因此高度怀疑跟电机驱动部分功能有关,通过断开上位机,直接通过串口控制设备转一下电机,然后再关机,果然复现问题,漏电流为 380uA 左右。当问题出现之后,必须拔掉电池再重新上电,电流才会下降到正常的范围(20uA 左右)。

电机驱动 IC 有 6 颗,分别平均分布在 A、B 两块副板上,拔掉副板的电机驱动连接线,电流直接降至 200uA 左右,反复测试都是如此,跟带不带电机没有太大关系。因此确认与电机驱动IC有关,通过示波器测量控制芯片的控制信号,确认软件控制逻辑正确,此时发现该电机芯片的电源不受控,直接通过电池供电。

电机驱动IC型号是 DW7888,我们查到规格书,待机电流 <2uA,因此即使电源未关断,在待机模式下,漏电流也不至于那么大才对。

【工作笔记】DW7888 马达驱动芯片待机模式漏电流过高的问题

【工作笔记】DW7888 马达驱动芯片待机模式漏电流过高的问题

【工作笔记】DW7888 马达驱动芯片待机模式漏电流过高的问题

然后回想问题的复现流程,开机之后默认为待机模式,为什么一驱动电机,再进入待机模式,就会出现问题呢?

这与芯片规格书描述不符呀?跟我们的硬件工程师沟通之后,让我在出现问题的时候让芯片进入刹车模式,然后再进入待机模式。想到规格书有写到刹车模式是可以释放马达能量的,觉得有机会,顺手就用飞线出来的3.3V,同时给其中一颗电机驱动IC的两个输入信号碰一下(FI\BI 都置高电平),奇迹出现了,电流居然下降了 60uA 左右,依次将所有的电机都这么操作一次,电流最终降到 20uA 的水平,说明每颗驱动IC漏电流在 60uA 左右。

【工作笔记】DW7888 马达驱动芯片待机模式漏电流过高的问题

我很兴奋的马上通过 MCU 来模拟这种操作,结果让人大跌眼镜,居然没效果,拿出示波器来测量,发现确实有给出刹车信号,百思不得其解(原因下文有解)。

最后电话咨询供应商,供应商拖了蛮久才回复说是这个芯片本身的待机电流就是在  50uA~60uA 左右,但是这个回复解释不了我们实测的现象,就请他帮忙联系芯片原厂的工程师沟通一下这事情。

解决问题

跟原厂技术重新沟通了整个情况,最后他们确认这是该芯片的设计缺陷,鉴于我们的新发现,他也十分诧异,希望我们寄一套平台给他们,分析原因。

最后给出的答复是 FI、BI 两个信号同时拉低的间隔要非常短,而我们两个信号拉低间隔了 900ns,他们用 8M 的 MCU 同时设置拉低(受示波器精度影响,测量不出时差),就能解决此问题。

恍然大悟,我们咋没想到呢,我们当时测试的时候是将 DW7888 输入信号飞的线拧在一块,然后再去碰 3.3V 只高电平,从而进入刹车模式,电压是同时传给两个信号。而 MCU 是顺序执行代码,所以会有先后之分,总会有间隔。只是我们 MCU 的主频是 72M 没理由比他们原厂 8M 的 MCU 还慢,直接上代码分析,看有没有优化空间。 

我们当时模拟的代码,考虑可移植和可配置,通过一个数组来存储每个在配置文件配置的 GPIO,因此实现如下:

【工作笔记】DW7888 马达驱动芯片待机模式漏电流过高的问题

测的波形如下,两个控制信号间隔约有 900ns:

【工作笔记】DW7888 马达驱动芯片待机模式漏电流过高的问题

上图的代码是逐个引脚控制,两根引脚控制信号的时间间隔有 900ns,可以移除循环语句和同时设置多个寄存器位,来缩短控制信号的时间间隔。因此修改代码如下:

【工作笔记】DW7888 马达驱动芯片待机模式漏电流过高的问题

测的波形如下,同组的 GPIO 几乎是同时拉低(示波器精度有限):

【工作笔记】DW7888 马达驱动芯片待机模式漏电流过高的问题

发现有一颗还存在 60uA 电流,查看原理图发现该芯片的 FI\BI 控制脚分别在GPIOA和GPIOB组,测得波形如下(500ns):

【工作笔记】DW7888 马达驱动芯片待机模式漏电流过高的问题

由于 GPIOA、GPIOB 两组是分别通过调用函数来实现拉低,考虑到函数入栈出栈的消耗,采用直接操作寄存器的方式:

【工作笔记】DW7888 马达驱动芯片待机模式漏电流过高的问题

测得波形如下,间隔约 124ns (这里直观地展现出调用普通函数的入栈出栈消耗有多大了,72MHz的主频,慢了4倍多):

【工作笔记】DW7888 马达驱动芯片待机模式漏电流过高的问题

测得结果通过,16uA:

【工作笔记】DW7888 马达驱动芯片待机模式漏电流过高的问题

最终补丁

上面的只是工程验证,实际应用还需要考虑到代码维护性以及稳定性,如需要有明确的注释,以及需要考虑中断的影响。

--- configuration.h	2020-12-10 11:28:07.000000000 +0800
+++ configuration.h	2020-12-10 11:23:40.000000000 +0800
@@ -169,12 +169,35 @@
 #define MOTOR_FI_RFRONT_PWM_CHANNEL				8		
 #define MOTOR_BI_LBACK_PWM_CHANNEL					9				// 左后电机
 #define MOTOR_FI_LBACK_PWM_CHANNEL					10		
 #define MOTOR_BI_RBACK_PWM_CHANNEL					11				// 右后电机
 #define MOTOR_FI_RBACK_PWM_CHANNEL					12
 
+// ------------------------------------ 注意(lmx:20201210) -----------------------------------
+
+// 修复 DW7888 芯片缺陷(需要注意此相关代码仅适用于 DW7888 驱动芯片): 
+// 1.当驱动电机之后再进入待机模式, 每颗芯片会存在 60uA 左右的漏电流, 而这些芯片的电源不受控制
+// 2.有效修复方法是先进入刹车模式, 再进入待机模式, 两个输入信号同时拉低的时间一定要小于 500ns
+// 3.由于当前硬件设计有一颗驱动芯片分别用了 GPIOA-15\GPIOB-3 两组引脚, 因此不能一次性同时设置
+// 4.实测可以通过直接操作寄存器的方式缩短两组 GPIO 控制时间间隔(124ns):
+// unsigned int groupa_allpin = FIX_DW7888_CHIP_BUG_GPIO_PIN_1;
+// unsigned int groupb_allpin = FIX_DW7888_CHIP_BUG_GPIO_PIN_2;
+// GPIO_BOP(FIX_DW7888_CHIP_BUG_GPIO_GROUP_1) = groupa_allpin;
+// GPIO_BOP(FIX_DW7888_CHIP_BUG_GPIO_GROUP_2) = groupb_allpin;
+// delay_1ms(100U);
+// disable all interrupt code
+// GPIO_BC(FIX_DW7888_CHIP_BUG_GPIO_GROUP_1) = groupa_allpin;
+// GPIO_BC(FIX_DW7888_CHIP_BUG_GPIO_GROUP_2) = groupb_allpin;
+// enable all interrupt code
+
+#define FIX_DW7888_CHIP_BUG_GPIO_GROUP_1			GPIOA
+#define FIX_DW7888_CHIP_BUG_GPIO_PIN_1				(GPIO_PIN_9 | GPIO_PIN_8 | GPIO_PIN_15 | GPIO_PIN_10 | GPIO_PIN_11)
+#define FIX_DW7888_CHIP_BUG_GPIO_GROUP_2			GPIOB
+#define FIX_DW7888_CHIP_BUG_GPIO_PIN_2				(GPIO_PIN_13 | GPIO_PIN_12 | GPIO_PIN_15 | GPIO_PIN_14 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_3)
+// ------------------------------------ 注意(lmx:20201210) -----------------------------------
+
 // Action 计时模块
 #define CFG_ACTION_TIMER							TIMER13
 #define CFG_ACTION_TIMER_RCU_CLOCK					RCU_TIMER13
 #define CFG_ACTION_TIMER_IRQ_NUMBER				TIMER13_IRQn
 #define CFG_ACTION_TIMER_IRQ_FUNCTION				TIMER13_IRQHandler
 
--- Interface\common.c	2020-12-10 11:28:40.000000000 +0800
+++ Interface\common.c	2020-12-10 11:26:15.000000000 +0800
@@ -18,12 +18,43 @@
 #include "common.h"
 #include "sensor_infra_red.h"
 #include "motor_control.h"
 #include "action_process.h"
 #include "function_switch.h"
 
+// ------------------------------------ 注意(lmx:20201210) -----------------------------------
+// 修复 DW7888 芯片缺陷(需要注意此相关代码仅适用于 DW7888 驱动芯片): 
+// 1.当驱动电机之后再进入待机模式, 每颗芯片会存在 60uA 左右的漏电流, 而这些芯片的电源不受控制
+// 2.有效修复方法是先进入刹车模式, 再进入待机模式, 两个输入信号同时拉低的时间一定要小于 500ns
+// 3.由于当前硬件设计有一颗驱动芯片分别用了 GPIOA-15\GPIOB-3 两组引脚, 因此不能一次性同时设置
+// 4.实测可以通过直接操作寄存器的方式缩短两组 GPIO 控制时间间隔(124ns):
+// ------------------------------------ 注意(lmx:20201210) -----------------------------------
+static void dw7888_low_power_mode()
+{
+	unsigned int groupa_allpin = FIX_DW7888_CHIP_BUG_GPIO_PIN_1;
+	unsigned int groupb_allpin = FIX_DW7888_CHIP_BUG_GPIO_PIN_2;
+
+	// 刹车模式
+	GPIO_BOP(FIX_DW7888_CHIP_BUG_GPIO_GROUP_1) = groupa_allpin;
+	GPIO_BOP(FIX_DW7888_CHIP_BUG_GPIO_GROUP_2) = groupb_allpin;
+	delay_1ms(100U);
+
+	// 待机模式
+	__disable_irq();
+	GPIO_BC(FIX_DW7888_CHIP_BUG_GPIO_GROUP_1) = groupa_allpin;
+	GPIO_BC(FIX_DW7888_CHIP_BUG_GPIO_GROUP_2) = groupb_allpin;
+	__enable_irq();
+	
+	return ;
+}
+
+static void common_fix_chip_bug_release()
+{
+	dw7888_low_power_mode();
+}
+
 static void common_periph_clock_init()
 {
 	// 系统滴答时钟初始化
 	systick_config();
 	
 	// 启用各个公共时钟
@@ -85,14 +116,14 @@
 	simple_sensor_release();
 	adc_control_release();
 	led_control_release();
 	master_transfer_release();
 	power_manager_release();
 	time_base_release();
+	common_fix_chip_bug_release();
 	common_periph_clock_release();
-	
 	return ;
 }
 
 // 进入升级模式(实质是跳转到 boot )
 void common_enter_update_mode(void)
 {

问题总结

1. 以后写完程序之后要测试低功耗的时候,应该全功能跑完之后,再关机来看漏电流。

2. 后面我们发现芯片承认书里面的 DW7888 规格书里面的被改为待机电流为 <50uA,也就是一开始选型就能发现问题,只是我们硬件工程师不够细心(虽然有他签字),这也从侧面证实了供应商其实是知道有这么一个问题,原厂之前应该也不知道有这种解决办法。

3. 像多个信号需要同时触发,使用手动去测试可以通过,但是MCU模拟却不通过,就需要首先考虑到 GPIO 之间的间隔时间,因为 MCU 代码是串行执行的,不像 FPGA 可以通过一个时钟触发多个代码块同时执行。那么简单的道理,居然让我给忽略了,忽略了,忽略了,唉。。。

小插曲

我们让供应商帮我们联系原厂工程师之后,客户发了邮件过来,说他们定位到了跟驱动IC有关,也咨询了IC厂,说是这个芯片的待机电流本身就是 50uA~60uA,将关机功耗标准拉高到 400uA,也就是说客户接受了。我们没想到客户那么积极处理问题,同时也没想到客户那么干脆就提高标准线了。既惊喜又纠结,惊喜的是起码不用担心损失的问题,纠结的是,手上的事情较多,那还要不要继续往下查呢?

最后还是坚持查下去,很希望能确认到问题的根本原因,因为供应商的答复并不能完全解释我们看到的现象,既然可以通过3.3V手动拉高可以解决,那么就说明这个问题是有办法解决的。既然已经申请了芯片原厂介入,应该不需要耗费太多的时间精力,不会影响其他的项目进度。所幸,坚持终有所获。

上一篇:commit message格式规范


下一篇:vue用命令批量解决ESLint警告