普通有刷直流電機 H橋驅動

      最近用到了低壓大功率有刷直流電機, 需要調速控制, 時間緊急,來不及加速度反饋, 直接使用PWM開環控制了。  根據功率估算了電流大概在10A左右,沒時間畫電路板,於是淘寶 找了下集成驅動模塊, 發現也就BTS7960 板橋芯片的模塊合適,於是買了3個, 模塊每個有2個 BTS7960, 組成一個H橋, 驅動一路電機, 需要2路。 由於之前沒有實際驅動過H橋, 看來下幾種驅動方式, 決定使用單橋臂 PWM調製 方法, 另一橋臂作爲方向使用, 這種情況下只有一路橋臂需要PWM引腳,實際分配引腳方便些, 但是有個問題,控制方向的橋臂驅動高電平時,  pwm 橋臂側最小時 輸出低電平的話,其實是最大輸出,  想到2種辦法,一是更改輸出極性, 二是 使用最大PWM值減去計算的pwm值作爲 PWM輸出, 不想再初始化定時器,於是採用 減pwm的方法寫的。             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;
}
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章