找回密码
 立即注册

QQ登录

只需一步,快速开始

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

舵机超声波避障的单片机程序

  [复制链接]
跳转到指定楼层
楼主
ID:147905 发表于 2017-11-15 23:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
舵机超声波避障和警灯闪烁
用别人的程序改的自己加了一些别的功能(我也是边学边做的这辆车可能有的地方不对大家多指点
有需要的可以拿去用,肯定成功
单片机用的是 89c52
超声波是rs04
电机驱动L298N
程序注释的已经很详细了!
  1. /******************************************************************************
  2. 2017.11.14修改
  3. 删除额外数码管功能
  4. 加入闪烁警灯程序
  5. ******************************************************************************/
  6.         #include <AT89x52.H>
  7.         #include <intrins.h>
  8.         #define led1 {P2_0=1,P2_1=0;}
  9.         #define led2 {P2_0=0,P2_1=1;}
  10.         
  11.         /**********如果io口不够用可以去掉2^4~2^7口将298使能接口接高电平即可***********/
  12.         #define Right_moto_go     {P0_0=1,P0_1=0,P0_2=1,P0_3=0,P2_7=1,P2_6=1,P2_5=1,P2_4=1;}        //右边电机向前走
  13.         #define Right_moto_back   {P0_0=0,P0_1=1,P0_2=0,P0_3=1,P2_7=1,P2_6=1,P2_5=1,P2_4=1;}        //右边电机向后走
  14.         #define Right_moto_Stop   {P0_0=1,P0_1=1,P0_2=1,P0_3=1,P2_7=1,P2_6=1,P2_5=1,P2_4=1;}        //右边电机停转   

  15.         #define Left_moto_go      {P0_4=0,P0_5=1,P0_6=0,P0_7=1,P2_7=1,P2_6=1,P2_5=1,P2_4=1;}  //左边电机向前走
  16.         #define Left_moto_back    {P0_4=1,P0_5=0,P0_6=1,P0_7=0,P2_7=1,P2_6=1,P2_5=1,P2_4=1;}         //左边电机向后转
  17.         #define Left_moto_Stop    {P0_4=1,P0_5=1,P0_6=1,P0_7=1,P2_7=1,P2_6=1,P2_5=1,P2_4=1;}  //左边电机停转                     
  18.         /*****************************************************************************/
  19.         
  20.         #define Sevro_moto_pwm  P1_2      //接舵机信号端输入PWM信号调节速度
  21.         #define  ECHO  P1_1                                        //超声波接口定义
  22.         #define  TRIG  P1_0                                        //超声波接口定义
  23.         
  24.         
  25.   unsigned char const discode[] ={ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xBF,0xff/*-*/};
  26.         unsigned char const positon[3]={ 0xfe,0xfd,0xfb};
  27.         unsigned char disbuff[4]={ 0,0,0,0,};
  28.   unsigned char posit=0;

  29.   unsigned char pwm_val_left  = 0;//变量定义
  30.         unsigned char push_val_left =14;//舵机归中,产生约,1.5MS 信号
  31.   unsigned long S=0;
  32.         unsigned long S1=0;
  33.         unsigned long S2=0;
  34.         unsigned long S3=0;
  35.         unsigned long S4=0;
  36.         unsigned int  time=0;                    //时间变量
  37.         unsigned int  timer=0;                        //延时基准变量
  38.         unsigned char timer1=0;                        //扫描时间变量                                       
  39.    
  40. /************************************************************************/        
  41. //延时函数        
  42.    void delay(unsigned int k)
  43.                         {                                
  44.                                  unsigned int x,y;
  45.                                  for(x=0;x<k;x++)
  46.                                  for(y=0;y<2000;y++);
  47.                         }
  48. /************************************************************************/        
  49. //前速前进
  50.     void  run(void)
  51. {
  52.    
  53.          Left_moto_go;    //左电机往前走
  54.          Right_moto_go ;  //右电机往前走
  55. }

  56. //前速后退
  57.     void  backrun(void)
  58. {
  59.    
  60.          Left_moto_back ;   //左电机往前走
  61.          Right_moto_back ;  //右电机往前走
  62. }

  63. //左转
  64.     void  leftrun(void)
  65. {
  66.    
  67.          Right_moto_go ;  //右电机往前走 ;
  68.          Left_moto_Stop ;   //左电机停止
  69. }

  70. //右转
  71.     void  rightrun(void)
  72. {
  73.    
  74.          Left_moto_go ;   //左电机往前走
  75.          Right_moto_Stop ;  //右电机停止
  76. }
  77. //停
  78.     void  stoprun(void)
  79. {
  80.    
  81.          Left_moto_Stop ;   //左电机往前走
  82.          Right_moto_Stop ;  //右电机往前走
  83. }


  84. //****************************去除额外功能********************************/
  85. //  void Display(void)                                  //扫描数码管
  86. //        {
  87. //         if(posit==0)
  88. //         {P3=(discode[disbuff[posit]])&0x7f;}//产生点
  89. //         else
  90. //         {P3=discode[disbuff[posit]];}
  91. //          if(posit==0)
  92. //         { P1_3=0;P1_4=1;P1_5=1;}
  93. //          if(posit==1)
  94. //          {P1_3=1;P1_4=0;P1_5=1;}
  95. //          if(posit==2)
  96. //          {P1_3=1;P1_4=1;P1_5=0;}
  97. //          if(++posit>=3)
  98. //          posit=0;
  99. //        }
  100. //************************************************************************/


  101. void  StartModule()                       //启动测距信号
  102.    {
  103.           TRIG=1;                                       
  104.           _nop_();
  105.           _nop_();
  106.           _nop_();
  107.           _nop_();
  108.           _nop_();
  109.           _nop_();
  110.           _nop_();
  111.           _nop_();
  112.           _nop_();
  113.           _nop_();
  114.           _nop_();
  115.           _nop_();
  116.           _nop_();
  117.           _nop_();
  118.           _nop_();
  119.           _nop_();
  120.           _nop_();
  121.           _nop_();
  122.           _nop_();
  123.           _nop_();
  124.           _nop_();
  125.           TRIG=0;
  126.    }
  127. /***************************************************/
  128. void Conut(void)                   //计算距离
  129.         {
  130.           while(!ECHO);                       //当RX为零时等待
  131.           TR0=1;                               //开启计数
  132.           while(ECHO);                           //当RX为1计数并等待
  133.           TR0=0;                                   //关闭计数
  134.           time=TH0*256+TL0;                   //读取脉宽长度
  135.           TH0=0;
  136.           TL0=0;
  137.           S=(time*1.7)/100;        //算出来是CM
  138.           disbuff[0]=S%1000/100;   //更新显示
  139.           disbuff[1]=S%1000%100/10;
  140.           disbuff[2]=S%1000%10 %10;
  141.         }
  142. /************************************************************************/
  143. void  COMM( void )                       
  144.   {
  145.                
  146.                  
  147.                   push_val_left=5;          //舵机向左转90度
  148.                   timer=0;
  149.                   while(timer<=4000); //延时400MS让舵机转到其位置
  150.                   StartModule();          //启动超声波测距
  151.           Conut();                           //计算距离
  152.                   S2=S;  
  153.   
  154.                   push_val_left=23;          //舵机向右转90度
  155.                   timer=0;
  156.                   while(timer<=4000); //延时400MS让舵机转到其位置
  157.                   StartModule();          //启动超声波测距
  158.           Conut();                          //计算距离
  159.                   S4=S;         
  160.         

  161.                   push_val_left=14;          //舵机归中
  162.                   timer=0;
  163.                   while(timer<=4000); //延时400MS让舵机转到其位置
  164.                   StartModule();          //启动超声波测距
  165.           Conut();                          //计算距离
  166.                   S1=S;         

  167.           if((S2<20)||(S4<20)) //只要左右各有距离小于,20CM小车后退
  168.                   {
  169.                   backrun();                   //后退
  170.                   timer=0;
  171.                   while(timer<=4000);
  172.                   }
  173.                   
  174.                   if(S2>S4)                 
  175.                      {
  176.                                     rightrun();          //车的左边比车的右边距离小        右转        
  177.                         timer=0;
  178.                         while(timer<=3500);//原4000
  179.                      }                                      
  180.                        else
  181.                      {
  182.                        leftrun();                //车的左边比车的右边距离大        左转
  183.                        timer=0;
  184.                        while(timer<=3500);//原4000
  185.                      }
  186.                                              

  187. }
  188. /*调节push_val_left的值改变电机转速,占空比            */
  189.                 void pwm_Servomoto(void)
  190. {  

  191.   if(pwm_val_left<=push_val_left)
  192.                Sevro_moto_pwm=1;
  193.         else
  194.                Sevro_moto_pwm=0;
  195.         if(pwm_val_left>=200)
  196.         pwm_val_left=0;
  197. }
  198. /***************************************************/
  199. ///*TIMER1中断服务子函数产生PWM信号*/
  200.          void time1()interrupt 3   using 2
  201. {        
  202.    TH1=(65536-100)/256;          //100US定时
  203.          TL1=(65536-100)%256;
  204.          timer++;                                  //定时器100US为准。在这个基础上延时
  205.          pwm_val_left++;
  206.          pwm_Servomoto();
  207. //         timer1++;                                 //2MS扫一次数码管
  208. //         if(timer1>=20)
  209. //         {
  210. //         timer1=0;
  211. //         Display();        
  212. //         }
  213. }
  214. /************************************************************************/

  215. /*****************************闪烁灯中断延时函数****************************/
  216. void delay1()
  217. {
  218.         unsigned char i,j,k;
  219.         for(i=1;i>0;i--)
  220.         for(j=100;j>0;j--)
  221.         for(k=250;k>0;k--);
  222. }
  223. void shansuo()
  224.          {
  225.                  led1;
  226.                  delay1();
  227.                  led2;
  228.                  delay1();                 
  229.          }
  230. /***********************************************************************/
  231. /*********************************************************************/                 
  232. /*--主函数--*/
  233.         void main(void)
  234. {
  235.   stoprun();
  236.         TMOD=0X11;
  237.         TH1=(65536-100)/256;          //100US定时
  238.         TL1=(65536-100)%256;
  239.         TH0=0;
  240.         TL0=0;  
  241.         TR1= 1;
  242.         ET1= 1;
  243.         ET0= 1;
  244.         EA = 1;

  245.         delay(100);
  246.   push_val_left=14;          //舵机归中


  247.         while(1)                       /*无限循环*/
  248.         {
  249.          shansuo();        //闪烁灯函数
  250.          if(timer>=200)          //100MS检测启动检测一次 原来500
  251.            {
  252.              timer=0;
  253.                    StartModule(); //启动检测
  254.        Conut();                  //计算距离
  255.        if(S<35)                  //距离小于20CM
  256.                    {
  257.                     stoprun();          //小车停止
  258.                     COMM();                                  //方向函数
  259.                    }
  260.                    else
  261.                    if(S>40)                  //距离大于,35CM往前走
  262.                    run();
  263.            }
  264.         }
  265. }
复制代码
全部资料51hei下载地址:
避障加警灯完.rar (38.36 KB, 下载次数: 198)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:262587 发表于 2017-12-17 10:55 | 只看该作者
很不错,正需要,感谢楼主
回复

使用道具 举报

板凳
ID:292103 发表于 2018-5-8 19:03 来自手机 | 只看该作者
好!写的不错
回复

使用道具 举报

地板
ID:297685 发表于 2018-5-9 08:41 | 只看该作者
有照片吗?
回复

使用道具 举报

5#
ID:292103 发表于 2018-5-19 10:29 | 只看该作者
为什么不能解压呢?
回复

使用道具 举报

6#
ID:382500 发表于 2018-8-9 23:27 | 只看该作者
电机怎么接线
回复

使用道具 举报

7#
ID:879227 发表于 2021-6-18 16:49 | 只看该作者
感谢楼主的分析,学到了不少知识,现在去进行测试。
回复

使用道具 举报

8#
ID:969453 发表于 2022-2-28 18:02 | 只看该作者
就想单纯的想小车避障,把数码管相关的删掉就行了吧,博主大佬
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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