普通有刷直流电机 H桥驱动

      最近用到了低压大功率有刷直流电机, 需要调速控制, 时间紧急,来不及加速度反馈, 直接使用PWM开环控制了。  根据功率估算了电流大概在10A左右,没时间画电路板,于是淘宝 找了下集成驱动模块, 发现也就BTS7960 板桥芯片的模块合适,于是买了3个, 模块每个有2个 BTS7960, 组成一个H桥, 驱动一路电机, 需要2路。 由于之前没有实际驱动过H桥, 看来下几种驱动方式, 决定使用单桥臂 PWM调制 方法, 另一桥臂作为方向使用, 这种情况下只有一路桥臂需要PWM引脚,实际分配引脚方便些, 但是有个问题,控制方向的桥臂驱动高电平时,  pwm 桥臂侧最小时 输出低电平的话,其实是最大输出,  想到2种办法,一是更改输出极性, 二是 使用最大PWM值减去计算的pwm值作为 PWM输出, 不想再初始化定时器,于是采用 减pwm的方法写的。普通有刷直流电机 H桥驱动_第1张图片             H桥简图

       考虑 方向桥臂有可能使用   继电器 或 接触器代替, 切换方向时 关闭使能了一段时间,避免驱动电机过程中切换方向,引起电弧,产生浪涌电压,损坏器件。 另外需要注意 大功率电机 需要添加加减速控制逻辑, 加速过程会避免大电流冲击, 减速过程能再生制动。     代码如下:

 

typedef enum DIR_ENUM    // 方向枚举
{
    DirForward  = 0,    
    DirBackward = 1
}DirEnum;

/  定义了个 最小PWM: BASE_PWM_VAL,  pwm 映射到 百分比:   BASE_PWM_PERC ~ 100
//  0 不要映射, 做 停止PWM用
u16  percConv(u32 pwm)
{
    if(0 == pwm)     return 0;
    else                  return BASE_PWM_VAL + (pwm * (100 - BASE_PWM_PERC)) / 100;
}
        //  PCout(6)
// RUN_MOTR_EN     PAout(8)
// 最少10mS 调用一次, 换向时 30mS内 无pwm输出
void setLRPwm(u16 reaPwmL, u16 reaPwmR, DirEnum dirL, DirEnum dirR)
{
    static DirEnum lastDirL, lastDirR;
    static u8 reinL, reinR;            //    static u16 lastPwmL, lastPwmR; 

    reaPwmL = percConv(reaPwmL);
    reaPwmR = percConv(reaPwmR);
                                   // check max pwm
    if(reaPwmL > MAX_PWM_VAL)  reaPwmL = MAX_PWM_VAL;
    if(reaPwmR > MAX_PWM_VAL)     reaPwmR = MAX_PWM_VAL;

    // 左或右 换向时, 重置 时间计数,  多少次内无PWM输出
    if(lastDirL != dirL)
    {
        reinL = 0;
        lastDirL = dirL;
    }
    if(lastDirR != dirR)
    {
        reinR = 0;
        lastDirR = dirR;
    }

    DIR_L = dirL;
    DIR_R = dirR;

    if(reinL < 4)        
        RUN_MOTL_EN = 0;
    else
    {
        if(DirForward == dirL)
        {
            TIM_SetCompare3(TIM4, reaPwmL);
        }else
            TIM_SetCompare3(TIM4, FULL_PWM_VAL - reaPwmL);
        if(0 == reaPwmL)    RUN_MOTL_EN = 0;
        else                            RUN_MOTL_EN = 1;
    }
    
    if(reinR < 3)        
        RUN_MOTR_EN = 0;
    else
    {
        if(DirForward == dirR)
        {
            TIM_SetCompare4(TIM4, reaPwmR);
        }else            
            TIM_SetCompare4(TIM4, FULL_PWM_VAL - reaPwmR);
        if(0 == reaPwmR)    RUN_MOTR_EN = 0;
        else                            RUN_MOTR_EN = 1;
    }                                        //    lastPwmL = reaPwmL;    lastPwmR = reaPwmR;
    
    reinL++;                    reinR++;
    if(reinL > 200)        reinL = 200;
    if(reinR > 200)        reinR = 200;
}
 

你可能感兴趣的:(电机驱动,嵌入式,H桥,直流有刷电机,BTS7960)