找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5889|回复: 2
打印 上一主题 下一主题
收起左侧

基于51单片机和L298N的小车制作

[复制链接]
跳转到指定楼层
楼主
ID:381204 发表于 2018-9-27 21:38 来自手机 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
到目前为止, 总算把51单片机过了一遍, 本来暑假就要完成的任务一直拖到了现在。  51学完, 就想着先做点东西, 就从小车开始。
     玩小车最重要的是什么? 电机。这个就不用多解释了。 从今天早上开始到现在 总算是知道点皮毛了。 因为有学长做过这东西, 所以做起来也有大概的方向  知道是要搞哪些东西。 现在主要是L298N电机驱动和PWM脉冲控制。  
什么是L298N电机驱动? 什么是PWM脉冲?
一开始我一无所知, 实验室里面有L298N驱动 但是我只知道它是L298N驱动, 对于怎么使用却是一点也不知道。 在网上找教程, 淘宝上找资料; 挣扎了一个上午总算是知道了L298N驱动怎么使用, 相应I/O口的含义以及用途。  给一个传送门:我是L298N驱动资料地址: L298N_电机驱动模块_程序书.doc (1.13 MB, 下载次数: 38)
那什么是PWM呢? PWM是脉冲宽度调制, 在电机方面主要是通过改变占空比来改变电机的转速, 从而实现加速、减速、转弯等基本功能。 什么是占空比? 占空比指的是一个周期内, 高电平占这个周期的比例。  占空比越高,
电压输出就越高, 电机转动的就越快。
在飞思卡尔、stm32 等芯片中有专门的模块用来控制PWM, 但是在51单片机中则没有, 所以需要用到内部的定时器来实现, 相对来说比较麻烦。 关于51单片机输出PWM波可以参考一下这篇文章:如果利用51单片机输出PWM波
我感觉这个网站对现在我也挺好的。
代码部分:
程序一: 通过P2^0和P2^1口来控制电机的转动, 通过按键来控制电机转动的快慢。
  1. #include <reg52.h>

  2. typedef unsigned int u16;
  3. typedef unsigned char u8;

  4. sbit PWM1 = P2^0;                 
  5. sbit PWM2 = P2^1;
  6. sbit key_add = P3^2;
  7. sbit key_less = P3^3;

  8. u16 count = 50, time;

  9. void init0()
  10. {
  11.         TMOD = 0x01;         // 方式一
  12.         TH0 = (65536 - 10)/256;                // 赋初值
  13.         TL0 = (65536 - 10)%256;
  14.         TR0 = 1;       // 开启定时器0
  15.         EA = 1;                   // 开启总中断
  16.         ET0 = 1;       // 定时器0允许中断
  17. }
  18. void delayms(u16 z)   // 延迟函数
  19. {
  20.         u16 i, j;
  21.         for (i = z; i > 0; i--)
  22.                 for (j = 110; j > 0; j--);
  23. }
  24. void speed_add()     // 加速函数
  25. {
  26.         if (key_add == 0)
  27.         {
  28.                 delayms(2);
  29.                 if (key_add == 0)
  30.                 {
  31.                         count += 5;  // 通过改变占空比来进行加速
  32.                 }
  33.                 while (!key_add);
  34.         }
  35. }
  36. void speed_less()//减速函数
  37. {
  38.         if (key_less == 0)
  39.         {
  40.                 delayms(2);
  41.                 if (key_less == 0)
  42.                 {
  43.                         count -= 5;
  44.                 }
  45.                 while (!key_less);
  46.         }
  47. }  
  48. int main (void)
  49. {
  50.         init0();
  51.         while (1)
  52.         {
  53.                 speed_add();
  54.                 speed_less();        
  55.         }
  56.         return 0;
  57. }
  58. void T0_inter() interrupt 1
  59. {
  60.         TR0 = 0;
  61.         TH0 = (65536 - 10)/256;
  62.         TL0 = (65536 - 10)%256;
  63.         TR0 = 1;
  64.         

  65.         PWM1 = 0;
  66.         time ++ ;
  67.         if (time < count)// 因为总数是100, 所以可以直接看出占空比是多少。
  68.         {
  69.                 PWM2 = 1;
  70.         }
  71.         else
  72.         {
  73.                 PWM2 = 0;
  74.         }
  75.         if (time >= 100)
  76.         {
  77.                 time = 0;
  78.         }
  79. }
复制代码

程序2:
  1. #include<reg52.h>

  2. #define uint unsigned int
  3. #define uchar unsigned char

  4. uchar time,count=50,flag=1;//低电平的占空比

  5. sbit PWM1=P2^0;//PWM 通道 1
  6. sbit PWM2=P2^1;//PWM 通道 2
  7. sbit key_turn=P3^3; //电机换向


  8. void delayxms(uint z);
  9. void Motor_turn(void);
  10. void timer0_init(void);


  11. void main(void)
  12. {
  13.         timer0_init();
  14.         while(1)
  15.         {
  16.                 Motor_turn();
  17.     }
  18. }

  19. void delayxms(uint z)//延时xms程序
  20. {
  21.     uint x,y;
  22.         for(y=z;x>0;x--)
  23.                for(y=110;y>0;y--);
  24. }

  25. /***电机正反向控制****/
  26. void Motor_turn(void)
  27. {
  28.         if(key_turn==0)
  29.         {
  30.                 delayxms(2);//此处时间不能太长,否者会的中断产生冲突
  31.                 if(key_turn==0)
  32.                 {
  33.                         flag=~flag;
  34.                 }
  35.                 while(!key_turn);
  36.         }
  37. }

  38. /***********定时器0初始化***********/
  39. void timer0_init(void)
  40. {
  41.     TMOD=0x01; //定时器0工作于方式1
  42.     TH0=(65536-10)/256;                // 赋初值
  43.     TL0=(65536-10)%256;
  44.     TR0=1;                                         // 开启定时器
  45.     ET0=1;                                         // 允许定时器0中断
  46.         EA=1;                                         // 开启总中断
  47. }

  48. /**************定时0中断处理******************/
  49. void timer0_int(void) interrupt 1
  50. {
  51.         TR0=0;//设置定时器初值期间,关闭定时器
  52.     TH0=(65536-10)/256;
  53.     TL0=(65536-10)%256;
  54.     TR0=1;
  55.     if(flag==1)//电机正转
  56.     {
  57.             PWM1=0;
  58.                 time++;
  59.         if(time<count)        //占空比
  60.         {
  61.                 PWM2=1;
  62.         }
  63.         else
  64.         {
  65.                         PWM2=0;
  66.                }
  67.         if(time>=100)
  68.         {
  69.                 time=0;
  70.         }
  71.         }
  72.     else //电机反转
  73.     {
  74.             PWM2=0;
  75.         time++;
  76.         if(time<count)
  77.         {
  78.                 PWM1=1;
  79.         }
  80.         else
  81.                 {
  82.                 PWM1=0;
  83.                 }
  84.         if(time>=100)
  85.         {
  86.                 time=0;
  87.         }
  88.         }
  89. }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:381204 发表于 2018-9-27 21:40 来自手机 | 只看该作者
谢谢楼主
回复

使用道具 举报

板凳
ID:405334 发表于 2018-10-4 15:55 来自手机 | 只看该作者
好东西
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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