找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3357|回复: 0
收起左侧

超声波循迹避障程序基本可以用,还不完善

[复制链接]
ID:186600 发表于 2017-7-2 22:56 | 显示全部楼层 |阅读模式
壁障小车

0.png

单片机源程序如下:
  1. /*******************************************************
  2. * 项目名称:循迹避障小车
  3. * 单 片 机:STC89C52RC
  4. * 功    能:循迹,红外遥控,超声波避障,舵机,PWM,跟踪
  5. * 作    者:刘琦
  6. * IO口定义:红外循迹                                P3^4,P3^5
  7. *                        红外避障                                P3^6,P3^7
  8. *                        电机                                          P1^0~P1^7               
  9. *                        超声波避障                                P2^4~P2^5
  10. *                        红外遥控                                P3^3
  11. *                        舵机                                        P2^3              
  12. *                        数码管段选                                P0
  13. *                        数码管位选                                P2^0~P2^3
  14. * 遥 控 器:2           前进                         (18)
  15. *                        8           后退                        (52)
  16. *                        5                停止                         (1C)
  17. *                        4           左转                        (08)
  18. *                        6           右转                        (5A)
  19. *                        1                遥控模式                (0C)
  20. *                        3                 循迹模式                (5E)
  21. *                        7                跟随模式                (42)
  22. *                        9                避障模式                (4A)
  23. *                        +                加速                        (15)
  24. *                        -                减速                        (07)
  25. * 定 时 器:T0                PWM(电机、舵机),数码管(超声波测距)
  26. *                         T1                红外遥控计时
  27. *                        T2                超声波计时
  28. *******************************************************/
  29. /******************************头文件区***********************************************/
  30. #include <reg52.h>
  31. #include "Dianji.h"
  32. #include "Yaokong.h"
  33. #include "RTX51TNY.H"
  34. #include "Chaoshengbo.h"
  35. #include "Duoji.h"

  36. /******************************宏定义区***********************************************/
  37. //需要定时刷新的任务数,0YaoKong,1Display,2CSB
  38. #define NUM_TASK_REFRESH 3
  39. //刷新频率
  40. //#define TIME_PER_SEC 200                                                        //每次进入中断的频率,200Hz,5ms
  41. #define TIME_PER_SEC 10000                                                        //每次进入中断的频率,10000Hz,0.1ms
  42. #define TIME_CLOCK 11059200                                                        //晶振频率
  43. #define TIME_YAOKONG_50HZ          TIME_PER_SEC/50                  //响应遥控命令频率,0.02s
  44. #define TIME_SUMA_300HZ                TIME_PER_SEC/300                //超声波距离显示数码管刷新频率,0.003s
  45. #define TIME_CSB_5HZ                TIME_PER_SEC/5                        //超声波自动检测的频率,0.2s

  46. #define FLAG_YAOKONG                0
  47. #define FLAG_XUNJI                        1
  48. #define FLAG_BIZHANG                2
  49. #define FLAG_GENSUI                        3

  50. #define FLAG_GO                                0
  51. #define FLAG_BACK                        1
  52. #define FLAG_STOP                        2
  53. #define FLAG_TURNLEFT                3
  54. #define FLAG_TURNRIGHT                4

  55. #define NO                                        0
  56. #define YES                                        1

  57. #define DELAYTURN                        5000
  58. #define DELAYDUOJI                        5000


  59. /******************************子函数声明区***********************************************/

  60. void initial_myself(void);   
  61. void initial_peripheral(void);
  62. void delay100ms(void);       

  63. /******************************IO口定义区***********************************************/
  64. sbit LEFT_XJ  = P3^4;        //        左循迹
  65. sbit RIGHT_XJ = P3^5;        //        右循迹
  66. sbit LEFT_GS  = P3^6;        //        左跟随
  67. sbit RIGHT_GS = P3^7;        //        右跟随

  68. //sbit LEFT_CS  = P                //        左测速
  69. //sbit RIGHT_CS = P                //        右测速

  70. sbit KEY=P2^6;                        //  激活超声波测距,测试用,蜂鸣器也响;

  71. /******************************全局变量定义区***********************************************/

  72. unsigned char ucPwm  = 4;                                                                //电机的PWM占空比,N/10
  73.                                
  74. unsigned int ucPwmCountDianJ = 0;                                                //电机Pwm计数
  75. unsigned int ucPwmCountDuoJ = 0;                                                //舵机Pwm计数

  76. unsigned char ucFlagState = FLAG_YAOKONG;                                //模式选择,遥控,循迹,避障
  77. unsigned char ucFlagControl = FLAG_STOP;                                //遥控模式下的控制选择,前进后退停止左转右转


  78. unsigned int uc_delay_task_cnt[NUM_TASK_REFRESH];                //任务刷新延迟

  79. unsigned char ucCSBCheck    = NO;                                                //用于判断是否需要停车检测

  80. unsigned int ucPwmDuoj = 6;                                                                //舵机归中,默认情况下先归中
  81. unsigned int ulS[4]         = {0,0,0,0};                                        //储存距离数据,0°,180°,90°,后退时90°

  82. unsigned char ucDuoJiPosition[3]={11,2,6};                                //舵机的0°,180°,90°对应的ucPwmDuoj数值

  83. unsigned char ucFlagTurning=NO;                                                        //在超声波避障模式中,判断是否正在转弯
  84. unsigned char ucFlagDuoJiPositon=0;                                                //正在检测的舵机位置标示,0代表正在检测0°
  85. unsigned char ucLockCSBCheck=NO;                                                //超声波检测过程中时,此为YES,锁住红外传感器的检测
  86. unsigned int  uiDelayDuoJiMove=DELAYDUOJI;                                //舵机移动延迟结束
  87. unsigned char ucFlagDuoJiMove=NO;                                                //舵机开始移动的标志,此标志为YES时uiDelayDuoJiMove开始减
  88. unsigned char ucFlagCSBBegin=NO;                                                //超声波开始检测标志,当uiDelayDuoJiMove为0时,为YES
  89. unsigned char ucNumS=0;                                                                        //ulS数组的第几位
  90. unsigned char ucNumCSB=0;                                                                //进入超声波检测的次数,用来控制什么时候结束检测,开始转弯
  91. unsigned int  uiDelayTurn=DELAYTURN;                                        //转弯结束,大概90°
  92. unsigned char ucFlagTurn=NO;                                                        //开始转动的标志,此标志为YES时uiDelayTurn开始减
  93. unsigned char ucFlagTurnOver=NO;                                                //转弯结束标志,为YES时,退出转弯
  94. unsigned char ucFlagSMGLock=NO;                                                        //数码管锁,从检测到障碍,到转弯结束,这段时间锁上不显示
  95. unsigned char ucFlagGuiZhong=NO;                                                //头一次进入避障模式先归中
  96. unsigned char ucFlagBegin=NO;                                                        //归中后此位为YES
  97. unsigned char ucFlagChangeState=NO;                                                //改变状态标识,如果改变了,那么初始化避障模式的变量
  98. unsigned char ucFlagBackOK=NO;                                                        //后退OK标识,后退结束后,才开始转弯


  99. //unsigned char ucCSBDirection = 0;                                                //用来记录并判断检测后行进方向
  100. //unsigned char ucCSBFlag     = 0;                                                //用来激活400ms计时
  101. //unsigned char ucFlagJumpoutPwm = 0;                                                //Pwm跳出标示,1为跳出

  102. //unsigned char const discode[] ={ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xBF,0xff/*-*/};
  103. //unsigned char const positon[3]={ 0xfe,0xfd,0xfb};


  104. /******************************主函数开始***********************************************/
  105. void main(void)
  106. {
  107.         initial_myself();
  108.         delay100ms();   
  109.     initial_peripheral();


  110.         while(1)
  111.         {
  112.                 if(ucFlagChangeState==YES)                                                //每次改变状态,将避障模式的变量初始化
  113.                 {
  114.                         ucFlagTurning=NO;                                                        //在超声波避障模式中,判断是否正在转弯
  115.                         ucFlagDuoJiPositon=0;                                                //正在检测的舵机位置标示,0代表正在检测0°
  116.                         ucLockCSBCheck=NO;                                                //超声波检测过程中时,此为YES,锁住红外传感器的检测
  117.                         uiDelayDuoJiMove=DELAYDUOJI;                                //舵机移动延迟结束
  118.                         ucFlagDuoJiMove=NO;                                                //舵机开始移动的标志,此标志为YES时uiDelayDuoJiMove开始减
  119.                         ucFlagCSBBegin=NO;                                                //超声波开始检测标志,当uiDelayDuoJiMove为0时,为YES
  120.                         ucNumS=0;                                                                        //ulS数组的第几位
  121.                         ucNumCSB=0;                                                                //进入超声波检测的次数,用来控制什么时候结束检测,开始转弯
  122.                         uiDelayTurn=DELAYTURN;                                        //转弯结束,大概90°
  123.                         ucFlagTurn=NO;                                                        //开始转动的标志,此标志为YES时uiDelayTurn开始减
  124.                         ucFlagTurnOver=NO;                                                //转弯结束标志,为YES时,退出转弯
  125.                         ucFlagSMGLock=NO;                                                        //数码管锁,从检测到障碍,到转弯结束,这段时间锁上不显示
  126.                         ucFlagGuiZhong=NO;                                                //头一次进入避障模式先归中
  127.                         ucFlagBegin=NO;                                                        //归中后此位为YES
  128.                         ucFlagBackOK=NO;                                                //后退OK标识,后退结束后,才开始转弯
  129.                         ucPwm=4;
  130.                         ucFlagChangeState=NO;
  131.                 }
  132.                 if(uc_delay_task_cnt[0]==0)
  133.                 {
  134.                         YaoKong();
  135.                         ET0=0;//在中断中也有可能变化的变量在更改前时先关闭中断
  136.                         uc_delay_task_cnt[0]=TIME_YAOKONG_50HZ;
  137.                         ET0=1;
  138.                 }
  139.                 //遥控模式
  140.                 if(ucFlagState==FLAG_YAOKONG)
  141.                 {
  142.                         switch(ucFlagControl)
  143.                         {
  144.                                 case FLAG_GO:
  145.                                         Go();
  146.                                         break;
  147.                                 case FLAG_STOP:
  148.                                         Stop();
  149.                                         break;
  150.                                 case FLAG_BACK:
  151.                                         Back();
  152.                                         break;
  153.                                 case FLAG_TURNLEFT:
  154.                                         TurnLeft();
  155.                                         break;
  156.                                 case FLAG_TURNRIGHT:
  157.                                         TurnRight();
  158.                                         break;
  159.                                 default:
  160.                                         break;
  161.                         }
  162.                 }
  163.                 //循迹模式
  164.                 if(ucFlagState==FLAG_XUNJI)
  165.                 {
  166.                         if(LEFT_XJ==1&&RIGHT_XJ==1)
  167.                         {
  168.                                 ucPwm=3;
  169.                                 Go();
  170.                         }
  171.                         else if(RIGHT_XJ==0)
  172.                         {
  173.                                 ucPwm=8;
  174.                                 TurnRight();
  175.                         }
  176.                         else if(LEFT_XJ==0)
  177.                         {
  178.                                 ucPwm=8;
  179.                                 TurnLeft();
  180.                         }
  181.                                
  182.                 }
  183.                 //跟随模式
  184.                 if(ucFlagState==FLAG_GENSUI)
  185.                 {
  186.                         if(LEFT_GS==1&&RIGHT_GS==1)                                                //左右都检测到物体
  187.                         {
  188.                                 Stop();
  189.                         }
  190.                         else if(LEFT_GS==0&&RIGHT_GS==1)                            //左侧未检测到,右侧检测到
  191.                         {
  192.                                 TurnRight();                                                                                                                                  
  193.                         }
  194.                         else if(LEFT_GS==1&&RIGHT_GS==0)                                //右侧未检测到,左侧检测到
  195.                         {
  196.                                 TurnLeft();
  197.                         }
  198.                         else                                                                                        //左右都未检测到
  199.                         {
  200.                                 Go();
  201.                         }       
  202.                 }
  203.                 //超声波+红外避障模式

  204.                 //ucFlagBegin=NO,
  205.                 if(ucFlagState==FLAG_BIZHANG)
  206.                 {
  207.                         if(ucFlagBegin==NO)
  208.                         {
  209.                                 ucPwmDuoj=ucDuoJiPosition[2];
  210.                                 ucFlagGuiZhong=YES;
  211.                         }
  212.                         else
  213.                         {
  214. //                                if(ucFlagSMGLock==NO&&uc_delay_task_cnt[1]==0)                                                //数码管刷新
  215.                                 if(uc_delay_task_cnt[1]==0)                                                //数码管刷新
  216.                                 {
  217.                                         Display();
  218.                                         ET0=0;//在中断中也有可能变化的变量在更改前时先关闭中断
  219.                                         uc_delay_task_cnt[1]=TIME_SUMA_300HZ;
  220.                                         ET0=1;
  221.                                 }
  222.        
  223.                                 if(ucFlagTurning==NO)                                                        //没在转弯
  224.                                 {                                                                                                 
  225.                                         if(ucLockCSBCheck==NO&&uc_delay_task_cnt[2]==0)        //超声波自动检测
  226.                                         {
  227.                                                 CSB ();
  228.                                                 ET0=0;//在中断中也有可能变化的变量在更改前时先关闭中断
  229.                                                 uc_delay_task_cnt[2]=TIME_CSB_5HZ;
  230.                                                 ET0=1;
  231.                                                 if(S<=40)
  232.                                                 {
  233.                                                          ucLockCSBCheck=YES;
  234.                                                          ucFlagSMGLock=YES;
  235.                                                          Stop();
  236.                                                 }
  237.                                         }
  238.        
  239.                                         if(ucLockCSBCheck==NO)
  240.                                         {
  241.                                                 Go();
  242.                                         }
  243.                                        
  244.                                         if(ucLockCSBCheck==YES)                                                        //遇到障碍后超声波检测整个过程开始
  245.                                         {
  246.                                                 if(ucFlagCSBBegin==NO)                                                                //超声波检测未开始
  247.                                                 {                                                                                                       
  248.                                                         ucPwmDuoj=ucDuoJiPosition[ucFlagDuoJiPositon];        //正在检测的角度,随着ucFlagDuoJiPositon变化而变化
  249.                                                         ucFlagDuoJiMove=YES;
  250.                                                 }
  251.                                                 if(ucFlagCSBBegin==YES)
  252.                                                 {
  253. //                                                        if(ucFlagDuoJiPositon<2)                                                //只在0°,180°进行超声波检测
  254. //                                                        {
  255.                                                                 CSB ();
  256.                                                                 CSB ();
  257.                                                                 CSB ();
  258.                                                                 ulS[ucNumS]=S;                                                                //将距离数据存起来
  259. //                                                                if(ucNumS<2)
  260.                                                                         ucNumS++;
  261. //                                                        }
  262.                                                         if(++ucFlagDuoJiPositon>2)
  263.                                                                 ucFlagDuoJiPositon=0;
  264.                                                         if(++ucNumCSB>=3)                                                               
  265.                                                         {
  266.                                                                  ucFlagTurning=YES;                                                        //激活转弯
  267.                                                                  ucLockCSBCheck=NO;                                                       
  268.                                                                  ucNumCSB=0;                                                                //进入检测的次数清0
  269.                                                                  ucNumS=0;                                                                        //存储距离数据的位置清0
  270.                                                         }
  271.                                                         ucFlagCSBBegin=NO;                                                                //超声波检测结束
  272.                                                 }
  273.                
  274.                                         }
  275.                                 }
  276.                                 else                                                                                                                //正在转弯
  277.                                 {
  278.                                         if(ucFlagBackOK==NO)
  279.                                         {
  280.                                                 if(        ulS[2]<30)
  281.                                                 {
  282.                                                         Back();
  283.                                                         CSB();
  284.                                                         ulS[3]=S;
  285.                                                         if(ulS[3]>=30)
  286.                                                                 ucFlagBackOK=YES;       
  287.                                                 }
  288.                                                 else
  289.                                                         ucFlagBackOK=YES;
  290.                                         }
  291.                                         else
  292.                                         {
  293.                                                 if(ucFlagTurnOver==NO)                                                                        //未转弯结束
  294.                                                 {
  295.                                                         ucFlagTurn=YES;
  296.                                                         if(ulS[0]>ulS[1])                                                                        //左侧>右侧
  297.                                                                 TurnLeft();
  298.                                                         else
  299.                                                                 TurnRight();
  300.                                                 }
  301.                                                 else
  302.                                                 {
  303.                                                         ucFlagTurning=NO;
  304.                                                         ucFlagTurnOver=NO;
  305.                                                         ucFlagSMGLock=NO;
  306.                                                         ucFlagBackOK=NO;
  307.                                                 }
  308.                                         }       
  309.                                 }
  310.                         }
  311.                 }
  312.         }
  313. }

  314. //中断函数
  315. void timer0(void) interrupt 1
  316. {
  317.         unsigned char i;
  318.         TR0=0;
  319.         TH0=255-TIME_CLOCK/TIME_PER_SEC/12/256;
  320.         TL0=255-TIME_CLOCK/TIME_PER_SEC/12%256;
  321.         //task_delay[]减到0时,相应的函数准备就绪
  322.         for(i=0;i<NUM_TASK_REFRESH;i++)
  323.         {
  324.                 if(uc_delay_task_cnt[i]!=0)//延迟不为0时才减
  325.                         {uc_delay_task_cnt[i]--;};
  326.         }
  327.         ucPwmCountDianJ++;
  328.         if(ucPwmCountDianJ  >= 10)
  329.         {
  330.                 ucPwmCountDianJ  = 0;
  331.         }
  332.        
  333.         //舵机转动距离控制
  334.         if(ucFlagDuoJiMove==YES||ucFlagGuiZhong==YES)
  335.         {
  336.                 ucPwmCountDuoJ++;
  337.                 if(ucPwmCountDuoJ>205)                                                //0.5+20(ms),整个周期长度
  338.                 {
  339.                         ucPwmCountDuoJ=0;
  340.                 }
  341.                 PwmServomoto();
  342.         }

  343.         //舵机转动时间控制
  344.         if(ucFlagDuoJiMove==YES)
  345.         {
  346.                 if(uiDelayDuoJiMove!=0)
  347.                         uiDelayDuoJiMove--;
  348.                 else
  349.                 {
  350.                         uiDelayDuoJiMove=DELAYDUOJI;
  351.                         ucFlagDuoJiMove=NO;
  352.                         ucFlagCSBBegin=YES;       
  353.                 }       
  354.         }
  355.         //头一次进入避障模式的舵机归中
  356.         if(ucFlagGuiZhong==YES)
  357.         {
  358.                 if(uiDelayDuoJiMove!=0)
  359.                         uiDelayDuoJiMove--;
  360.                 else
  361.                 {
  362.                         uiDelayDuoJiMove=DELAYDUOJI;
  363.                         ucFlagGuiZhong=NO;
  364.                         ucFlagBegin=YES;       
  365.                 }       
  366.         }

  367.         //转弯延迟
  368.         if(ucFlagTurn==YES)
  369.         {
  370.                 if(uiDelayTurn!=0)
  371.                         uiDelayTurn--;
  372.                 else
  373.                 {
  374.                         uiDelayTurn=DELAYTURN;
  375.                         ucFlagTurn=NO;
  376.                         ucFlagTurnOver=YES;
  377.                 }       
  378.         }

  379.         TR0=1;
  380. ……………………

  381. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
8.6 No.1 超声波避障基本可以用,还不完善.zip (90.83 KB, 下载次数: 12)
回复

使用道具 举报

ID:214762 发表于 2017-7-3 08:54

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

本版积分规则

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

Powered by 单片机教程网

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