• Arduino ESP32使用U3115S芯片控制H桥驱动有刷直流电机


    问题提出

    直流有刷电机控制使用U3115S芯片。芯片是电压高达300V的半H桥驱动电路,管脚说明:

    NumberSymbolDescription
    1VCC低侧固定逻辑电源输入
    2HIN逻辑输入端,控制门电路驱动输出(HO), 同相
    3LIN#逻辑输入端,控制门电路驱动输出(LO), 异相
    4COM低侧电源返回
    5LO低侧门驱动输出
    6VS高侧浮动电源返回
    7HO高侧门驱动输出
    8VB高侧浮动电源

    其实上面的表中的信息量很大。要能够实现对该模块的控制,需要注意的地方很多,最主要的是在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进行配置

    1. 采用ledc PWM对H桥的上臂进行控制,实现一个PWM
    2. 采用对上臂的PWM端连接中断,当上臂控制端变化时产生中断,根据输出的高低来控制下臂的输出。
    3. 由于采用了中断,对下臂就可以采用常规的方法进行控制。
      这里应该注意到,因为U3115S的内部已经实现了同时打开上下臂开关管的保护,我们的外部控制程序可以不必考虑其它的保护措施。
    void setup()
    {
    	attachInterrupt(motorLU, isrLU, CHANGE);
        attachInterrupt(motorRU, isrRU, CHANGE);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    上面的程序将电机控制的左上臂和右上臂的信号变化用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;
        }  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    上面是中断处理程序。

    通过中断处理,实现下臂的互补PWM输出。

  • 相关阅读:
    使用labelme自制coco格式数据集
    [极客大挑战 2019]BuyFlag 1(两种解法)
    常用的Linux系统的IO函数
    【Leetcode】1027. Longest Arithmetic Subsequence
    RabbitMQ 学习(四)-- 发布确认模式
    【联邦学习】联邦学习量化——non-iid数据集下的仿真
    Python报错:ValueError: operands could not be broadcast together with shapes
    空间数据结构管理---RTree(上篇)
    前端代码统计工具cloc的安装与使用
    【CSS】背景样式(颜色、图片、平铺、附着和位置)
  • 原文地址:https://blog.csdn.net/weixin_44481398/article/details/128031762