找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7835|回复: 2
收起左侧

六路循迹时间显示小车

[复制链接]
ID:117724 发表于 2016-6-11 23:04 | 显示全部楼层 |阅读模式
六路循迹小车,红外模块作循迹部分,主控芯片用STC89C52RC,lcd1602显示小车行驶时间,小车通过设定标志位来通过复杂的赛道,小车赛道如图:

白色区域是上坡,两个凹槽是障碍物

白色区域是上坡,两个凹槽是障碍物


对赛道解析:中间白色,两边黑色的是桥,蓝色的区域是一个坡,中间的凹槽是障碍物.

程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. sbit En_L=P1^4;
  6. sbit En_R=P1^5;        //定义使能端

  7. sbit l2 = P2^0;
  8. sbit ml = P2^1;
  9. sbit r2 = P2^2;
  10. sbit mr = P2^3;
  11. sbit l1 = P1^6;
  12. sbit r1 = P1^7;       //定义传感器位置: (l1) (l2) (ml) (mr) (r2) (r1)
  13.                                          
  14. sbit IN1 = P1^0;
  15. sbit IN2 = P1^1;
  16. sbit IN3 = P1^2;
  17. sbit IN4 = P1^3;      //定义驱动IO口
  18. uchar count,num;
  19. uchar bz=0;          //定义标志位
  20. #define PWM_CHUZHI 100
  21. #define S_CIRCLE 100
  22. uchar Speed_L_Now;
  23. uchar Speed_R_Now;          //左右轮实时速度

  24. #define Data P0                    //lcd数据端口
  25. sbit RS = P2^7;                            //lcd的rs口
  26. sbit RW = P2^6;                                //lcd的rw口
  27. sbit E = P2^5;                            //lcd的e口
  28. int sec=0,min=0;
  29. uchar FirstLine[]="  Time:00min00s";
  30. /********功能函数********/
  31. /***延时函数***/
  32. void DelayMs(uint z)
  33. {
  34.         uint x,y;
  35.         for(x=z;x>0;x--)
  36.                 for(y=110;y>0;y--);
  37. }
  38. /******液晶写命令******/
  39. void lcd_write_com(uchar c)
  40. {
  41.         DelayMs(5);       //操作前短暂延时,保证信号稳定
  42.         E=0;
  43.         RS=0;
  44.         RW=0;
  45.         _nop_();
  46.         E=1;
  47.         Data=c;
  48.         E=0;
  49. }
  50. /*****写数据*****/
  51. void lcd_write_dat(uchar c)
  52. {
  53.         DelayMs(5);// 操作前短暂延时,保证信号稳定
  54.         E=0;
  55.         RS=1;
  56.         RW=0;
  57.         _nop_();
  58.         E=1;
  59.         Data=c;
  60.         E=0;
  61.         RS=0;
  62. }
  63. /*******LCD初始化****/
  64. void lcd_init()
  65. {
  66.         DelayMs(15);
  67.         lcd_write_com(0x38);
  68.         DelayMs(10);
  69.         lcd_write_com(0x38);
  70.         DelayMs(10);
  71.         lcd_write_com(0x38);
  72.         DelayMs(10);
  73.         lcd_write_com(0x06);
  74.         DelayMs(10);                  //显示光标移动位置
  75.         lcd_write_com(0x0c);
  76.         DelayMs(10);                  //显示开及光标设置
  77.         lcd_write_com(0x01);
  78.         DelayMs(10);                  //显示清屏
  79.         for(num=0;num<15;num++)
  80.         {
  81.                 lcd_write_dat(FirstLine[num]);     //将“Time:”写入LCD
  82.                 DelayMs(5);       
  83.         }
  84. }


  85. /****定时器T1:液晶实时显示***/
  86. void timer1()interrupt 3
  87. {
  88.         TH1=(65536-50000)/256;
  89.         TL1=(65536-50000)%256;
  90.         count++;        
  91. }

  92. /******定时器0用于输出PWM控制电机速度*******/
  93. void motor_pwm_out()interrupt 1
  94. {
  95.         static uchar count;
  96.         TH0=(65536-PWM_CHUZHI)/256;
  97.         TL0=(65536-PWM_CHUZHI)%256;
  98.         count++;
  99.         if(count>=Speed_L_Now)
  100.   {
  101.         En_L=0;       
  102.   }
  103.         if(count>=Speed_R_Now)
  104.         {
  105.                 En_R=0;
  106.         }
  107.         if(count==S_CIRCLE)
  108.         {
  109.                 En_L=1;
  110.                 En_R=1;
  111.                 count=0;       
  112.         }
  113. }
  114. void write_fm(uchar add,uchar date)   //将分秒写进lcd的函数
  115. {       
  116.         uint shi,ge;
  117.         lcd_write_com(0x80+add);
  118.         shi=date/10;
  119.         ge =date%10;
  120.         lcd_write_dat(0x30+shi);
  121.         lcd_write_dat(0x30+ge);
  122. }
  123. void ahead()     //前进函数
  124. {
  125.         IN1=1;
  126.         IN2=0;
  127.         IN3=1;
  128.         IN4=0;
  129.         Speed_L_Now=46;
  130.         Speed_R_Now=43;
  131. }
  132. void poahead()     //上坡后的前进函数
  133. {
  134.         IN1=1;
  135.         IN2=0;
  136.         IN3=1;
  137.         IN4=0;
  138.         Speed_L_Now=43;
  139.         Speed_R_Now=40;
  140. }
  141. void turn_left()   //左转函数
  142. {
  143.         IN1=0;
  144.         IN2=1;
  145.         IN3=1;
  146.         IN4=0;
  147.         Speed_L_Now=44;
  148.         Speed_R_Now=42;
  149. }
  150. void turn_right()    //右转函数
  151. {
  152.         IN1=1;
  153.         IN2=0;
  154.         IN3=0;
  155.         IN4=1;
  156.         Speed_L_Now=44;
  157.         Speed_R_Now=42;
  158. }
  159. void big_turn()   //上坡后大转弯函数
  160. {
  161.         IN1=1;
  162.         IN2=0;
  163.         IN3=0;
  164.         IN4=1;
  165.         Speed_L_Now=43;
  166.         Speed_R_Now=20;               
  167. }
  168. void stop()          //停止函数
  169. {
  170.         IN1=0;
  171.         IN2=0;
  172.         IN3=0;
  173.         IN4=0;
  174. }
  175. void xunji1()    //循迹控制函数
  176. {
  177.         if(l1==0&&ml==0&&r1==0&&mr==0&&l2==0&&r2==0)  //六个都没检测到黑线
  178.         ahead();
  179.         if(l1==1&&ml==0&&r1==0&&mr==0&&l2==0&&r2==0)  //l1检测到
  180.         turn_left();
  181.         if(l1==0&&ml==0&&r1==0&&mr==0&&l2==1&&r2==0)  //l2检测到
  182.         turn_left();
  183.         if(l1==1&&ml==1&&r1==0&&mr==0&&l2==1&&r2==0)  //l1,l2,ml检测到
  184.         ahead();
  185.         if(l1==0&&ml==1&&r1==0&&mr==0&&l2==1&&r2==0)  //l2,ml检测到
  186.         turn_left();
  187.         if(l1==0&&ml==0&&r1==1&&mr==0&&l2==0&&r2==1)  //r1,r2检测到
  188.         turn_right();
  189.         if(l1==0&&ml==0&&r1==0&&mr==1&&l2==0&&r2==1)  //mr,r2检测到
  190.         turn_right();
  191.         if(l1==0&&ml==1&&r1==0&&mr==0&&l2==0&&r2==0)  //ml检测到
  192.         turn_left();
  193.         if(l1==0&&ml==1&&mr==1&&r1==0&&l2==0&&r2==0) //ml,mr检测到
  194.         poahead();
  195.         if(l1==0&&ml==0&&mr==1&&r1==0&&l2==0&&r2==0) //mr检测到
  196.         turn_right();
  197.         if(l1==0&&ml==0&&mr==0&&r1==1&&l2==0&&r2==0) //r1检测到
  198.         turn_right();
  199.         if(l1==0&&ml==0&&mr==1&&r1==0&&l2==0&&r2==1) //mr,r2检测到
  200.         turn_right();
  201.         if(l1==0&&ml==0&&mr==1&&r1==1&&l2==0&&r2==1) //r1,r2,mr检测到
  202.         ahead();
  203.         if(l1==0&&ml==1&&mr==1&&r1==1&&l2==0&&r2==1) //r1,r2,mr,ml检测到
  204.         ahead();
  205.         if(l1==1&&ml==1&&mr==1&&r1==0&&l2==1&&r2==0) //l1,l2,mr,ml检测到
  206.         ahead();
  207.         if(l1==0&&ml==1&&mr==1&&r1==0&&l2==1&&r2==1) //l2,r2,ml,mr检测到
  208.         ahead();               
  209.         if(l1==1&&ml==1&&mr==1&&r1==1&&l2==1&&r2==1) //六个都检测到
  210.         ahead();       
  211. }
  212. void xunji2()
  213. {
  214.         if(l1==0&&ml==0&&r1==0&&mr==0&&l2==0&&r2==0)  //六个都没检测到黑线
  215.         ahead();
  216.         if(l1==1&&ml==0&&r1==0&&mr==0&&l2==0&&r2==0)  //l1检测到
  217.         turn_right();
  218.         if(l1==0&&ml==0&&r1==0&&mr==0&&l2==1&&r2==0)  //l2检测到
  219.         turn_right();
  220.         if(l1==1&&ml==1&&r1==0&&mr==0&&l2==1&&r2==0)  //l1,l2,ml检测到
  221.         ahead();
  222.         if(l1==0&&ml==1&&r1==0&&mr==0&&l2==1&&r2==0)  //l2,ml检测到
  223.         turn_right();
  224.         if(l1==0&&ml==0&&r1==1&&mr==0&&l2==0&&r2==1)  //r1,r2检测到
  225.         turn_left();
  226.         if(l1==0&&ml==0&&r1==0&&mr==1&&l2==0&&r2==1)  //mr,r2检测到
  227.         turn_left();
  228.         if(l1==0&&ml==0&&mr==0&&r1==1&&l2==0&&r2==0) //r1检测到
  229.         turn_left();
  230.         if(l1==0&&ml==0&&mr==1&&r1==0&&l2==0&&r2==1) //mr,r2检测到
  231.         turn_left();
  232.         if(l1==0&&ml==0&&mr==1&&r1==1&&l2==0&&r2==1) //r1,r2,mr检测到
  233.         ahead();
  234.         if(l1==1&&ml==1&&mr==1&&r1==0&&l2==1&&r2==0) //l1,l2,mr,ml检测到
  235.         big_turn();
  236.         if(l1==0&&ml==1&&mr==1&&r1==1&&l2==0&&r2==1) //r1,r2,mr,ml检测到
  237.         turn_right();               
  238.         if(l1==1&&ml==1&&mr==1&&r1==1&&l2==1&&r2==1) //六个都检测到
  239.         big_turn();         
  240.         bz++;               
  241. }
  242. void xunji3()
  243. {
  244.         if(l1==0&&ml==0&&r1==0&&mr==0&&l2==0&&r2==0)  //六个都没检测到黑线
  245.         poahead();
  246.         if(l1==1&&ml==0&&r1==0&&mr==0&&l2==0&&r2==0)  //l1检测到
  247.         turn_right();
  248.         if(l1==0&&ml==0&&r1==0&&mr==0&&l2==1&&r2==0)  //l2检测到
  249.         turn_right();
  250.         if(l1==1&&ml==1&&r1==0&&mr==0&&l2==1&&r2==0)  //l1,l2,ml检测到
  251.         turn_right();
  252.         if(l1==0&&ml==1&&r1==0&&mr==0&&l2==1&&r2==0)  //l2,ml检测到
  253.         turn_right();
  254.         if(l1==0&&ml==0&&r1==1&&mr==0&&l2==0&&r2==1)  //r1,r2检测到
  255.         turn_left();
  256.         if(l1==0&&ml==0&&r1==0&&mr==1&&l2==0&&r2==1)  //mr,r2检测到
  257.         turn_left();
  258.         if(l1==0&&ml==0&&mr==0&&r1==1&&l2==0&&r2==0) //r1检测到
  259.         turn_left();
  260.         if(l1==0&&ml==0&&mr==1&&r1==0&&l2==0&&r2==1) //mr,r2检测到
  261.         turn_left();
  262.         if(l1==0&&ml==0&&mr==1&&r1==1&&l2==0&&r2==1) //r1,r2,mr检测到
  263.         turn_left();
  264.         if(l1==0&&ml==1&&mr==1&&r1==1&&l2==0&&r2==1) //r1,r2,mr,ml检测到
  265.         turn_right();               
  266.         if(l1==1&&ml==1&&mr==1&&r1==1&&l2==1&&r2==1) //六个都检测到
  267.         poahead();                        
  268.         bz++;               
  269. }
  270. void xunji4()
  271. {
  272.         if(l1==0&&ml==0&&r1==0&&mr==0&&l2==0&&r2==0)  //六个都没检测到黑线
  273.         poahead();
  274.         if(l1==1&&ml==0&&r1==0&&mr==0&&l2==0&&r2==0)  //l1检测到
  275.         turn_right();
  276.         if(l1==0&&ml==0&&r1==0&&mr==0&&l2==1&&r2==0)  //l2检测到
  277.         turn_right();
  278.         if(l1==1&&ml==1&&r1==0&&mr==0&&l2==1&&r2==0)  //l1,l2,ml检测到
  279.         poahead();
  280.         if(l1==0&&ml==1&&r1==0&&mr==0&&l2==1&&r2==0)  //l2,ml检测到
  281.         turn_right();
  282.         if(l1==0&&ml==0&&r1==1&&mr==0&&l2==0&&r2==1)  //r1,r2检测到
  283.         turn_left();
  284.         if(l1==0&&ml==0&&r1==0&&mr==1&&l2==0&&r2==1)  //mr,r2检测到
  285.         turn_left();
  286.         if(l1==0&&ml==0&&mr==0&&r1==1&&l2==0&&r2==0) //r1检测到
  287.         turn_left();
  288.         if(l1==0&&ml==0&&mr==1&&r1==0&&l2==0&&r2==1) //mr,r2检测到
  289.         turn_left();
  290.         if(l1==0&&ml==0&&mr==1&&r1==1&&l2==0&&r2==1) //r1,r2,mr检测到
  291.         poahead();
  292.         if(l1==1&&ml==1&&mr==1&&r1==0&&l2==1&&r2==0) //l1,l2,mr,ml检测到
  293.         poahead();
  294.         if(l1==0&&ml==1&&mr==1&&r1==1&&l2==0&&r2==1) //r1,r2,mr,ml检测到
  295.         poahead();               
  296.         if(l1==1&&ml==1&&mr==1&&r1==1&&l2==1&&r2==1) //六个都检测到
  297.         stop();
  298. }

  299. /******mcu初始化*******/
  300.         void mcu_init()
  301. {
  302.         TMOD=0x11;                    // 设置定时器0和为工作方式1(0001 0001)
  303.         TH0=(65536-PWM_CHUZHI)/256;  //装初值
  304.         TL0=(65536-PWM_CHUZHI)%256;
  305.         TH1=(65536-50000)/256;     //装初值(50ms溢出一次)
  306.         TL1=(65536-50000)%256;
  307.         EA=1;                //开总中断
  308.         ET0=1;                //开定时器0中断
  309.         ET1=1;                //开定时器1中断
  310.         TR0=1;                //启动定时器0
  311.         TR1=1;           //启动定时器1
  312.                                        
  313.         IT0=1;
  314.         IT1=1;
  315.         EX0=1;
  316.         EX1=1;
  317.         En_L=1;
  318.         En_R=1;
  319.         ahead();       
  320. }
  321. /*********main********/       
  322.         void main()
  323. {                               
  324.         lcd_init();                        //液晶初始化
  325.         DelayMs(20);
  326.         mcu_init();                    //mcu初始化
  327.         while(1)
  328.     {         
  329.                 switch(bz)
  330.                 {
  331.                   case 0: xunji1();break;
  332.                   case 1: xunji1();break;
  333.                   case 2: xunji1();break;
  334.                   case 3: xunji2();break;
  335.                   case 4: xunji2();break;
  336.                   case 5: xunji3();break;
  337.                   case 6: xunji4();break;
  338.                   default: xunji4();               
  339.                 }
  340.                  if(count==20)                          //将分和秒的数值写进lcd
  341.                 {
  342.                         count=0;
  343.                         sec++;
  344.                         if(sec==60)
  345.                         {
  346.                           sec=0;
  347.                           min++;
  348.                         }                                                  
  349.                         write_fm(12,sec);
  350.                         write_fm(7,min);                       
  351.                 }               
  352.         }
  353.   }

复制代码



注:小车选择上坡和过桥,不绕过障碍物

循迹小车.zip

36.3 KB, 下载次数: 27, 下载积分: 黑币 -5

循迹小车程序

评分

参与人数 2黑币 +105 收起 理由
sax_yang + 5 很给力!
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:126509 发表于 2016-6-13 22:02 | 显示全部楼层
我爱你版主亲爱的母亲
回复

使用道具 举报

ID:146651 发表于 2016-11-8 08:42 | 显示全部楼层
好资料,收藏学习了,评分给您5黑币。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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