找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于ZYWIFI094小车实现循迹、红外避障、遥控综合程序-采用PWM调速方式

[复制链接]
跳转到指定楼层
楼主
ID:1101034 发表于 2023-11-24 15:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
基于ZYWIFI094小车实现循迹、红外避障、遥控综合程序--采用PWM调速方式
keil工程文件来自实训师傅分享以及自己修改,基于ZYWIFI094小车(STC89C52RC芯片),可以实现循迹红外避障以及遥控等功能。
欢迎大家交流指正!

单片机源程序如下:
  1. /**********************ZYWIFI0939C-WIFI机器人实验板例程************************
  2. *  平台:ZYWIFI0939C-WIFI机器人 + Keil U4 + STC89C52
  3. *  名称:ZY-1智能小车参考程序
  4. *  硬件设置:要有自己动手能力,才能完成实验
  5. *  使用说明:根据下面IO口自己用杜邦线连接各种模块,可以自己修改各种模块IO口
  6. *  视频教程:本小车配套学习C语言详细视频教程,资料统一网盘下载
  7.    重点提示:本程序只做参考,不提供技术支持,请自己研究吸收。
  8.    
  9. ******************************************************************/  
  10. #include <AT89x51.H>
  11. #include <intrins.h>
  12. #include <HJ-4WD_PWM.H>                  //包含HL-1蓝牙智能小车驱动IO口定义等函数
  13. #define Left_1_led        P3_7         //左循迹传感器   

  14. #define Right_1_led       P3_6         //右循迹传感器

  15. #define LeftIRBZ          P3_4         //左避障传感器         

  16. #define RightIRBZ         P3_5         //右避障传感器            

  17. sbit SB1=P2^3;                            //定义蜂鸣器端口
  18. sbit IRIN=P3^3;                                       //定义红外接收端口

  19. unsigned char code  LedShowData[]={0x03,0x9F,0x25,0x0D,0x99,  //定义数码管显示数据
  20.                                    0x49,0x41,0x1F,0x01,0x19};//0,1,2,3,4,5,6,7,8,9
  21. unsigned char code  RecvData[]={0x19,0x46,0x15,0x43,0x44,0x40,0x0d};//遥控器键码
  22. unsigned char IRCOM[7];

  23. //#define ShowPort P0                                   //定义数码管显示端口
  24. unsigned char temp = 1;

  25. void Delay1ms(unsigned int i)         //延时1ms
  26. {
  27. unsigned char j,k;
  28. do{
  29.   j = 10;
  30.   do{
  31.    k = 50;
  32.    do{
  33.     _nop_();
  34.    }while(--k);     
  35.   }while(--j);
  36. }while(--i);

  37. }

  38. void delay_nus(unsigned int i)  //延时:i>=12 ,i的最小延时单12 us
  39. {
  40.   i=i/10;
  41.   while(--i);
  42. }   
  43. void delay_nms(unsigned int n)  //延时n ms
  44. {
  45.   n=n+1;
  46.   while(--n)  
  47.   delay_nus(900);         //延时 1ms,同时进行补偿
  48.   
  49. }  

  50. void delayms(unsigned char x)                         //0.14mS延时程序
  51. {
  52.   unsigned char i;                                    //定义临时变量
  53.   while(x--)                                          //延时时间循环
  54.   {
  55.     for (i = 0; i<13; i++) {}                         //14mS延时
  56.   }
  57. }

  58. void Delay()                                          //定义延时子程序
  59. {
  60.   unsigned int DelayTime=30000;                       //定义延时时间变量
  61.   while(DelayTime--);                                 //开始进行延时循环
  62.   return;                                             //子程序返回
  63. }

  64. void ControlCar_yaokong(unsigned char ConType)    //定义电机控制子程序        (红外遥控单独设置一个 switch  case  语句  )
  65. {

  66.   stop();
  67. switch(ConType)                          //判断用户设定电机形式
  68. {
  69.          case 0:
  70.          {
  71.                  EX1=0;
  72.                   break;
  73.          }
  74.   case 1:  //前进                         //判断用户是否选择形式1
  75.   {
  76.     stop();                                                      //进入前进之前 先停止一段时间  防止电机反向电压冲击主板 导致系统复位
  77.         Delay1ms(150);
  78.         run();
  79.     break;
  80.   }
  81.   case 2: //后退                          //判断用户是否选择形式2
  82.   {
  83.     stop();                                                                      //进入后退之前 先停止一段时间  防止电机反向电压冲击主板 导致系统复位
  84.     Delay1ms(150);         
  85.         back();                                 //M2电机反转
  86.     break;
  87.   }
  88.   case 3: //右转                          //判断用户是否选择形式3
  89.   {
  90.      stop();                                                                  //进入左转之前 先停止一段时间  防止电机反向电压冲击主板 导致系统复位
  91.          Delay1ms(150);
  92.          rightrun1s();                                //M2电机正转
  93.          break;
  94.   }
  95.   case 4: //左转                          //判断用户是否选择形式4
  96.   {
  97.      stop();                                                                  //进入右转之前 先停止一段时间  防止电机反向电压冲击主板 导致系统复位
  98.          Delay1ms(150);
  99.      leftrun1s();                                  //M1电机正转  //M2电机反转
  100.           break;
  101.   }
  102.   case 5: //停止                          //判断用户是否选择形式5
  103.   {
  104.     stop();
  105.         break;                                //退出当前选择
  106.   }
  107. }
  108. }

  109. //机器人避障子程序   0代表有障碍
  110. void Robot_Avoidance()                  
  111. {
  112.             
  113.                                   if((RightIRBZ&LeftIRBZ)==0)                //检测到障碍
  114.                                   {         
  115.                                    SB1=0;                //蜂鸣器响
  116.                                          stop();                     //停止
  117.            Delay1ms(200);                 //停止MS   防止电机反相电压冲击  导致系统复位
  118.                                          back();                         //小车后退
  119.                                         Delay1ms(300);         //后退ms
  120.                                                 SB1=1;
  121.                                                  stop();
  122.                                                 EX1=1;
  123.                                                 while(IRCOM[2]!=RecvData[0])
  124.                                                 {
  125.                                                         EX1=1;
  126.                                                 }

  127.                                   }
  128.                   
  129. }
  130. //机器人循迹子程序
  131. void Robot_Traction()                     //机器人循迹子程序   1代表检测到黑线
  132. {
  133.   
  134.    //SB1=1;
  135.    if(Left_1_led  == 0 && Right_1_led == 0)    //没检测到黑线,就前进,1代表检测到黑线         Left_1_led           Right_1_led
  136.    {
  137.       run();                     
  138.       delay_nms (10);
  139.           SB1=1;
  140.    }
  141.    
  142.    else if(Left_1_led  == 0 && Right_1_led == 1)
  143.    {
  144.       rightrun();                       //右侧检测到黑线,开始向右转一定的角度
  145.       delay_nms (10);
  146.    }

  147.    else if(Left_1_led  == 1 &&  Right_1_led == 0)
  148.    {
  149.       leftrun();                         //左侧检测到黑线,开始向左转一定的角度
  150.          
  151.       delay_nms (10);
  152.    }
  153.    else if(Left_1_led  == 1 &&  Right_1_led == 1)
  154.    {
  155.       SB1=1;
  156.           stop();                         //左右都检测到黑线,停止
  157.          
  158.       delay_nms (10);
  159.    }
  160.      
  161. }

  162. //----------红外遥控-------------------------------------------------------------
  163. void IR_IN() interrupt 2 using 0                      //定义INT2外部中断函数
  164. {
  165.   unsigned char j,k,N=0;                              //定义临时接收变量
  166.   
  167.   EX1 = 0;                                            //关闭外部中断,防止再有信号到达   
  168.   delayms(15);                                        //延时时间,进行红外消抖
  169.   if (IRIN==1)                                        //判断红外信号是否消失
  170.   {  
  171.      EX1 =1;                                          //外部中断 开
  172.          return;                                          //返回
  173.   }
  174.                            
  175.   while (!IRIN)                                       //等IR变为高电平,跳过9ms的前导低电平信号。
  176.   {
  177.       delayms(1);                                     //延时等待
  178.   }

  179.   for (j=0;j<4;j++)                                   //采集红外遥控器数据
  180.   {
  181.     for (k=0;k<8;k++)                                 //分次采集8位数据
  182.     {
  183.        while (IRIN)                                   //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
  184.        {
  185.          delayms(1);                                  //延时等待
  186.        }
  187.       
  188.        while (!IRIN)                                  //等 IR 变为高电平
  189.        {
  190.          delayms(1);                                  //延时等待
  191.        }
  192.    
  193.        while (IRIN)                                   //计算IR高电平时长
  194.        {
  195.          delayms(1);                                  //延时等待
  196.          N++;                                         //计数器加加
  197.          if (N>=30)                                   //判断计数器累加值
  198.              {
  199.            EX1=1;                                     //打开外部中断功能
  200.                return;                                    //返回
  201.          }                  
  202.        }
  203.                                        
  204.       IRCOM[j]=IRCOM[j] >> 1;                         //进行数据位移操作并自动补零
  205.      
  206.       if (N>=8)                                       //判断数据长度
  207.       {
  208.          IRCOM[j] = IRCOM[j] | 0x80;                  //数据最高位补1
  209.       }
  210.       N=0;                                            //清零位数计录器
  211.     }
  212.   }
  213.    
  214.   if (IRCOM[2]!=~IRCOM[3])                            //判断地址码是否相同
  215.   {
  216.      EX1=1;                                           //打开外部中断
  217.      return;                                          //返回
  218.   }



  219.   for(j=0;j<7;j++)                                   //循环进行键码解析
  220.    {
  221.       if(IRCOM[2]==RecvData[j])                       //进行键位对应
  222.       {
  223.                 ControlCar_yaokong(j);                               //遥控按键相应数码
  224.       }
  225.    }

  226.    EX1 = 0;                                           //外部中断关
  227. }
  228. //-------------------------------------------------------------------------------------------------------
  229. void main()                               //主程序入口
  230. {
  231.   TMOD=0X01;
  232.   TH0= 0XFc;                  //1ms定时
  233.   TL0= 0X18;
  234.   TR0= 1;
  235.   ET0= 1;
  236.   EA = 1;                           //开总中断                                              //同意开启外部中断1
  237.   IT1=1;                                               //设定外部中断1为低边缘触发类型

  238.   while(1)                                //程序主循环
  239.   {
  240.                
  241. //  Robot_Traction();               //寻迹
  242.                 EX1=1;
  243.                 if(IRCOM[2]==RecvData[6])   //遥控上的200+
  244.                 {
  245.                         stop();
  246.                         while(IRCOM[2]!=RecvData[0])    //遥控上的100+
  247.                         {
  248.                                 EX1=1;
  249.                         }
  250.                         IRCOM[2]=0x00;
  251.                 }
  252.                 Robot_Traction();               //寻迹
  253.   Robot_Avoidance();              //避障
  254.          
  255.   }
  256. }
复制代码

原理图: 无
仿真: 无
代码: 循迹、红外避障、遥控综合程序--PWM调速.7z (631.5 KB, 下载次数: 17)

评分

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

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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