找回密码
 立即注册

QQ登录

只需一步,快速开始

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

自动避障红外电动小车C51程序

[复制链接]
跳转到指定楼层
楼主
ID:210992 发表于 2017-6-25 14:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
自动避障红外电动小车C51程序

单片机源程序如下:
  1. #include"reg51.h"
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint  unsigned int
  5. #define left_infrare  0
  6. #define right_infrare 1
  7. #define dj_state1        0X5F      //前进
  8. #define dj_state2        0X4F      //右转  
  9. #define dj_state3        0X1F      //左转  
  10. #define dj_state4        0X0F      //后退  
  11. #define dj_state5        0XfF      //停车
  12. #define light_off        0x0f      //关转向灯
  13. #define left_light       0X5F      //左转向灯    两个是5f
  14. #define right_light      0XaF      //右转向灯0xaf,两个是0xbf
  15. #define back_light       0XcF      //刹车灯即后灯
  16. #define front_light      0x3f      //前灯
  17. #define light_on         0xff      //开所有灯
  18. #define true  1
  19. #define false 0
  20. #define LCD_Data  P0
  21. #define Busy  0x80            //用于检测LCD状态字中的Busy标识
  22. sbit    c=P1^2;              //转向灯使能端
  23. uchar code talk1[]={"backward"};
  24. uchar code talk2[]={"forward"};
  25. uchar code talk3[]={"Turnleft"};
  26. uchar code talk4[]={"Turn right"};
  27. uchar flage =0x00;
  28. sbit  ledcs=P1^2;         //74H573的片选信号
  29. //sbit  left_led=P0^2;     //左红外发射管
  30. //sbit  right_led=P0^3;    //右红外发射管

  31. sbit  LCD_RS = P1^5;     //LCD定义引脚
  32. sbit  LCD_RW = P1^6;     //
  33. sbit  LCD_E  = P1^7 ;
  34. void Delay5Ms(void)
  35. {
  36. uint TempCyc = 5552;
  37. while(TempCyc--);
  38. }
  39. //400ms延时
  40. void Delay400Ms(void)
  41. {uchar TempCycA = 5;
  42. uint TempCycB;
  43. while(TempCycA--)
  44.    { TempCycB=7269;
  45.      while(TempCycB--);
  46.     }
  47. }
  48. //LCD读状态
  49. unsigned char ReadStatusLCD(void)
  50. {
  51. LCD_Data = 0xFF;
  52. LCD_RS = 0;
  53. LCD_RW = 1;
  54. LCD_E = 0;
  55. LCD_E = 0;
  56. LCD_E = 1;
  57. while (LCD_Data & Busy);   //检测忙信号
  58. return(LCD_Data);
  59. }
  60. //LCD写数据
  61. void WriteDataLCD(unsigned char WDLCD )
  62. {
  63. ReadStatusLCD();  //检测忙
  64. LCD_Data = WDLCD;
  65. LCD_RS=1;
  66. LCD_RW =0;
  67. LCD_E = 0; //若晶振速度太高可以在这后加小的延时
  68. LCD_E = 0; //延时 ,为了安全
  69. LCD_E = 0; //延时
  70. LCD_E = 1;
  71. }
  72. //LCD写指令
  73. void WriteCommandLCD(unsigned char WCLCD,BuysC)
  74. {
  75. if (BuysC) ReadStatusLCD();   //根据需要检测忙,BuysC为0时忽略忙检测
  76. LCD_Data = WCLCD;
  77. LCD_RS= 0;
  78. LCD_RW= 0;
  79. LCD_E = 0;  //延时 ,为了安全
  80. LCD_E = 0;
  81. LCD_E = 0; //延时
  82. LCD_E = 1;
  83. }
  84. void LCDInit(void)         //LCD初始化
  85. {
  86. Delay400Ms();
  87. LCD_Data = 0;
  88. WriteCommandLCD(0x38,0);  //三次显示模式设置,不检测忙信号
  89. Delay5Ms();
  90. WriteCommandLCD(0x38,0);
  91. Delay5Ms();
  92. WriteCommandLCD(0x38,0);
  93. Delay5Ms();

  94. WriteCommandLCD(0x38,1); //显示模式设置,开始要求每次检测忙信号
  95. WriteCommandLCD(0x08,1); //关闭显示
  96. WriteCommandLCD(0x01,1); //显示清屏
  97. WriteCommandLCD(0x06,1); // 显示光标移动设置
  98. WriteCommandLCD(0x0C,1); // 显示开及光标设置
  99. }
  100. //按指定位置显示一个字符
  101. void DisplayOneChar(uchar X, uchar Y, uchar DData)
  102. {
  103. Y &= 0x1;
  104. X &= 0xF;                 //限制X不能大于15,Y不能大于1
  105. if (Y)
  106. X |= 0x40;               //当要显示第二行时地址码+0x40;
  107. X |= 0x80;               // 算出LCD的指令码
  108. WriteCommandLCD(X, 0);   //这里不检测忙信号,发送地址码
  109. WriteDataLCD(DData);
  110. }
  111. //按指定位置显示一串字符(只能写一行);
  112. void DisplayListChar(uchar X, uchar Y,uchar ListLength, uchar  *DData,uchar n)
  113. { uchar i;
  114. Y &= 0x01;
  115. X &= 0x0F;                 //限制X不能大于15,Y不能大于1
  116. for(i=0;i<ListLength;i++)
  117. { if (X <= 0x0F) //X坐标应小于0xF
  118.     {   DisplayOneChar(X, Y, DData[i]); //显示单个字符
  119.          if(n==true)Delay400Ms();
  120.           X++;
  121.     }
  122.   }
  123. }
  124. /****************************
  125. 红外线接收子程序,利用了中断的下降沿触发方式
  126. ****************************/
  127. void infrared_ray()interrupt 0  using 3
  128. {  uchar i=90;
  129.    flage=0x01;             //接受标志位
  130.    while(i--);            //减小灵敏度
  131.    EX0=0;               //关掉中断,等到发射方波后才开启,处于别动
  132. }
  133. // 延时子程序
  134. void delay(uint n)
  135. {
  136.   while(--n);
  137. }
  138. //中断初始化
  139. void Init0(void)
  140. {  EA=1;
  141.    IT0=1;
  142.     }
  143. /***************************************
  144. /*原理是把中断打开并 发射方波,
  145. 当有中断时就转到中断产生中断位为下一步转向做准备,
  146. 当没有是关闭中断
  147. ****************************************/
  148. void seng_wave(uchar timer,bit n)//timer通过载波发射信号的时间,n->左右发射管的选择
  149. {  uchar i;
  150.    P1 |= 0X04;      //ledcs=1为74ls573为11脚为高电平时数据直接输出,为低时把数据锁存住,即保持
  151.    IE |= 0X01;
  152.    P0 |=0x0c;   //04
  153.    for(i=timer;i>0;i--)
  154.      { if(n)P0^=0x08;                      // 右发射管通过载波发射信号//00
  155.         else P0^=0x04;                    // 左发射管通过载波发射信号//0c
  156.          delay(100);                     //这里控制着灵敏度(控制38khz的方波的多少)和距离
  157.       }                                     //timer*delay(x)即为发射管得到的平均电流
  158.     P1 &= 0Xfb;
  159.     IE &= 0Xfe;
  160. }
  161. //led转向灯指示子程序
  162. void light_control(uchar deng)
  163. {   ledcs=1;
  164.     P0 =deng;
  165.     ledcs=0;  //11111011
  166. }
  167. //电机和灯光的控制部分
  168. void  control(uchar n,uchar dj_state,uchar light)
  169. {   uchar i;
  170.    // P1|=0x04;
  171.      light_control(light);    //led转向指示灯
  172.      delay(100);
  173.      P2 =dj_state;              //电机的方向控制
  174.     WriteCommandLCD(0x01,1); //LCD显示清屏

  175.           switch(dj_state)
  176.           { case dj_state2 :{ DisplayListChar(3,1,10,talk4,false);}break;
  177.             case dj_state3: { DisplayListChar(3,1,8,talk3,false);}break;
  178.             case dj_state4: { DisplayListChar(3,1,7,talk1,false); }break;
  179.              default :break;
  180.              }
  181.           for(i=n;i>0;i--)
  182.           {delay(2000);}
  183.            P2=dj_state5;               //停车
  184.          light_control(light_off);       //led关闭
  185.         WriteCommandLCD(0x01,1); //LCD显示清屏
  186.          P2=dj_state1;                     //前进
  187.         if(dj_state1)
  188.            { P1|=0X04;          //ledcs=1;
  189.              P0=0x0f;
  190.              P1&=0XFB;
  191.              delay(100);
  192.              DisplayListChar(0,0,7,talk2,false);
  193.              }
  194.      }
  195. /****************************************
  196. 避障主要控制部分
  197. *****************************************/
  198. void move_car(void)
  199. {
  200.    uchar temp =0x00;
  201.    //左边红外管发射
  202.        seng_wave(1,left_infrare);     //向下为中断开启有关闭后,要执行的语句
  203.         if(flage==0x01){temp|=0x01;flage=0x00;}
  204.        //右边红外管发射
  205.          delay(30);
  206.         seng_wave(1,right_infrare);    //向下为中断开启有关闭后,要执行的语句
  207.         if(flage==0x01){temp|=0x02;flage=0x00;}

  208. ……………………

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

所有资料51hei提供下载:
自动避障红外电动小车C51程序.rar (2.81 KB, 下载次数: 22)


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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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