一文详解H桥马达控制器的工作原理

今日头条

1151人已加入

描述

H桥马达控制器(H-Bridge Motor Controlle)非常简单,用起来也非常有趣,像小时候玩风车一样。但是,马达是工业应用的基础,用起来并不简单。

本项目电路中的 NPN 晶体管可为马达提供更大电流,这样我们就可以使用较小电压来切换马达,使用较大电压驱动马达,让马达获得更高转速和更大力矩。但是,一定要确保马达工作于安全功率和要求电压范围内。

 

电路

 

该电路中的开关可由微型控制器取代,可通过PWM技术控制马达的转速。当然,也可以控制马达让其在一个方向旋转。

也可以再增加一个晶体管,这次我们使用 P-N-P 型,并通过一个二极管来保护这两个晶体管,免受来自马达的感性负载影响。

 

电路



为电路正确工作,需下拉引脚2为 LOW,并为引脚3加上一个PWM信号。电路中,两个晶体管通过推、拉电流,为马达提供更大的力矩,实现更高的效率。

这下,我们开始提到的问题出现了,那就是如何让让马达转向。这也不难,把电路复制一下,再增加几个元件就解决了。不过,电路看起来有些复杂。

 

电路

 

这个电路中,Q1、Q2为P-N-P晶体管,Q3、Q4为N-P-N晶体管,P-N-P晶体管导通时基极的R1 or R2必须下拉为 LOW,N-P-N晶体管工作时基极的R3 or R4必须上拉为 HIGH。

这里,PNP和NPN晶体管必须为匹配良好的对管,电流和电压大小要根据马达尺寸来选择,这取决于马达是用于小玩具或者个人爱好,而2N2222A NPN晶体管、2N2907A PNP晶体管可提供中等性能。也可以使用NPN型2N3904晶体管和PNP型2N3906晶体管, 但是性能表现不佳,而ZTX1049A NPN型晶体管和ZTX968 PNP型晶体管的表现最佳。

对于像RC类的较大型DC马达,NPN型的TIP120、TIP121和TIP122,PNP型的TIP125、TIP126、TIP127能够承受5A工作电流,以及高达8A的峰值电流。但是一定要使用散热片,这些晶体管的外形也非常大,封装形式TO-220。

通过下拉为LOW(接地),D2、D4可打开或关断一个指定的 PNP 晶体管(Q1 or Q2 )。

D3、D5为PWM或常态数字输出,将其上拉为HIGH(接VCC)可打开晶体管(Q3 or Q4 )。

如果想让马达转向,这也简单。上拉D4为HIGH,下拉D5为LOW,D2也为LOW,为D3施加一个PWM信号,或者将其上拉为HIGH,看看发生了什么?

上拉D2为LOW开关Q1,上拉D5为High,或为其加上一个PWM信号,打开Q4、Q2、Q3并保持关闭。

现在,电路就开始向Q1推、拉电流,经过马达,再经过Q4流向地,使马达按照一定方向转圈,我们称之为正向。

相反,如果D2 HIGH,D4 LOW, D5 LOW,D3 HIGH或者添加一个PWM信号,使电流从Q2流出,再通过马达的流向Q3,这就有效的改变了马达的方向。

不过,有些情况会导致电池短路,例如:
D2 LOW,D5 High 或PWM状态
D4 LOW,D3 High 或PWM状态

这两种状态会导致电池电压直接与“地”短路,因此千万别使用这两个组合。

下面是Arduino开发板代码:


/*

* Example code to use with DIY H-Bridge ( One Motor )

* Another second motor will need another H-Bridge, and control pins

*

* Maker and IOT Ideas 2020 (MakerIOT2020)

*/

/* Define control pins */

const int fwd_enable=2;

const int fwd_pwm=3;

const int rev_enable=4;

const int rev_pwm=5;

void setup()

{

     // Set pin Modes, while preventing accidental short of supply

     digitalWrite(fwd_enable,HIGH);

     digitalWrite(rev_enable,HIGH);

     // force PNP transistors to stay off;

     digitalWrite(fwd_pwm,LOW);

     digitalWrite(rev_pwm,LOW);

     // force NPN transistors to stay off;

     // now set the pin mode.

     pinMode(fwd_enable,OUTPUT);

     pinMode(rev_enable,OUTPUT);

     pinMode(fwd_pwm,OUTPUT);

     pinMode(rev_pwm,OUTPUT);

}

void stop_all()

{

     /* This will stop everything,

     *  allowing the motor to run free or coast)

     *  

     */

     digitalWrite(fwd_pwm,LOW);

     digitalWrite(rev_pwm,LOW);

     digitalWrite(fwd_enable,HIGH);

     digitalWrite(rev_enable,HIGH);

}

void motor_fwd()

{

     /*  

      *   Makes the motor run “forward”

      *   If you find that it actually reverses your motor,

      *   please swap the physical wiring at the motor once.

      *   It should now work correctly forever …

      */

     digitalWrite(rev_enable,HIGH);

     digitalWrite(rev_pwm,LOW);

     // Make sure about the states of the other side of the

     // H-Bridge, to prevent shorts

     digitalWrite(fwd_enable,LOW);

     digitalWrite(fwd_pwm,HIGH);

     // Motor will now be on and running, at a fixed speed

}

void motor_fwd_pwm(int motor_speed)

{

     digitalWrite(rev_enable,HIGH);

     digitalWrite(rev_pwm,LOW);

     // Make sure about the states of the other side of the

     // H-Bridge, to prevent shorts

     digitalWrite(fwd_enable,LOW);

     analogWrite(fwd_pwm,motor_speed);

}

void motor_rev()

{

     digitalWrite(fwd_enable,HIGH);

     digitalWrite(fwd_pwm,LOW);

     // Make sure about the states of the other side of the

     // H-Bridge, to prevent shorts

     digitalWrite(rev_enable,LOW);

     digitalWrite(rev_pwm,HIGH);

     // Motor will now be on and running, at a fixed speed

}

void motor_rev_pwm(int motor_speed)

{

     digitalWrite(fwd_enable,HIGH);

     digitalWrite(fwd_pwm,LOW);

     // Make sure about the states of the other side of the

     // H-Bridge, to prevent shorts

     digitalWrite(rev_enable,LOW);

     analogWrite(rev_pwm,motor_speed);

}

void motor_brake()

{

     /*

      * This will brake the motor, or make it slow down

      */

      digitalWrite(fwd_enable,HIGH);

      digitalWrite(rev_enable,HIGH);

      digitalWrite(fwd_pwm,HIGH);

      digitalWrite(rev_pwm,HIGH);

}

void motor_brake_intervals(int brakes = 2)

{

     // this will brake the motor x times, default of 2

     // delay used here for ease of explanation, feel free to change

     // this to millis

     for (int i = 0; i < brakes; i++)

         {

             motor_brake;

             delayMicroseconds(10);

             stop_all();

             delayMicroseconds(10);

         }

     // and allow motor to run free

     stop_all();

}

void loop() {

 // Sample use

 // Start with a stopped motor

 stop_all();

 // go forwards

 motor_fwd();

 delay(2000);

 // brake and stop

 motor_brake_intervals(5);

 // reverse direction

 motor_rev();

 delay(2000);

 // brake and stop

 motor_brake_intervals(5);

 // PWM slow to fast

 for (int i = 155; i < 255; i+=10)

 {

     motor_fwd_pwm(i);

     delay(100);

 }

 // brake and stop

 motor_brake_intervals(5);

 delay(500);

 // Reverse fast to slow

 for (int i = 255; i > 155 ; i-=10)

 {

     motor_rev_pwm(i);

 }

 // brake and stop

 motor_brake_intervals(5);

 delay(500);

 stop_all;

}

  审核编辑:汤梓红
 
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分