找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 41702|回复: 18
收起左侧

直流电机的PWM单片机控制实例 L298N模块ENA与ENB的说明

  [复制链接]
ID:140725 发表于 2017-3-22 04:11 | 显示全部楼层 |阅读模式
使用直流/步进两用驱动器可以驱动两台直流电机。分别为M1和M2。引脚A,B可用于输入PWM脉宽调制信号对电机进行调速控制。(如果无须调速可将两引脚接5V,使电机工作在最高速状态,既将短接帽短接)实现电机正反转就更容易了,输入信号端IN1接高电平输入端IN2接低电平,电机M1正转。(如果信号端IN1接低电平, IN2接高电平,电机M1反转。)控制另一台电机是同样的方式,输入信号端IN3接高电平,输入端IN4接低电平,电机M2正转。(反之则反转),PWM信号端A控制M1调速,PWM信号端B控制M2调速。可参考下图表:
0.png

输入部分接线图
0.png
输出部分接线图 0.png
下面是单片机源程序:
  1. #include <reg52.h>

  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. #define CYCLE 20        //周期

  5. sbit IN1 =P1^0;//右
  6. sbit IN2 =P1^1;
  7. sbit IN3 =P1^2;//左
  8. sbit IN4 =P1^3;
  9. sbit ENB =P1^4;
  10. sbit ENA =P1^5;
  11. sbit h1 = P0^0;
  12. sbit h2 = P0^1;
  13. sbit h3 = P0^2;
  14. sbit h4 = P0^3;
  15. sbit h5 = P0^4;

  16. uchar pwm1,pwm2,flag,a;
  17. void delayms(uint xms);

  18. void go();//直走
  19. void hou();
  20. void tl();//左转
  21. void tr();//右转
  22. void Init_Timer0(void);//定时器初始化
  23. void hou()
  24. {
  25.         IN1 = 1;//右
  26.         IN2 = 0;
  27.         IN3 = 1;//左
  28.         IN4 = 0;
  29. }
  30. void tlz()
  31. {
  32.         IN1 = 0;//右
  33.         IN2 = 1;
  34.         IN3 = 1;//左
  35.         IN4 = 0;
  36. }
  37. void tl()
  38. {
  39.         IN1 = 0;//右
  40.         IN2 = 1;
  41.         IN3 = 0;//左
  42.         IN4 = 0;
  43. }
  44. void tr()
  45. {
  46.         IN1 = 0;//右
  47.         IN2 = 0;
  48.         IN3 = 0;//左
  49.         IN4 = 1;
  50. }
  51. void go()
  52. {
  53.         IN1 = 0;
  54.         IN2 = 1;
  55.         IN3 = 0;
  56.         IN4 = 1;
  57. }
  58. void suiji()
  59. {
  60.         if(h3==0)
  61.         {
  62.                 pwm1=10;
  63.           pwm2=2;
  64.                 tl();
  65.   }
  66.         else if(h3==0&&h2==0)
  67.         {
  68.                 pwm1=10;
  69.           pwm2=3;
  70.                 tr();
  71.   }
  72.         else if(h1==0||h2==0)
  73.         {
  74.                 pwm1=10;
  75.           pwm2=5;
  76.                 tr();
  77.   }
  78.                 else if(h3==0||h4==0)
  79.         {
  80.                 pwm1=5;
  81.           pwm2=10;
  82.                 tl();
  83.   }
  84.                 else if(h5==0||h4==0)
  85.         {
  86.                 pwm1=3;
  87.           pwm2=10;
  88.                 tl();
  89.   }
  90.         else
  91.         {
  92.                 pwm1=3;
  93.           pwm2=3;
  94.                 go();
  95.   }
  96. }
  97.         

  98. void xunji()
  99. {
  100.         while(h2==1&&h3==1&&h4==1&&h5==1&&h1==1)
  101. {
  102.          pwm1=3;
  103.          pwm2=3;
  104.    go();
  105. }
  106.         
  107.                 //////////////*****************////////////////////////
  108.         
  109.                 if(h2==0||h3==0)
  110.                         {
  111.                                 pwm1=1;
  112.                                 pwm2=10;
  113.                                 tlz();
  114.                         }
  115.                         else if(h4==1&&h5==1&&h2==0&&h3==0&&h1==0)
  116.                         {
  117.                                 pwm1=10;
  118.                                 pwm2=1;
  119.                                 tr();
  120.                         }
  121.                         else if(h4==0&&h5==1)
  122.                         {
  123.                                 pwm1=3;
  124.               pwm2=3;
  125.                                 go();
  126.                         }
  127.                         else if(h5==0)
  128.                         {
  129.                                 pwm1=3;
  130.                                 pwm2=3;
  131.                                 tl();
  132.                         }
  133.                         else
  134.                         {
  135.                                 pwm1=3;
  136.               pwm2=3;
  137.                                 go();
  138.                         }

  139.                 //////////////////*************/////////////////////
  140.         
  141. }
  142. /*******初始化函数********/
  143. void init()
  144. {
  145.         TMOD=0x20;
  146.         TH1=0xfd;
  147.         TL1=0xfd;
  148.         TR1=1;
  149.         REN=1;
  150.         SM0=0;
  151.         SM1=1;
  152.         EA=1;
  153.         ES=1;
  154. }
  155. void main()
  156. {
  157.         //uchar i;
  158.         Init_Timer0();
  159.   init();
  160.         
  161.   a = SBUF;
  162.                         switch(a)
  163.            {

  164.                         case 02:
  165.                                 {
  166.                                         pwm1=5;
  167.                                         pwm2=5;
  168.                                         hou();//后
  169.                                 } break;
  170.                         case 03:
  171.                                 {
  172.                                         pwm1=8;
  173.                                         pwm2=8;
  174.                                         tr();//右
  175.                                 } break;
  176.                         case 04:
  177.                                 {
  178.                                         pwm1=8;
  179.                                         pwm2=8;
  180.                                         tl(); //左
  181.                                 } break;
  182. //                        case 05:
  183. //                        {
  184. //                                xunji();
  185. //      }break;
  186.                         case 06:
  187.                         {
  188.                                 suiji();
  189.       }break;
  190.                         case 07:
  191.                         {
  192.                                 pwm1=5;
  193.               pwm2=5;
  194.                                 go();
  195.       }break;
  196.                         case 0x08:
  197.                         {
  198.                                 IN1 = 0;//
  199.               IN2 = 0;
  200.               IN3 = 0;//
  201.               IN4 = 0;
  202.       }
  203.                         default:break;
  204.            }
  205. }

  206. ////毫秒延时
  207. //void delayms(uint xms)
  208. //{
  209. //uint i, j;
  210. //for(i=xms;i>0;i--)         //xms 毫秒
  211. //        for(j=110;j>0;j--);
  212. //}

  213. /*------------------------------------------------
  214.                     定时器初始化子程序
  215. ------------------------------------------------*/
  216. void Init_Timer0(void)
  217. {
  218. TMOD |= 0x01;          //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响                     
  219. //TH0=0x00;              //给定初值
  220. //TL0=0x00;
  221. EA=1;            //总中断打开
  222. ET0=1;           //定时器中断打开
  223. TR0=1;           //定时器开关打开
  224. }
  225. /*------------------------------------------------
  226.                  定时器中断子程序
  227. ------------------------------------------------*/
  228. void Timer0_isr(void) interrupt 1
  229. {
  230. static unsigned char count;
  231. TH0=(65536-2000)/256;                  //重新赋值 2ms
  232. TL0=(65536-2000)%256;

  233.         if (count==pwm1)
  234.                         {
  235.                          ENA = 0;                           
  236.                         }
  237.         if(count==pwm2)
  238.                 {
  239.                                 ENB = 0;  
  240.                 }
  241.                 count++;
  242.         if(count == CYCLE)       //反之低电平时间结束后返回高电平
  243.                         {
  244.                         count=0;
  245.                 if(pwm1!=0)    //如果开启时间是0 保持原来状态
  246.                 {
  247.                         ENA = 1;              
  248.                         
  249.                 }
  250.                 if(pwm2!=0)
  251.                 {
  252.                         ENB = 1;
  253.                 }
  254.       }

  255. }
  256. void ser1() interrupt 4
  257. {
  258.         EA=0;
  259.         if(RI==1)
  260.         {
  261.                 a = SBUF;
  262.                 RI=0;
  263.         }
  264.         EA=1;
  265. }
复制代码

  1. /********************************************************************
  2. 实现功能:直流电机调试程序
  3. 使用芯片:AT89S52 或者 STC89C52
  4. 晶振:11.0592MHZ
  5. 编译环境:Keil
  6. 【声明】此程序仅用于学习与参考,引用请注明版权和作者信息!     
  7. *********************************************************************/
  8. #include<reg52.h>
  9. #define uchar unsigned char//宏定义无符号字符型
  10. #define uint unsigned int  //宏定义无符号整型
  11. sbit P2_0=P2^0;//M1启动
  12. sbit P2_1=P2^1;//M1停止
  13. sbit P2_2=P2^2;//M2启动
  14. sbit P2_3=P2^3;//M2停止
  15. sbit P1_0=P1^0;//M1
  16. sbit P1_1=P1^1;//M1
  17. sbit P1_2=P1^2;//M2
  18. sbit P1_3=P1^3;//M2
  19. /********************************************************************
  20.                             延时函数
  21. *********************************************************************/
  22. void delay(uchar t)//延时程序
  23. {
  24. uchar m,n,s;
  25. for(m=t;m>0;m--)
  26. for(n=20;n>0;n--)
  27. for(s=248;s>0;s--);
  28. }
  29. /********************************************************************
  30.                             主函数
  31. *********************************************************************/
  32. main()
  33. {
  34. while(1)
  35.    {
  36.        if(P2_0==0){delay(3);if(P2_0==0)//M1启动
  37.          {
  38.                  P1_0=1;                                    
  39.                         P1_1=0;
  40.           }}
  41.        if(P2_1==0){delay(3);if(P2_1==0)//M1停止
  42.          {
  43.                  P1_0=1;
  44.                          P1_1=1;
  45.                   }}
  46.             if(P2_2==0){delay(3);if(P2_2==0)//M2启动
  47.          {
  48.                  P1_2=1;
  49.                           P1_3=0;
  50.           }}
  51.        if(P2_3==0){delay(3);if(P2_3==0)//M2停止
  52.          {
  53.                  P1_2=1;
  54.                          P1_3=1;
  55.                   }}

  56. …………余下代码请下载附件…………
复制代码
问:Ena 和Enb是分别接两个直流电机么?直流电机的剩下那端接哪儿?

答:
不是直接接连个电机  他两端是脉宽调制  举个例子  如果你要实现两个电机不同的转速来达到智能小车转弯的效果你可以这样
四个输入端接在单片机的四个管脚   四个输出端接在两个直流电机  两个使能端也接到单片机的两管脚(就是ENA,ENB)通过写程序来控制
电机的转速写程序的方法有很多的简单说明一下定义一个变量j  然后让j++;当j=20ms的时候吧j清0;送给高电平定义一个i  叫i++;让i=10ms的时候
i=0;送低电平,这就实现了电机转20ms听10ms的过程,由于扫描很快就实现了电机的减速,而你必须在你的单片机的使能端管脚送一个低电平
减速机要ENA=0;(让此管教的电压小于2.5v)他才能执行电机调速的过程,ENB=1是另一个电机全速运行,哪一个电机减速运行就实现了差速转弯了
    这只是我自己的理解   也不知道该怎么说希望你能看懂吧。
0.png
下载:
l298驱动直流电机程序和教程.rar (402.08 KB, 下载次数: 357)

评分

参与人数 1黑币 +8 收起 理由
木木123 + 8 赞一个!

查看全部评分

回复

使用道具 举报

ID:149167 发表于 2017-3-22 08:31 | 显示全部楼层
51黑有你真精彩
回复

使用道具 举报

ID:179657 发表于 2017-3-22 09:52 | 显示全部楼层
厉害喽我的歌
回复

使用道具 举报

ID:179657 发表于 2017-3-22 09:52 | 显示全部楼层
我也做了一个PWM的控制程序
回复

使用道具 举报

ID:179661 发表于 2017-3-22 10:00 | 显示全部楼层
步进电机怎么驱动
回复

使用道具 举报

ID:1 发表于 2017-3-22 18:09 | 显示全部楼层

L298N+光耦驱动步进电机测试程序和原理图:http://www.51hei.com/bbs/dpj-79475-1.html
回复

使用道具 举报

ID:151000 发表于 2017-8-11 01:27 | 显示全部楼层
谢谢楼主分享   
回复

使用道具 举报

ID:140358 发表于 2017-12-1 09:54 | 显示全部楼层
赞,不错,容易学习
回复

使用道具 举报

ID:305541 发表于 2018-4-20 16:14 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:318181 发表于 2018-4-27 23:34 | 显示全部楼层
不错,下来看看
回复

使用道具 举报

ID:309574 发表于 2018-5-7 17:12 | 显示全部楼层
谢谢楼主分享‘



回复

使用道具 举报

ID:213489 发表于 2018-5-9 09:46 | 显示全部楼层
原理图接线和程序不一致啊
回复

使用道具 举报

ID:185372 发表于 2018-5-24 08:18 | 显示全部楼层
正在使用,不过是stm32,这个来学习下,感谢
回复

使用道具 举报

ID:381204 发表于 2018-9-27 22:20 来自手机 | 显示全部楼层
请问谁有完整的程序呀?我不好下载
回复

使用道具 举报

ID:381204 发表于 2018-9-28 23:09 | 显示全部楼层
请问程序中的h1,h2,h3,h4,h5是什么呀?
回复

使用道具 举报

ID:470187 发表于 2019-2-12 13:39 | 显示全部楼层
感谢楼主。很厉害。我的毕业设计终于可以做出来来哈哈哈哈哈哈哈哈哈哈。
回复

使用道具 举报

ID:488862 发表于 2019-3-11 21:31 | 显示全部楼层
学习一下。利用调速来给小车转弯
回复

使用道具 举报

ID:556754 发表于 2019-6-6 18:52 | 显示全部楼层
谢谢楼主
回复

使用道具 举报

ID:421308 发表于 2019-7-23 09:34 | 显示全部楼层
太厉害了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表