找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3190|回复: 6
收起左侧

51单片机循迹车的一点程序问题(环岛)

[复制链接]
ID:590125 发表于 2019-8-10 16:57 | 显示全部楼层 |阅读模式
先贴本人自己写出来的程序吧。
图片1.png
问题是在环岛扫到全黑的情况与全黑停车情况的判断,车子扫到全黑时总是突然开始倒车并附有卡顿挺迷的。希望大家能给个好建议。
PS.如果轮子转速太快红外测速无法记录外部中断怎么整?

单片机源程序如下:
  1. #include<reg52.h>
  2. #include<stdio.h>
  3. #include<intrins.h>
  4. #include<stdlib.h>
  5. sbit left1=P1^0;
  6. sbit left2=P1^1;                         //定义前方左侧红外探头端口
  7. sbit right1=P1^2;
  8. sbit right2=P1^3;                         //定义前方右侧红外探头端口

  9. //sbit ENA=P1^4;
  10. //sbit ENB=P1^5;
  11. //sbit ENC=P1^6;
  12. //sbit END=P1^7;


  13. sbit L2A=P0^0;                            //定义左侧电机驱动A端
  14. sbit L2B=P0^1;                            //定义左侧电机驱动B端

  15. sbit R2A=P0^2;                            //定义右侧电机驱动A端
  16. sbit R2B=P0^3;                            //定义右侧电机驱动B端

  17. sbit L1A=P0^4;                            //定义左侧电机驱动A端
  18. sbit L1B=P0^5;                            //定义左侧电机驱动B端

  19. sbit R1A=P0^6;                            //定义右侧电机驱动A端
  20. sbit R1B=P0^7;                            //定义右侧电机驱动B端

  21. typedef unsigned int uint;
  22. typedef unsigned char uchar ;

  23. uchar R_data;
  24. bit R_flag=0;
  25. int tim=0;
  26. int x=0;
  27. int count = 0;
  28. int  v_speed,Distance=0,time=0;
  29. char speed[7];
  30. int PWM1 = 0;
  31. int PWM2 = 0;
  32. int pussy=0;

  33. void itoa_00(int v_speed);
  34. void Time0_Init(void);
  35. void Outside0_Init(void);
  36. void Uart_Init(void);
  37. void xunji(void);
  38. void tingzhi(void);
  39. void qianjin(void);
  40. void zuozhuan(void);
  41. void youzhuan(void);
  42. char exchange(int v_speed);

  43. void delay_ms(uint i)//1ms??
  44. {
  45.   uchar x,j;  
  46.   for(j=0;j<i;j++)
  47.     for(x=0;x<=148;x++);
  48. }




  49. void Uart_SendByte(uchar Byte)
  50. {
  51.     SBUF =    Byte;
  52.     while(!TI)                   //è?1?·¢?ííê±?£?ó2?t?á????TI
  53.     {
  54.         _nop_();   
  55.     }   
  56. }

  57. void main()
  58. {
  59.     Uart_Init();
  60.     Time0_Init();
  61.     Outside0_Init();
  62.     while(1)
  63.     {
  64.     if(R_flag==1)
  65.         {
  66.             for(x=0;x<6;x++)
  67.             {        
  68.                Uart_SendByte(speed[x]);
  69.                 delay_ms(1);
  70.             }
  71.             R_flag=0;        
  72.         }   
  73.   xunji();
  74.     }        
  75. }


  76. int cout;
  77. void itoa_00(int v_speed)
  78. {   
  79.       cout = v_speed/100;
  80.         speed[0]=exchange(cout);
  81.       v_speed%=100;
  82.       cout = v_speed/10;
  83.       speed[1]=exchange(cout);
  84.       v_speed%=10;
  85.       speed[2]=exchange(v_speed);
  86.       speed[3] = '\n';
  87.       speed[4]='\0';

  88. }
  89. char exchange(int v_speed)
  90. {
  91.         switch(v_speed)
  92.         {
  93.             case 0:return '0';
  94.             case 1:return '1';
  95.             case 2:return '2';
  96.             case 3:return '3';
  97.             case 4:return '4';
  98.             case 5:return '5';
  99.             case 6:return '6';
  100.             case 7:return '7';
  101.             case 8:return '8';
  102.             case 9:return '9';            
  103.         }
  104.         return '\0';
  105. }

  106. void Uart_Init(void)
  107. {
  108.      TMOD = 0x21;   //?¨ê±?÷1¤×÷?ú?¨ê±?÷1μ?·?ê?2
  109.      PCON = 0x00;   //2?±??μ
  110.      SCON = 0x50;    //′?ú1¤×÷?ú·?ê?1£?2¢?ò???ˉ′DD?óê?   
  111.      TH1 = 0xFd;    //éè??2¨ì??ê 9600
  112.      TL1 = 0xFd;
  113.      TR1 = 1;        //???ˉ?¨ê±?÷1
  114.        ES = 1;        //?a′?ú?D??
  115.        EA = 1;        //?a×ü?D??        
  116. }

  117. void Time0_Init()  //?¨ê±?÷?D??0????
  118. {
  119.     TMOD = 0x21;
  120.     TH0 = 0xfc;            //11.0592 ---0.05s
  121.       TL0 = 0x18;
  122.     ET0 = 1;
  123.     TR0 = 1;   
  124.       EA = 1;
  125. }

  126. void Outside0_Init()  
  127. {
  128.       EX0 = 1;  
  129.       IT0 = 1;  
  130.       EA = 1;      
  131. }

  132. void EX0_ISR() interrupt 0
  133. {
  134.       Distance += 1;
  135. }

  136. void Timer0Interrupt() interrupt 1  //?¨ê±?÷?D??
  137. {
  138.    TH0 = 0xfc;            //11.0592 ---0.05s
  139.      TL0 = 0x18;
  140.      pussy++;
  141.      count++;
  142.      if(count == 1000)
  143.      {
  144.          time+=1;
  145.          count=0;
  146.      }
  147.      if(pussy<7)
  148.      {PWM1=0;}
  149.      if(7<=pussy<10)
  150.      {PWM1=1;}
  151.      if(pussy==10)
  152.      {pussy=0;}
  153. }
  154. void Uart_Int(void) interrupt 4  
  155. {
  156.     if(RI == 1)   
  157.     {
  158.         v_speed = Distance/time;
  159.         itoa_00(v_speed);   
  160.         RI = 0;  
  161.         R_flag=1;
  162.     }
  163. }

  164. void tingzhi()
  165. {
  166.     //ENA=0;
  167.   L1A=0;                            //定义左侧电机驱动A端
  168.   L1B=0;                            //定义左侧电机驱动B端
  169.   //ENB=0;
  170.   L2A=0;                            //定义右侧电机驱动A端
  171.   L2B=0;                            //定义右侧电机驱动B端
  172.   //ENC=0;
  173.   R1A=0;                            //定义左侧电机驱动A端
  174.   R1B=0;                            //定义左侧电机驱动B端
  175.   //END=0;
  176.   R2A=0;                            //定义右侧电机驱动A端
  177.   R2B=0;                            //定义右侧电机驱动B端
  178. }

  179. void qianjin()
  180. {
  181.     //ENA=1;
  182.   L1A=0;
  183.     L1B=1;
  184.         //ENB=1;
  185.    
  186.     L2A=0;
  187.     L2B=1;
  188.         //ENC=1;

  189.     R1A=1;
  190.     R1B=0;
  191.         //END=1;

  192.     R2A=0;
  193.     R2B=1;
  194. }

  195. void zuozhuan1()
  196. {
  197.         //ENA=1;

  198.   L1A=0;                            //定义左侧电机驱动A端
  199.   L1B=0;                            //定义左侧电机驱动B端
  200.     //ENB=1;

  201.   L2A=0;                            //定义右侧电机驱动A端
  202.   L2B=0;                            //定义右侧电机驱动B端
  203.     //ENC=1;

  204.   R1A=0;                            //定义左侧电机驱动A端
  205.   R1B=1;                            //定义左侧电机驱动B端
  206.     //END=1;

  207.   R2A=1;                            //定义右侧电机驱动A端
  208.   R2B=0;                            //定义右侧电机驱动B端
  209. }

  210. void youzhuan1()
  211. {
  212.     //    ENA=1;

  213.   L1A=0;                            //定义左侧电机驱动A端
  214.   L1B=1;                            //定义左侧电机驱动B端
  215.     //ENB=1;

  216.   L2A=0;                            //定义右侧电机驱动A端
  217.   L2B=1;                            //定义右侧电机驱动B端

  218.   R1A=0;                            //定义左侧电机驱动A端
  219.   R1B=0;                            //定义左侧电机驱动B端

  220.   R2A=0;                            //定义右侧电机驱动A端
  221.   R2B=0;                            //定义右侧电机驱动B端
  222. }


  223. void xunji()
  224. {
  225.     if((right2 == 0)&&(right1 == 0)&&(left1 == 0)&&(left2 == 0))
  226.     {
  227.         qianjin();
  228.     }
  229.     if((right2 == 0)&&(right1 ==1)&&(left1 == 0)&&(left2 == 0))
  230.     {
  231.         youzhuan1();
  232.     }
  233.     if((right2 == 0)&&(right1 == 0)&&(left1 == 1)&&(left2 == 0))
  234.     {
  235.         zuozhuan1();
  236.     }
  237.     if((right2 == 0)&&(right1 == 0)&&(left1 == 0)&&(left2 == 1))
  238.     {
  239.         zuozhuan1();
  240.     }
  241.     if((right2 == 1)&&(right1 == 0)&&(left1 == 0)&&(left2 == 0))
  242.     {
  243.         youzhuan1();
  244.     }
  245.     if((right2 == 1)&&(right1 == 1)&&(left1 == 1)&&(left2 == 1))
  246.     {
  247.         if(tim<100)
  248.         {
  249.             qianjin();
  250.           delay_ms(100);
  251.             tingzhi();
  252.             }
  253.         }
  254.     }   
  255. }
复制代码


回复

使用道具 举报

ID:332444 发表于 2019-8-10 19:59 | 显示全部楼层
随便说说,首先不要直接使用 int char 应使用unsigned int这样的;2逻辑简化这当然不是必要的,只是可以简化代码如 if(right2 == left2 == 0 && right1 == left1 == 1);3调用寻迹前添加判断R_flag这是猜测的。
回复

使用道具 举报

ID:503018 发表于 2019-8-10 20:55 | 显示全部楼层
随便说说,首先不要直接使用 int char 应使用unsigned int这样的;2逻辑简化这当然不是必要的,只是可以简化代码如 if(right2 == left2 == 0 && right1 == left1 == 1);3调用寻迹前添加判断R_flag
回复

使用道具 举报

ID:590125 发表于 2019-8-10 21:11 | 显示全部楼层
xianfajushi 发表于 2019-8-10 19:59
随便说说,首先不要直接使用 int char 应使用unsigned int这样的;2逻辑简化这当然不是必要的,只是可以简 ...

R_flag 的判断内容要写些什么呢?是对红外的判断还是?
回复

使用道具 举报

ID:332444 发表于 2019-8-11 06:32 | 显示全部楼层
判断式应该是连续的,而不是单独的,如if(right2 == left2 == 0 && right1 == left1 == 1)。。else if(right2 == left2 == 0 && right1 == left1 == 1)这样;if(R_flag) xunji();这样试看
回复

使用道具 举报

ID:377268 发表于 2019-8-12 00:55 | 显示全部楼层
代码问题有点多。首先你的PWM频率太低了吧,20Hz?,电机控制起码是几千Hz的这样你走起来就会很抖的,还有就是PWM电平反转的判断语句,也不对的能用可以说是巧合,C的if判断不能这么写,然后就是你的最后一块儿代码逻辑不对。你的停车线比较宽,用计时的方法判断是进环岛还是停车可以,但是代码写得很不对,你要在检测到双黑线后开始time计数,继续前进延时一段时间后再检测一次是不是全黑,是的话停车不是就继续循迹。最后,倒车这个我倒不确定,但是抖动就是你最后那块儿没写好。可能是抖着抖着自己后退了,跟你驱动频率太低也可能有关系。
回复

使用道具 举报

ID:560467 发表于 2019-8-16 21:26 | 显示全部楼层
随便说说:其实这种路线使用4个红外循迹模块的话是可以更加容易的实现区分环岛和停车点的。使用4个传感器全部放在车头排放位置类似于色子上的4,只不过前面的两个稍微宽一些
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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