找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机智能小车红外避障循迹程序

[复制链接]
跳转到指定楼层
楼主
ID:801290 发表于 2020-7-10 22:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
51单片机智能小车红外避障程序以及文档
  1. #include"car_psb.h"
  2. #define uint unsigned int                //用uint代替无字符整形数据的名称
  3. #define uchar unsigned char
  4. sbit A1 = P0^3;
  5. sbit A2 = P0^2;//A1为L293芯片2脚(IN1),A2为L293芯片7脚(IN2),控制右电机
  6. sbit B1 = P0^1;
  7. sbit B2 = P0^0;
  8. sbit key1 = P0^6;//按钮s1
  9. sbit key2 = P3^5;//按钮s2
  10. sbit key3 = P3^6;//按钮s3
  11. sbit key4 = P3^7;//按钮s4
  12. sbit u4_out1 = P1^0;//左红外循迹
  13. sbit u4_out2 = P1^1;//右红外循迹
  14. #define c_stop  {A1=0;A2=0;B1=0;B2=0;}//小车停止
  15. #define c_go    {A1=1;A2=0;B1=1;B2=0;}//小车向前
  16. #define c_bask  {A1=0;A2=1;B1=0;B2=1;}//小车后退
  17. #define c_left  {A1=1;A2=0;B1=0;B2=1;}//小车向左
  18. #define c_right {A1=0;A2=1;B1=1;B2=0;}//小车向右
  19. uchar shu;

  20. void delayms(uint xms);//延时xms毫秒;

  21. bit start;
  22. void delayms(uint xms);//延时xms毫秒;
  23. void main(void)
  24. {
  25.         c_init();//每次都需要先调用此函数
  26. c_stop;//单片机上电先让电机停止。
  27.         while(1)//进入死循环,一直循环{}里的程序
  28.         {
  29.                 if(key1==0)//如果检测到key1为0,测判断按键被按下
  30.                 {
  31.                         delayms(5);//延时大约5ms防止按键振动产生影响
  32.                         if(key1==0)//延时5ms后key1为0,测确定按键被按下,执行按钮按下后的程序
  33.                         {
  34.                                 c_right;//小车向右
  35.                                 delayms(3000) ;
  36.                                 c_left;//小车向左
  37.                                 delayms(3000) ;
  38.                                 c_bask;//小车向后
  39.                                 delayms(3000) ;
  40.                                 c_go;//小车向前
  41.                                 delayms(3000) ;
  42.                                  c_stop;
  43. //                                while(key1==0);//等待按钮被松开
  44.                         }
  45.                 }
  46.                
  47.                 if(key2==0)//如果检测到key2为0,测判断按键被按下
  48.                 {
  49.                         delayms(5);//延时大约5ms防止按键振动产生影响
  50.                         if(key2==0)//延时5ms后key2为0,测确定按键被按下,执行按钮按下后的程序
  51.                         {
  52.                                 c_bask;
  53.                                 delayms(2000);//小车后退
  54.                                 c_stop;
  55.                                
  56.                                 while(key2==0);//等待按钮被松开
  57.                         }
  58.                 }
  59.                
  60.                 if(key3==0)//如果检测到key3为0,测判断按键被按下
  61.                 {
  62.                         delayms(5);//延时大约5ms防止按键振动产生影响
  63.                         if(key3==0)//延时5ms后key3为0,测确定按键被按下,执行按钮按下后的程序
  64.                         {
  65.                                   shu++;
  66.                                   if(shu==3)
  67.                                    shu=0;
  68.                                   if(shu==2)
  69.                                   {
  70.                                           start = ~start;
  71.                                   }

  72.                                 while(key3==0);//等待按钮被松开
  73.                                         if(start == 0)//停止
  74.                 {
  75.                         c_stop;
  76.                 }
  77.                
  78.                 else if(start == 1)//开始红外循迹
  79.                 {
  80.                          while(1)
  81.                          {
  82.                         if((u4_out1==0)&(u4_out2==1))//当右循迹等于1时,说明小车右循迹在循迹线上,小车需左转
  83.                         {
  84.                                 c_left;
  85.                                 delayms(50);
  86.                                 c_go;
  87.                                 delayms(10);
  88.                                 c_stop;
  89.                                 delayms(50);
  90.                         }
  91.                         else if((u4_out1==1)&(u4_out2==0))//当左循迹等于1时,说明小车左循迹在循迹线上,小车需要右转
  92.                         {
  93.                                 c_right;
  94.                                 delayms(50);
  95.                                 c_go;
  96.                                 delayms(10);
  97.                                 c_stop;
  98.                                 delayms(50);
  99.                         }
  100.                         else if(((u4_out1==0)&(u4_out2==0))|((u4_out1==1)&(u4_out2==1)))//当小车左右两边的循迹一致时,小车直走
  101.                         {
  102.                                 c_go;
  103.                                 delayms(50);
  104.                                 c_stop;
  105.                                 delayms(30);
  106.                         }
  107.                 }
  108.                         }
  109.                         }
  110.                 }
  111.                
  112.         }
  113. }
复制代码
  1. #include"car_psb.h"
  2. #define smg P2

  3. sbit b = P0^4;//蜂鸣器驱动三极管B管脚

  4. sbit u3_en = P4^4;//u3的使能管脚
  5. sbit u4_en = P4^5;//u4芯片的使能管脚
  6. sbit u5_en = P4^6;//u5芯片的使能管脚

  7. sbit key1 = P0^6;//s1按钮
  8. sbit key2 = P3^5;//s2按钮
  9. sbit key3 = P3^6;//s3按钮
  10. sbit key4 = P3^7;//s4按钮

  11. sbit DQ = P0^5;//ds18b20数据线

  12. sbit DATA=P4^7;   //双向数据线
  13. sbit RST=P1^7;    //使能线
  14. sbit SCLK=P0^7;   //时钟线

  15. sbit A1 = P0^3;
  16. sbit A2 = P0^2;//A1为L293芯片2脚(IN1),A2为L293芯片7脚(IN2),控制右电机
  17. sbit B1 = P0^1;
  18. sbit B2 = P0^0;//B1为L293芯片10脚(IN3),B2为L293芯片15脚(IN4),控制左电机
  19.                                                          //注意芯片使能管脚1脚(E1)和9脚(E2)已接vcc高电平,
  20.                                                          //所以不需要单片机控制输出高电平使能

  21. sbit u5_out2 = P1^6;//右光敏电阻
  22. sbit u5_out1 = P1^4;//左光敏电阻

  23. sbit u4_out3 = P1^2;//左红外避障
  24. sbit u4_out4 = P1^3;//右红外避障

  25. sbit u4_out1 = P1^0;//右红外循迹
  26. sbit u4_out2 = P1^1;//左红外循迹

  27. sbit Echo  = P3^3;//超声波信号反馈端
  28. sbit Tring = P3^4;//超声波信号发送端

  29. sbit Rt = P3^2;//红外接收管脚,单片机中断0管脚

  30. unsigned char a[4];//保存红外遥控器的四位数据
  31. unsigned char code tab1[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//数码管位选
  32. unsigned char code ds1302_w[]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//ds1302芯片写字节
  33. unsigned char code ds1302_r[]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};//ds1302芯片写字节

  34. /*************************************************************/
  35. //函数名称:void delayms(unsigned int xms)
  36. //函数功能:延时xms毫秒
  37. //xms取值为0-65535
  38. //调用:为内部调用函数
  39. /************************************************************/
  40. void delayms(unsigned int xms)
  41. {
  42.         unsigned int x,y;
  43.         for(x=xms;x>0;x--)
  44.                 for(y=1100;y>0;y--);
  45. }

  46. /*************************************************************/
  47. //函数名称:void c_stop(void)
  48. //函数功能:小车停止
  49. //调用:为内部调用函数
  50. /************************************************************/
  51. void c_stop(void)  
  52. {A1=0;A2=0;B1=0;B2=0;}//小车停止

  53. /*************************************************************/
  54. //函数名称:void c_go(void)
  55. //函数功能:小车向前
  56. //调用:为内部调用函数
  57. /************************************************************/
  58. void c_go(void)   
  59. {A1=1;A2=0;B1=1;B2=0;}//小车向前

  60. /*************************************************************/
  61. //函数名称:void c_bask(void)
  62. //函数功能:小车后退
  63. //调用:为内部调用函数
  64. /************************************************************/
  65. void c_bask(void)  
  66. {A1=0;A2=1;B1=0;B2=1;}//小车后退

  67. /*************************************************************/
  68. //函数名称:void c_left(void)
  69. //函数功能:小车向左
  70. //调用:为内部调用函数
  71. /************************************************************/
  72. void c_left(void)  
  73. {A1=1;A2=0;B1=0;B2=1;}//小车向左

  74. /*************************************************************/
  75. //函数名称:void c_right(void)
  76. //函数功能:小车向右
  77. //调用:为内部调用函数
  78. /************************************************************/
  79. void c_right(void)
  80. {A1=0;A2=1;B1=1;B2=0;}//小车向右


  81. /*************************************************************/
  82. //函数名称:void bell(unsigned int x,unsigned int time)
  83. //函数功能:蜂鸣器驱动函数,让蜂鸣器循环响停X次
  84. //                                (蜂鸣器响time毫秒,停time毫秒为一次)
  85. //x取值为0-65535,time取值为0-65535
  86. //调用:为外部调用函数
  87. /************************************************************/
  88. void bell(unsigned int x,unsigned int time)
  89. {
  90.         unsigned int i;
  91.         for(i=x;i>0;i--)
  92.         {
  93.                 b = ~b;
  94.                 delayms(time);
  95.         }
  96.         b = 1;
  97. }

  98. /*********************数码管****************************************/

  99. /*************************************************************/
  100. //函数名称:void display_init()
  101. //函数功能:0-7位的数码管显示,初始化程序
  102. //调用:为外部调用函数
  103. /************************************************************/
  104. void display_init(void)
  105. {
  106.         P4SW = 0x70;
  107.         smg = 0xff;
  108. }

  109. /*************************************************************/
  110. //函数名称:void display_07(unsigned char x,unsigned char dat)
  111. //函数功能:0-7位的数码管显示
  112. //x取值为0-7,dat取值为0-0xff
  113. //调用:为外部调用函数
  114. //调用时如:display_07(0,0xc0);则让0位数码管显示0,(0xc0是共阳数码管“0”的编码)
  115. /************************************************************/
  116. void display_07(unsigned char cmd,unsigned dat)
  117. {
  118.         u5_en = 0;
  119.         u3_en = 0;
  120.         u4_en = 0;//先将两个芯片不使能,数据不能改变
  121.         smg = dat;//将段选的数据赋予P2
  122.         u3_en = 1;//u3使能,数据输入
  123.         u3_en = 0;//稍作延时后将u3不使能
  124.         smg = tab1[cmd];//将需要点亮的数码管数据赋予P2
  125.         u4_en = 1;//u4使能,P2数据进入u4
  126.         delayms(2);//u4使能后稍作延时
  127.         smg = 0x00;
  128.         u3_en = 0;
  129.         u4_en = 0;//将两个芯片不使能,数据不能改变结束一轮数据的输入
  130.         u5_en = 0;
  131. }


  132. /*********************led驱动****************************************/

  133. /*************************************************************/
  134. //函数名称:void display_led(unsigned char dat)
  135. //函数功能:8位led的显示
  136. //dat取值为0-0xff
  137. //调用:为外部调用函数
  138. /************************************************************/
  139. void display_led(unsigned char dat)
  140. {
  141.         u5_en = 0;
  142.         u3_en = 0;
  143.         u4_en = 0;//先将两个芯片不使能,数据不能改变
  144.         smg = dat;//将段选的数据赋予P2
  145.         u5_en = 1;//u5使能,数据输入
  146.         u5_en = 0;//稍作延时后将u5不使能
  147. }

  148. /*********************按钮驱动****************************************/

  149. /*************************************************************/
  150. //函数名称:bit k1()
  151. //函数功能:返回一位数据,当按钮按下时返回1,没有按下时返回0
  152. //调用:为外部调用函数
  153. /************************************************************/
  154. bit k1(void)
  155. {
  156.         bit dat;
  157.         if(key1==0)
  158.         {
  159.                 delayms(2);
  160.                 if(key1==0)
  161.                 {
  162.                         dat = 1;
  163.                 }
  164.         }
  165.         else if(key1==1)
  166.         {
  167.                 dat = 0;
  168.         }
  169.        
  170.         return dat;
  171. }

  172. /*************************************************************/
  173. //函数名称:bit k2()
  174. //函数功能:返回一位数据,当按钮按下时返回1,没有按下时返回0
  175. //调用:为外部调用函数
  176. /************************************************************/
  177. bit k2(void)
  178. {
  179.         bit dat;
  180.         if(key2==0)
  181.         {
  182.                 delayms(2);
  183.                 if(key2==0)
  184.                 {
  185.                         dat = 1;
  186.                 }
  187.         }
  188.         else if(key2==1)
  189.         {
  190.                 dat = 0;
  191.         }
  192.        
  193.         return dat;
  194. }

  195. /*************************************************************/
  196. //函数名称:bit k3()
  197. //函数功能:返回一位数据,当按钮按下时返回1,没有按下时返回0
  198. //调用:为外部调用函数
  199. /************************************************************/
  200. bit k3(void)
  201. {
  202.         bit dat;
  203.         if(key3==0)
  204.         {
  205.                 delayms(2);
  206.                 if(key3==0)
  207.                 {
  208.                         dat = 1;
  209.                 }
  210.         }
  211.         else if(key3==1)
  212.         {
  213.                 dat = 0;
  214.         }
  215.        
  216.         return dat;
  217. }

  218. /*************************************************************/
  219. //函数名称:bit k4()
  220. //函数功能:返回一位数据,当按钮按下时返回1,没有按下时返回0
  221. //调用:为外部调用函数
  222. /************************************************************/
  223. bit k4(void)
  224. {
  225.         bit dat;
  226.         if(key4==0)
  227.         {
  228.                 delayms(2);
  229.                 if(key4==0)
  230.                 {
  231.                         dat = 1;
  232.                 }
  233.         }
  234.         else if(key4==1)
  235.         {
  236.                 dat = 0;
  237.         }
  238.        
  239.         return dat;
  240. }


  241. /*********************DS18B20温度传感器驱动****************************************/

  242. /***************************************************/
  243. //函数名称:void delay750us(void);
  244. //函数功能:延时7500us;
  245. /***************************************************/
  246. void delay750us(void)  
  247. {
  248.     unsigned char a,b;
  249.     for(b=112;b>0;b--)
  250.         for(a=17;a>0;a--);
  251. }

  252. /***************************************************/
  253. //函数名称:void delay70us(void);
  254. //函数功能:延时70us;
  255. /***************************************************/
  256. void delay70us(void)  
  257. {
  258.     unsigned char a;
  259.     for(a=192;a>0;a--);
  260. }

  261. /***************************************************/
  262. //函数名称:void delay15us(void);
  263. //函数功能:延时15us;
  264. /***************************************************/
  265. void delay15us(void)   
  266. {
  267.     unsigned char a,b;
  268.     for(b=1;b>0;b--)
  269.         for(a=38;a>0;a--);
  270.     _nop_();  
  271. }

  272. /***************************************************/
  273. //函数名称:void delay45us(void);
  274. //函数功能:延时45us;
  275. /***************************************************/
  276. void delay45us(void)   
  277. {
  278.     unsigned char a,b;
  279.     for(b=49;b>0;b--)
  280.         for(a=1;a>0;a--);
  281.     _nop_();  
  282. }

  283. /***************************************************/
  284. //函数名称:void delay2us(void);
  285. //函数功能:延时2us;
  286. /***************************************************/
  287. void delay2us(void)   
  288. {
  289.     unsigned char a;
  290.     for(a=4;a>0;a--);
  291. }

  292. /***************************************************/
  293. //函数名称:void delay4us(void);
  294. //函数功能:延时4us;
  295. /***************************************************/
  296. void delay4us(void)   
  297. {
  298.     unsigned char a,b;
  299.     for(b=1;b>0;b--)
  300.         for(a=8;a>0;a--);
  301. }

  302. /***************************************************/
  303. //函数名称:void delay6us(void);
  304. //函数功能:延时6us;
  305. /***************************************************/
  306. void delay6us(void)  
  307. {
  308.     unsigned char a;
  309.     for(a=15;a>0;a--);
  310. }

  311. /***************************************************/
  312. //函数名称:void delay30us(void);
  313. //函数功能:延时30us;
  314. /***************************************************/
  315. void delay30us(void)   
  316. {
  317.     unsigned char a;
  318.     for(a=81;a>0;a--);
  319.     _nop_();  
  320. }

  321. /***************************************************/
  322. //函数名称:bit ack_ds18b20(void);
  323. //函数功能:        ds18b20复位答应函数
  324. /***************************************************/
  325. bit ack_ds18b20(void)
  326. {
  327.         bit flag;//返回标志位定义
  328.        
  329.         DQ = 1;//先将数据总线置高电平1
  330.         delayms(2);//延时(延时时间没有太大要求,但尽可能短比较好)
  331.         DQ = 0;//将数据总线拉低
  332.         delay750us();//延时480-960us之内的时间
  333.         DQ = 1;//将总是拉高释放数据线
  334.         delay70us();//将总线拉高后需要等待15-60us后ds18b20会释放一个60-240us的低电平
  335.         if(DQ==0)
  336.                 flag = 1;//检测到总是拉低则输出1
  337.         else
  338.                 flag = 0;//检测总线是高电平则输出0
  339.         delay750us();//从单片机拉高释放数据线后需要延时大于480us才能结束
  340.         DQ = 1;//将数据线释放
  341.        
  342.         return flag;//返回数据
  343. }

  344. /***************************************************/
  345. //函数名称:write_ds18b20(uchar dat)
  346. //函数功能:        向ds18b20发送一个字节的数据
  347. /***************************************************/
  348. void write_ds18b20(unsigned char dat)
  349. {
  350.         unsigned char i;
  351.         DQ = 1;//先将总线拉高
  352.         delayms(1);//稍作延时,时间不定
  353.         for(i=0;i<8;i++)
  354.         {
  355.                 DQ = 0;//先拉低总线
  356.                 delay15us();//延时15us
  357.                 DQ = dat&0x01;//按从低位到高位的顺序发送数据,一次发送一位数据
  358.                 delay45us();//保存数据状态,延时45us
  359.                 DQ = 1;//将总线释放
  360.                 dat>>=1;//将数据右移一位,为下一次数据发送做准备
  361.         }
  362.         DQ = 1;//8位数据发送完后释放总线
  363. }
  364. /***************************************************/
  365. //函数名称:read_ds18b20(uchar dat)
  366. //函数功能:        读取一个字节的数据
  367. /***************************************************/
  368. unsigned char read_ds18b20(void)
  369. {
  370.         unsigned char dat;
  371.         unsigned char i;
  372.         for(i=0;i<8;i++)
  373.         {
  374.                 dat >>= 1;//右移一位
  375.                 DQ = 1;//总线先拉高
  376.                 delay2us();//延时2us
  377.                 DQ = 0;//将总线拉低
  378.                 delay6us();//延时6us
  379.                 DQ = 1;//将总线拉高
  380.                 delay4us();//延时4us
  381.                 if(DQ == 1)//读取总线的状态,如果是1的,就写进数据里,如果是0就不作处理
  382.                         dat |= 0x80;
  383.                 delay30us();//延时30us
  384.         }
  385.        
  386.         return dat;//返回读取到的数据
  387. }

  388. /*************************************************************/
  389. //函数名称:unsigned int Rtemp_ds18b20()
  390. //函数功能:向ds18b20读取温度值,如实际温度为36.5,返回的数据为365
  391. //调用:为外部调用函数
  392. /************************************************************/
  393. unsigned int Rtemp_ds18b20()
  394. {
  395.         bit k;
  396.         unsigned char temph,templ;//读取的温度高低数据保存
  397.         unsigned int temp;//计算后的温度
  398.         k = ack_ds18b20();//先发送复位信号
  399.         if(k==1)//ds18b20如果有答应,则读取温度
  400.         {
  401.                 write_ds18b20(0xcc);//跳过ROM匹配命令
  402.                 write_ds18b20(0xbe);//发送读取温度命令
  403.                 templ = read_ds18b20();//读取温度低8位
  404.                 temph = read_ds18b20();//读取温度高8位
  405.                 temp = (temph*256+templ)*0.0625*10;//将读取的温度数据进行计算转换为温度值,
  406.         }                                                                                                                                                //并扩大10倍,将小数点后一位往前移动一位,方便显示               

  407.         k = ack_ds18b20();//先发送复位信号
  408.         if(k==1)//ds18b20如果有答应,则发送温度转换命令
  409.         {
  410.                 write_ds18b20(0xcc);//跳过ROM匹配命令
  411.                 write_ds18b20(0x44);//发送温度转换命令
  412.         }
  413.         return temp;
  414. }


  415. /*********************DS1302驱动****************************************/

  416. void delaynus(unsigned char n)
  417. {
  418.         unsigned char i;
  419.         for(i=0;i<(n*10);i++);
  420. }

  421. /*************************************************************/
  422. //函数名称:void Write1302(unsigned char dat)
  423. //函数功能:向ds1302芯片发送一个字节的数据
  424. //调用:为内部调用函数
  425. /************************************************************/
  426. void Write1302(unsigned char dat)//发送一个字节的数据
  427. {
  428.   unsigned char i;
  429.   SCLK=0;            //先将时钟线置位
  430.   delaynus(2);      
  431.   for(i=0;i<8;i++)      
  432.   {
  433.                 DATA=dat&0x01;   //先发送低电平
  434.                 delaynus(2);      
  435.                 SCLK=1;          //拉高时钟线,时钟芯片在这时候读取数据线上的电平
  436.                 delaynus(2);      
  437.                 SCLK=0;          //时钟线复位
  438.                 dat>>=1;         //数据右移
  439.         }       
  440. }

  441. /*************************************************************/
  442. //函数名称:unsigned char Read1302(void)
  443. //函数功能:向ds1302芯片读取一个字节的数据
  444. //调用:为内部调用函数
  445. /************************************************************/
  446. unsigned char Read1302(void)
  447. {
  448.         unsigned char i,dat;
  449.         delaynus(2);        
  450.         for(i=0;i<8;i++)   
  451.         {
  452.                 dat>>=1;      
  453.                 if(DATA==1)   
  454.                 dat|=0x80;   
  455.                 SCLK=1;      
  456.                 delaynus(2);   
  457.                 SCLK=0;      
  458.                 delaynus(2);  
  459.         }         
  460.         return dat;        
  461. }  


  462. /*************************************************************/
  463. //函数名称:void WriteSet1302(unsigned char Cmd,unsigned char dat)
  464. //函数功能:向ds1302芯片内部某个字节(Cmd)写入一个数据(dat)
  465. //参数说明:Cmd为0-6,分别代表"秒,分,时,日,月,周,年"
  466. //调用:为外部调用函数
  467. /************************************************************/
  468. void WriteSet1302(unsigned char Cmd,unsigned char dat)//向时钟写入一个字节的数据
  469. {
  470.         WriteSet1302(0x8E,0x00);  //关闭写保护
  471.         RST=0;           
  472.         SCLK=0;         
  473.         RST=1;           
  474.         delaynus(2);     
  475.         Write1302(ds1302_w[Cmd]);  
  476.         Write1302(((dat/10)<<4)|(dat%10));  
  477.         SCLK=1;         
  478.         RST=0;           
  479. }

  480. /*************************************************************/
  481. //函数名称:unsigned char ReadSet1302(unsigned char Cmd)
  482. //函数功能:向ds1302芯片内部某个字节(Cmd)读出一个数据,并将数据返回
  483. //调用:为外部调用函数
  484. /************************************************************/
  485. unsigned char ReadSet1302(unsigned char Cmd)
  486. {
  487.         unsigned char dat;
  488.         RST=0;                 
  489.         SCLK=0;               
  490.         RST=1;                 
  491.         Write1302(ds1302_r[Cmd]);        
  492.         dat=Read1302();      
  493.         SCLK=1;              
  494.         RST=0;   
  495.        
  496.         return dat;         
  497. }

  498. /******************************寻光模块*******************************/

  499. /*************************************************************/
  500. //函数名称:bit gm_left(void)
  501. //函数功能:左寻光光敏电阻,当亮度大时返回1,亮度比较小时返回0
  502. //调用:为外部调用函数
  503. /************************************************************/
  504. bit gm_left(void)
  505. {
  506.         bit dat;
  507.         dat = u5_out1;
  508.         return dat;
  509. }

  510. /*************************************************************/
  511. //函数名称:bit gm_left(void)
  512. //函数功能:右寻光光敏电阻,当亮度大时返回1,亮度比较小时返回0
  513. //调用:为外部调用函数
  514. /************************************************************/
  515. bit gm_right(void)
  516. {
  517.         bit dat;
  518.         dat = u5_out2;
  519.         return dat;
  520. }

  521. /******************************红外避障模块*******************************/

  522. /*************************************************************/
  523. //函数名称:bit hbz_left(void)
  524. //函数功能:左红外避障,接收到反射回来的信号返回0,没有收到信号返回1
  525. //调用:为外部调用函数
  526. /************************************************************/
  527. bit hbz_left(void)
  528. {
  529.         bit dat;
  530.         dat = u4_out3;
  531.         return dat;
  532. }

  533. /*************************************************************/
  534. //函数名称:bit hbz_right(void)
  535. //函数功能:右红外避障,接收到反射回来的信号返回0,没有收到信号返回1
  536. //调用:为外部调用函数
  537. /************************************************************/
  538. bit hbz_right(void)
  539. {
  540.         bit dat;
  541.         dat = u4_out4;
  542.         return dat;
  543. }

  544. /******************************红外循迹模块*******************************/
  545. /*************************************************************/
  546. //函数名称:bit hxj_left(void)
  547. //函数功能:左红外循迹,接收到反射回来的信号返回0,没有收到信号返回1
  548. //调用:为外部调用函数
  549. /************************************************************/
  550. bit hxj_left(void)
  551. {
  552.         bit dat;
  553.         dat = u4_out2;
  554.         return dat;
  555. }

  556. /*************************************************************/
  557. //函数名称:bit hxj_right(void)
  558. //函数功能:右红外循迹,接收到反射回来的信号返回0,没有收到信号返回1
  559. //调用:为外部调用函数
  560. /************************************************************/
  561. bit hxj_right(void)
  562. {
  563.         bit dat;
  564.         dat = u4_out1;
  565.         return dat;
  566. }

  567. /******************************超声波模块*******************************/

  568. /***************************************************/
  569. //函数名称:void delay20us();
  570. //函数功能:延时20us;
  571. /***************************************************/
  572. void delay20us()                //@11.0592MHz
  573. {
  574.         unsigned char i;

  575.         _nop_();
  576.         _nop_();
  577.         _nop_();
  578.         i = 24;
  579.         while (--i);
  580. }

  581. /***************************************************/
  582. //函数名称:void csb_init(void);
  583. //函数功能:        超声波模块初始化程序
  584. //使用定时器1计算时间,
  585. /***************************************************/
  586. void csb_init(void)
  587. {
  588.         EA = 1;                                //打开中断总开关
  589.         AUXR &= 0xBF;        //定时器时钟12T模式
  590.         TMOD &= 0x0F;               
  591.         TMOD |= 0x10;        //定时器1工作方式1,16位计时模式       
  592.         TF1 = 0;                        //将定时器溢出标志复位       
  593. }

  594. /***************************************************/
  595. //函数名称:unsigned int get_distance(void);
  596. //函数功能:        获取超声波返回的时间,并计算距离,返回计算好的距离
  597. //使用定时器1计算时间,
  598. /***************************************************/
  599. unsigned int get_distance(void)
  600. {
  601.          unsigned int Distance;        //测量到的距离
  602.    unsigned char flag_i=0;        //距离测量成果标志位
  603.          TR1 = 0;                        //先将定时器1关闭
  604.    TH1 = 0;
  605.          TL1 = 0;                        //将定时器1的计数清零
  606.    Tring = 0;                //信号端先置零
  607.    delayms(2);                //稍微延时一下
  608.    Tring = 1;       
  609.    delay20us();               
  610.    Tring = 0;                   //信号端置位保存大约10us的时间,产生开始信号
  611.        
  612.    while(Echo==0);         //等待返回高电平
  613.    TR1 = 1;                                        //启动定时器1开始计数
  614.    while(Echo==1)        //当为1时计时
  615.    {
  616.                    Distance = TH1*256+TL1;
  617.                         if(Distance>27110)                           //大约4000时间已超出出量距离,返回888
  618.                         {
  619.                                 TR1 = 0;
  620.                                 flag_i = 2;
  621.                                 Distance = 888;
  622.                                 break;
  623.                         }
  624.                         else
  625.                                 flag_i = 1;
  626.    }
  627.    if(flag_i==1)
  628.    {
  629.                    TR1 = 0;                                //关闭定时器3;
  630.                         Distance = TH1*256+TL1;                //读取定时器里的时间
  631.                         Distance *= 0.01844;                        //距离=(时间*速度)/2,时间单位秒,速度单位m/s,距离单位米
  632.                         if(Distance>500)                                //定时器一个计时时间:12/11.0592=1.085
  633.                         Distance=888;                                                //时间=(TH1*256+TL1)*1.085,单位微秒,转换为秒需除1000000
  634.    }                                                                                                        //距离=(340*(TH1*256+TL1)*1.085)/2/1000000=(TH1*256+TL1)*0.0001844,单位米
  635.                                                                                                                         //转化为厘米显示:0.0001844*100=0.01844,单位厘米
  636.          TR1 = 0;//关闭定时器1中断
  637.    return Distance;//将计算出的距离返回
  638. }

  639. /******************************红外遥控模块*******************************/
  640. /***************************************************/
  641. //函数名称:void hwyk_init(void);
  642. //函数功能:        超声波模块初始化程序
  643. //使用定时器1计算时间,
  644. /***************************************************/
  645. void hwyk_init(void)
  646. {
  647.         EA = 1;//打开中断总开关
  648.         ET1 = 1;//允许定时器0中断
  649.         EX0 = 1;//允许外部中断0中断
  650.         IT0 = 1;//下降沿触发外部中断0
  651.         AUXR &= 0xBF;                //定时器工作在12T模式
  652.         TMOD &= 0x0f;                //将定时器工作模式设置先复位
  653.         TMOD |= 0x10;                //设置定时工作在方式1中,16位计时模式
  654.         TH1 = 0;
  655.         TL1 = 0;//将定时器计时溢出清零
  656. }

  657. /***************************************************/
  658. //函数名称:unsigned char get_hwyk(void);
  659. //函数功能:        返回接收到的红外按键码
  660. //使用定时器1计算时间,
  661. /***************************************************/
  662. unsigned char get_hwyk(void)
  663. {
  664.         unsigned char i,x;//i为计算接上多少字节的数据,x为计算每一个字节数据的第几位
  665.         unsigned char temp;//临时接到字节数据存储
  666.         unsigned int Ltime,Htime;//波形的高低电平时间存储
  667.         EX0 = 0;//先将中断允许关闭,放在其他的电平造成干扰
  668.         TH1 = 0;
  669.         TL1 = 0;//将定时器的计算寄存器清零
  670.         TR1 = 1;//定时器开始运行计时
  671.         while(Rt==0)//计算低电平时间
  672.         {
  673.                 if((TH1*256+TL1)>16000)//如果低电平时间超过16000,则实际时间是16000*1.085=17360us,是引导码9000us的两倍
  674.                 {
  675.                         Rt = 1;//将管脚释放
  676.                         IE0 = 0;//将中断标记位清零
  677.                         TR1 = 0;//定时器关闭
  678.                         TF1 = 0;
  679.                         EX0 = 1;//重新开启外中断
  680.                         break;//直接退出中断
  681.                 }
  682.         }
  683.         TR1 = 0;
  684.         Ltime = TH1*256+TL1;//记录低电平时间
  685.         TH1 = 0;
  686.         TL1 = 0;//将定时器的计算寄存器清零
  687.         TR1 = 1;//定时器开始运行计时
  688.         while(Rt==1)//计算高电平时间
  689.         {
  690.                 if((TH1*256+TL1)>9000)//如果高电平时间超过9000,则实际时间是9000*1.085=9765us,是引导码4500us的两倍
  691.                 {
  692.                         Rt = 1;//将管脚释放
  693.                         IE0 = 0;//将中断标记位清零
  694.                         TR1 = 0;//定时器关闭
  695.                   TF1 = 0;
  696.                         EX0 = 1;//重新开启外中断       
  697.                         break;//直接退出中断
  698.                 }
  699.         }
  700.         TR1 = 0;
  701.         Htime = TH1*256+TL1;//记录高电平时间
  702.        
  703.         if((Ltime>7800)&&(Ltime<8800)&&(Htime>3800)&&(Htime<4500))//如果引导码低电平在9000us左右,高电平在4500us左右,则符合
  704.         {
  705.                 for(i=0;i<4;i++)//一共有4个字节数据
  706.                 {
  707.                         for(x=0;x<8;x++)//每个字节有8位数据
  708.                         {
  709.                                 temp >>= 1;//先接上低位,在接高位,所以需要先左移一位
  710.                                 while(Rt==0);//跳过低电平
  711.                                
  712.                                 TH1 = 0;
  713.                                 TL1 = 0;
  714.                                 TR1 = 1;
  715.                                 while(Rt==1);
  716.                                 TR1 = 0;
  717.                                 Htime = TH1*256+TL1;//测量高电平时间
  718.                                
  719.                                 if((Htime>300)&&(Htime<720))//高电平符合则为0
  720.                                         temp &= 0x7f;
  721.                                 if((Htime>1300)&&(Htime<1800))//高电平符合则为1
  722.                                         temp |= 0x80;
  723.                         }
  724.                         a[i] = temp;//将每个字节都存储到数组中
  725.                 }
  726.         }
  727.         Rt = 1;
  728.         IE0 = 0;
  729.         TR1 = 0;
  730.         TF1 = 0;
  731.         EX0 = 1;//重新启动外部中断
  732.        
  733.         return a[2];//读取遥控编码的第三位,第三位为按键码
  734. }

  735. /******************************红外遥控模块*******************************/
  736. /***************************************************/
  737. //函数名称:void c_init(void);
  738. //函数功能:        小车初始化,每个程序都需要保护这个
  739. /***************************************************/
  740. void c_init(void)
  741. {
  742.         unsigned char i=0;
  743.         unsigned char dddd;
  744.         unsigned int vvvv;
  745.         if(i==1)
  746.         {
  747.         c_stop();
  748.         c_go();
  749.         c_bask();
  750.         c_left();
  751.         c_right();
  752.         bell(1,200);
  753.         display_init();
  754.         display_07(0,0);
  755.         display_led(0xaa);
  756.         k1();
  757.         k2();
  758.         k3();
  759.         k4();
  760.         vvvv = Rtemp_ds18b20();
  761.         WriteSet1302(0x80,0x00);
  762.         dddd = ReadSet1302(0x81);
  763.         gm_left();
  764.         gm_right();
  765.         hbz_left();
  766.         hbz_right();
  767.         hxj_left();
  768.         hxj_right();
  769.         csb_init();
  770.         vvvv = get_distance();
  771.         hwyk_init();
  772.         dddd = get_hwyk();
  773.         }
  774. }
复制代码


新建文件夹.zip

621.56 KB, 下载次数: 39, 下载积分: 黑币 -5

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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