Arduino ESP32实现互补PWM输出
问题提出
直流有刷电机控制使用U3115S芯片。芯片是电压高达300V的半H桥驱动电路,管脚说明:
Number | Symbol | Description |
---|---|---|
1 | VCC | 低侧固定逻辑电源输入 |
2 | HIN | 逻辑输入端,控制门电路驱动输出(HO), 同相 |
3 | LIN# | 逻辑输入端,控制门电路驱动输出(LO), 异相 |
4 | COM | 低侧电源返回 |
5 | LO | 低侧门驱动输出 |
6 | VS | 高侧浮动电源返回 |
7 | HO | 高侧门驱动输出 |
8 | VB | 高侧浮动电源 |
其实上面的表中的信息量很大。要能够实现对该模块的控制,需要注意的地方很多,最主要的是在HIN和LIN#端输入互补的PWM控制信号
半桥驱动电路
半桥驱动电路的一个注意事项是电容自举升压。
必须是PWM互补输入才能工作
如上图,输出的电位可以通过示波器查看。因为使用了自举升压的电路,在VB和VS之间有一个电容,这个电容在Q1关闭,Q2导通时会被充电,电压接近VCC,我们的例子中是12V左右。当要打开Q1时,这个12V的电压就会为Q1的G-S端提供电压,使其导通。Q1导通后,S端的电压被抬升,在我们的电路里电压值抬升到24V,VB端的电压是35.4V。但要注意,这个电压不会保持很长时间,经过一定的时间,电压会降低,最终停留在接近电源电压值。所以,在使用这个半桥驱动电路时一定要用互补的PWM来驱动。即在控制输入的HIN和LIN#端输入互补的PWM。如果是按我们想象的给控制Q1管的控制端输入一个3.3V的高电平,给控制Q2管的控制输入加一个0.0V的话,在输出端得不到24V的输出。必须采用PWM,而且是互补的PWM输入。下面的图是能够正常工作的电压给定:
上面的图是在网上找打的。这样就可以形成一个单极有刷直流电机的驱动。实际测量的波形输出:
Arduino ESP32的互补PWM控制
要实现互补PWM,需要MCPWM,但Arduino好像不支持MCPWM,在库管理中只找到了一个MCPWM库,好像还不是为Arduino准备的,应该是为ESP-IDF准备的,也没有例子程序。为快速实现样机,对PWM进行配置
- 采用ledc PWM对H桥的上臂进行控制,实现一个PWM
- 采用对上臂的PWM端连接中断,当上臂控制端变化时产生中断,根据输出的高低来控制下臂的输出。
- 由于采用了中断,对下臂就可以采用常规的方法进行控制。
这里应该注意到,因为U3115S的内部已经实现了同时打开上下臂开关管的保护,我们的外部控制程序可以不必考虑其它的保护措施。
void setup()
{
attachInterrupt(motorLU, isrLU, CHANGE);
attachInterrupt(motorRU, isrRU, CHANGE);
}
上面的程序将电机控制的左上臂和右上臂的信号变化用isrLU和isrRU中断处理程序关联。
void IRAM_ATTR isrLU(void)
{
if ( digitalRead(motorLU) && PWMN) // UP close DOWN open
{
digitalWrite(motorLD, HIGH); // UP 1, DOWN 0
return;
}
if ( !digitalRead(motorLU) && PWMN) // UP open DOWN close
{
digitalWrite(motorLD, LOW); // UP 0, DOWN 1
return;
}
}
void IRAM_ATTR isrRU(void)
{
if ( digitalRead(motorRU) && PWMN) // UP close DOWN open
{
digitalWrite(motorRD, HIGH); // UP 1, DOWN 0
return;
}
if ( !digitalRead(motorRU) && PWMN) // UP open DOWN close
{
digitalWrite(motorRD, LOW); // UP 0, DOWN 1
return;
}
}
上面是中断处理程序。
通过中断处理,实现下臂的互补PWM输出。