找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于51单片机的智能迷宫小车设计 含PCB原理图 源程序

  [复制链接]
跳转到指定楼层
楼主

单片机的智能迷宫小车的原理图和pcb,都是用ad画的








51单片机的智能迷宫小车的所有资料下载:
迷宫源程序.zip (112.56 KB, 下载次数: 156)

小车电路图.zip (2.37 MB, 下载次数: 133)





下面是部分代码预览:
  1. #include<reg52.h>
  2. #include<stdio.h>
  3. #include <intrins.h>
  4. #include<string.h>
  5. #include<math.h>
  6. #define uchar unsigned char  //无符号字符型占用一个字节 范围0~255,                          
  7. #define uint unsigned int  /*无符号整型占用二个字节 范围0~65535*/
  8. #define dataPort P1
  9. uchar bianma1;           //编码计数
  10. uint yejinjishu=0;        //液晶计数
  11. uchar wang=1;
  12. uchar guo=1;
  13. uchar  a1=0,a2=0,a3=0,a4=0;         //小车方向判断
  14. uchar  b1=0,b2=0,b3=0,b4=0;

  15. //电机操作初始化
  16. uchar i=0,j=0; /* 中断计数器 */  
  17. uchar m1=0; /* 电机1速度值 */  
  18. uchar m2=0; /* 电机2速度值 */   

  19. sbit s1=P0^0; /* L298的Input 1 */  
  20. sbit s2=P0^1; /* L298的Input 2 */  
  21. sbit s3=P0^2; /* L298的Input 3 */  
  22. sbit s4=P0^3; /* L298的Input 4 */
  23. sbit en1=P0^4; /* L298的Enable A */  
  24. sbit en2=P0^5; /* L298的Enable B */  

  25. //寻线 红外接收头 初始化
  26. sbit P2_2=P3^1;
  27. sbit P2_3=P2^3;
  28. sbit P2_4=P2^4;
  29. sbit P2_5=P2^5;
  30. sbit P2_6=P2^6;
  31. sbit P2_7=P2^7;

  32. //按键初始化
  33. sbit markkey=P2^0;  
  34. sbit logokey=P2^1;  
  35. uchar mark=0;  //选线while 标志
  36. uchar logo=0;  //最佳路线行走标记


  37. unsigned char idata road[30];         //转向数组
  38. unsigned char code aa[10][4]={"LBL","LBA","ABL","ABA","ABR","RBA","RBR","RBL","LBR"};//数组无需改变 code
  39. unsigned char code  a[10][2]={"A","R","R","B","L","L","A","B","B"};
  40. unsigned char idata *p;   //地址寄存器 用于字符串操作
  41. //unsigned char idata  cun24c02[15];//ram允许情况可以无限添加 记忆数组


  42. // 函数初始化
  43. void KEY();
  44. void line();
  45. void stop();
  46. void youlun();
  47. void zuolun();
  48. void zhizou();
  49. void zhizou1();
  50. void zhizou2();
  51. void ISD1420p(uchar t1,uint t2);
  52. void Run_SNAKE(void);


  53. /********简易延时函数******/  
  54. void delay(uint t)
  55. {  
  56.     for(t;t>0;t--);  
  57. }

  58. void DelayUs(uint us)  //标准延时 us
  59. {
  60. unsigned char uscnt;
  61. uscnt=us>>1;         
  62. while(--uscnt);
  63. }

  64. void DelayMs(uint ms)  //标准延时 ms
  65. {
  66. while(--ms)
  67.    {
  68.      DelayUs(250);
  69.      DelayUs(250);
  70.      DelayUs(250);
  71.      DelayUs(250);
  72.    }
  73. }  



  74. //595 初始化 串转并
  75. /*sbit sclk=P3^0;
  76. sbit dat=P3^1;       
  77. sbit st = P2^1;
  78. void write595(uchar wrdat)
  79. {
  80.   uchar sum;
  81.   for(sum=0;sum<8;sum++)
  82.      {
  83.                   sclk=0;
  84.                   dat=wrdat&0x80;
  85.                   wrdat<<=1;
  86.                   sclk=1;
  87.          }
  88.   st=0;
  89.   _nop_();
  90.   _nop_();
  91.   _nop_();
  92.   _nop_();
  93.   _nop_();
  94.   _nop_();
  95.   _nop_();
  96.   st=1;
  97. } */
  98. sbit SDA=P0^6;//sbit dat=P3^1;
  99. sbit SCL=P2^2;//sbit sclk=P3^0;
  100. sbit jiyibiaozhi=P0^7;//st = P2^1;
  101. void write595(uchar wrdat)
  102. {
  103.   uchar sum;
  104.   for(sum=0;sum<8;sum++)
  105.      {
  106.                   SCL=0;
  107.                   SDA=wrdat&0x80;
  108.                   wrdat<<=1;
  109.                   SCL=1;
  110.          }
  111.   jiyibiaozhi=0;
  112.   _nop_();
  113.   _nop_();
  114.   _nop_();
  115.   _nop_();
  116.   _nop_();
  117.   _nop_();
  118.   _nop_();
  119.   jiyibiaozhi=1;
  120. }

  121. /*******************************************************
  122. ********************************************************
  123. ***************24c02部分*********************************
  124. ********************************************************
  125. *******************************************************
  126. #define  _Nop()  _nop_()  //定义空指令                       
  127. bit ack;                      //应答标志位
  128. //sbit SDA=P2^1;
  129. //sbit SCL=P2^0;
  130. /*------------------------------------------------
  131.                     启动总线
  132. ------------------------------------------------
  133. void Start_I2c()
  134. {
  135.   SDA=1;   //发送起始条件的数据信号
  136.   _Nop();
  137.   SCL=1;
  138.   _Nop();    //起始条件建立时间大于4.7us,延时
  139.   _Nop();
  140.   _Nop();
  141.   _Nop();
  142.   _Nop();   
  143.   SDA=0;     //发送起始信号
  144.   _Nop();    //起始条件锁定时间大于4μ
  145.   _Nop();
  146.   _Nop();
  147.   _Nop();
  148.   _Nop();      
  149.   SCL=0;    //钳住I2C总线,准备发送或接收数据
  150.   _Nop();
  151.   _Nop();
  152. }
  153. /*------------------------------------------------
  154.                     结束总线
  155. -----------------------------------------------
  156. void Stop_I2c()
  157. {
  158.   SDA=0;    //发送结束条件的数据信号
  159.   _Nop();   //发送结束条件的时钟信号
  160.   SCL=1;    //结束条件建立时间大于4μ
  161.   _Nop();
  162.   _Nop();
  163.   _Nop();
  164.   _Nop();
  165.   _Nop();
  166.   SDA=1;    //发送I2C总线结束信号
  167.   _Nop();
  168.   _Nop();
  169.   _Nop();
  170.   _Nop();
  171. }
  172. /*----------------------------------------------------------------
  173.                  字节数据传送函数               
  174. 函数原型: void  SendByte(unsigned char c);
  175. 功能:  将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
  176.      此状态位进行操作.(不应答或非应答都使ack=0 假)     
  177.      发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
  178. ------------------------------------------------------------------
  179. void  SendByte(unsigned char c)
  180. {
  181. unsigned char BitCnt;

  182. for(BitCnt=0;BitCnt<8;BitCnt++)  //要传送的数据长度为8位
  183.     {
  184.      if((c<<BitCnt)&0x80)SDA=1;   //判断发送位
  185.        else  SDA=0;               
  186.      _Nop();
  187.      SCL=1;               //置时钟线为高,通知被控器开始接收数据位
  188.       _Nop();
  189.       _Nop();             //保证时钟高电平周期大于4μ
  190.       _Nop();
  191.       _Nop();
  192.       _Nop();         
  193.      SCL=0;
  194.     }
  195.    
  196.     _Nop();
  197.     _Nop();
  198.     SDA=1;               //8位发送完后释放数据线,准备接收应答位
  199.     _Nop();
  200.     _Nop();   
  201.     SCL=1;
  202.     _Nop();
  203.     _Nop();
  204.     _Nop();
  205.     if(SDA==1)ack=0;     
  206.        else ack=1;        //判断是否接收到应答信号
  207.     SCL=0;
  208.     _Nop();
  209.     _Nop();
  210. }

  211. /*----------------------------------------------------------------
  212.                  字节数据传送函数               
  213. 函数原型: unsigned char  RcvByte();
  214. 功能:  用来接收从器件传来的数据,并判断总线错误(不发应答信号),
  215.      发完后请用应答函数。  
  216. ------------------------------------------------------------------       
  217. unsigned char  RcvByte()
  218. {
  219.   unsigned char retc;
  220.   unsigned char BitCnt;
  221.   
  222.   retc=0;
  223.   SDA=1;             //置数据线为输入方式
  224.   for(BitCnt=0;BitCnt<8;BitCnt++)
  225.       {
  226.         _Nop();           
  227.         SCL=0;       //置时钟线为低,准备接收数据位
  228.         _Nop();
  229.         _Nop();      //时钟低电平周期大于4.7us
  230.         _Nop();
  231.         _Nop();
  232.         _Nop();
  233.         SCL=1;       //置时钟线为高使数据线上数据有效
  234.         _Nop();
  235.         _Nop();
  236.         retc=retc<<1;
  237.         if(SDA==1)retc=retc+1; //读数据位,接收的数据位放入retc中
  238.         _Nop();
  239.         _Nop();
  240.       }
  241.   SCL=0;   
  242.   _Nop();
  243.   _Nop();
  244.   return(retc);
  245. }

  246. /*----------------------------------------------------------------
  247.                      应答子函数
  248. 原型:  void Ack_I2c(void);

  249. ---------------------------------------------------------------
  250. void Ack_I2c(void)
  251. {
  252.   
  253.   SDA=0;     
  254.   _Nop();
  255.   _Nop();
  256.   _Nop();      
  257.   SCL=1;
  258.   _Nop();
  259.   _Nop();              //时钟低电平周期大于4μ
  260.   _Nop();
  261.   _Nop();
  262.   _Nop();  
  263.   SCL=0;               //清时钟线,钳住I2C总线以便继续接收
  264.   _Nop();
  265.   _Nop();   
  266. }
  267. /*----------------------------------------------------------------
  268.                      非应答子函数
  269. 原型:  void NoAck_I2c(void);

  270. ----------------------------------------------------------------
  271. void NoAck_I2c(void)
  272. {
  273.   
  274.   SDA=1;
  275.   _Nop();
  276.   _Nop();
  277.   _Nop();      
  278.   SCL=1;
  279.   _Nop();
  280.   _Nop();              //时钟低电平周期大于4μ
  281.   _Nop();
  282.   _Nop();
  283.   _Nop();  
  284.   SCL=0;                //清时钟线,钳住I2C总线以便继续接收
  285.   _Nop();
  286.   _Nop();   
  287. }
  288. /*----------------------------------------------------------------
  289.                     向有子地址器件发送多字节数据函数               
  290. 函数原型: bit  ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no);  
  291. 功能:     从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
  292.           地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。
  293.            如果返回1表示操作成功,否则操作有误。
  294. 注意:    使用前必须已结束总线。
  295. ----------------------------------------------------------------
  296. bit ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
  297. {
  298.    unsigned char i;
  299. for(i=0;i<no;i++)
  300.     {
  301.    Start_I2c();               //启动总线
  302.    SendByte(sla);             //发送器件地址
  303.      if(ack==0)return(0);
  304.    SendByte(suba);            //发送器件子地址
  305.      if(ack==0)return(0);

  306.      SendByte(*s);            //发送数据
  307.        if(ack==0)return(0);
  308.      Stop_I2c();                  //结束总线
  309.      DelayMs(1);               //必须延时等待芯片内部自动处理数据完毕
  310.          s++;
  311.          suba++;
  312.     }
  313.   return(1);
  314. }
  315. /*----------------------------------------------------------------
  316.                     向有子地址器件读取多字节数据函数               
  317. 函数原型: bit  ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no);  
  318. 功能:     从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
  319.           地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。
  320.            如果返回1表示操作成功,否则操作有误。
  321. 注意:    使用前必须已结束总线。
  322. ---------------------------------------------------------------
  323. bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
  324. {
  325.    unsigned char i;

  326.    Start_I2c();               //启动总线
  327.    SendByte(sla);             //发送器件地址
  328.      if(ack==0)return(0);
  329.    SendByte(suba);            //发送器件子地址
  330.      if(ack==0)return(0);

  331.    Start_I2c();
  332.    SendByte(sla+1);
  333.       if(ack==0)return(0);

  334.   for(i=0;i<no-1;i++)
  335.     {
  336.      *s=RcvByte();              //发送数据
  337.       Ack_I2c();                //发送就答位
  338.      s++;
  339.     }
  340.    *s=RcvByte();
  341.     NoAck_I2c();                 //发送非应位
  342.     Stop_I2c();                    //结束总线
  343.   return(1);
  344. }

  345. /*------------------------------------------------
  346.                    主函数
  347. ------------------------------------------------
  348. main()
  349. {
  350. //bit flag;
  351. unsigned char i;
  352. DelayMs(6000);
  353. ISendStr(0xae,80,dat,5);            //写入24c02
  354. DelayMs(10);                          //写入后必须延时等待24c02内部
  355.                                        //烧录数据处理完毕方可继续其他操作
  356. IRcvStr(0xae,80,dat1,5);             //从24c02读出数据
  357. while(1)
  358.      {

  359.            for(i=0;i<5;i++)              //查表
  360.              {
  361.                  DelayMs(2000);
  362.          P1=dat1[i];
  363.                  }
  364.          }
  365. }  */

  366. /*****************************************************
  367. ******************************************************
  368. **********************12864部分***********************
  369. ******************************************************
  370. *****************************************************/
  371. sbit rs=P3^7;
  372. sbit rw=P3^6;
  373. sbit en=P3^5;
  374. sbit psb=P3^4;
  375. sbit rst=P3^3;

  376. uchar key1=1,key2=1,key3=1,key4=1;

  377. void checkBusy(void)   //判忙
  378. {
  379. rs=0;
  380. rw=1;
  381. en=1;
  382. dataPort=0xff;
  383. while(dataPort & 0x80);
  384. en=0;
  385. }

  386. void writeCommand(unsigned char cmd)   //写命令
  387. {
  388. checkBusy();
  389. rs=0;
  390. rw=0;
  391. en=1;
  392. dataPort=cmd;
  393. _nop_();
  394. en=0;
  395. }

  396. void writeData(unsigned char adata)          //写数据
  397. {
  398. checkBusy();
  399. rs=1;
  400. rw=0;
  401. en=1;
  402. dataPort=adata;
  403. _nop_();
  404. en=0;
  405. }

  406. unsigned char readData(void)        //读数据
  407. {
  408. unsigned char RData;
  409. dataPort=0xff;
  410. checkBusy();
  411. rs=1;
  412. rw=1;
  413. en=0;
  414. en=1;
  415. RData=dataPort;
  416. en=0;
  417. return RData;
  418. }       

  419. void ClrGDRAM(void)          //显示用户自定义字符
  420. {
  421.         unsigned char x,y;
  422.         for(y=0;y<64;y++)
  423.             for(x=0;x<16;x++)
  424.             {
  425.                         writeCommand(0x34);
  426.             writeCommand(y+0x80);     //行地址  
  427.             writeCommand(x+0x80);     //列地址  
  428.             writeCommand(0x30);
  429.             writeData(0x00);
  430.             writeData(0x00);
  431.         }
  432.         //writeCommand(0x30);
  433. }

  434. void LcmInit(void)                        //12864初始化
  435. {
  436. writeCommand(0x30);
  437. DelayMs(50);
  438. writeCommand(0x01);
  439. DelayMs(50);
  440. writeCommand(0x06);
  441. DelayMs(50);
  442. writeCommand(0x0c);
  443. ClrGDRAM();
  444. psb=1;
  445. }

  446. /* 清屏*/
  447. void ClrScreen()
  448. {
  449.    writeCommand(0x01);
  450.    DelayMs(15);
  451. }
  452.           
  453. /*画点  打点位置(x0,y0);color=1,点亮;color=0,擦除*/
  454. void drawPoint(unsigned char x,unsigned char y,unsigned char color)
  455. {
  456. unsigned char row,collum,cbite;
  457. unsigned char tempH,tempL;
  458. writeCommand(0x34);
  459. writeCommand(0x36);
  460. collum=x>>4;
  461. cbite=x&0x0f;
  462. if(y<32)
  463.         row=y;
  464. else
  465.         {row=y-32;
  466.         collum+=8;
  467.         }
  468. writeCommand(0x80+row);
  469. writeCommand(0x80+collum);
  470. readData();
  471. tempH=readData();
  472. tempL=readData();
  473. writeCommand(0x80+row);
  474. writeCommand(0x80+collum);
  475. if (color)
  476. {
  477.          if(cbite<8)
  478.          {
  479.          tempH|=(1<<(7-cbite));
  480.          }
  481.          else
  482.          {
  483.          tempL|=(1<<(15-cbite));
  484.          }
  485. }
  486. else
  487. {
  488.            if(cbite<8)
  489.          {
  490.          tempH&=~(1<<(7-cbite));
  491.          }
  492.          else
  493.          {
  494.          tempL&=~(1<<(15-cbite));
  495.          }
  496. }
  497. writeData(tempH);
  498. writeData(tempL);
  499. writeCommand(0x30);
  500. }

  501. /**3X3个点合为一个**/
  502. void drawPoint_3(unsigned char x,unsigned char y, unsigned char color)   
  503. {
  504.   drawPoint(x,  y,  color);
  505.   drawPoint(x+1,y,  color);
  506.   drawPoint(x-1,y,  color);
  507.   drawPoint(x+1,y-1,color);
  508.   drawPoint(x,  y-1,color);
  509.   drawPoint(x-1,y-1,color);
  510.   drawPoint(x-1,y+1,color);
  511.   drawPoint(x,  y+1,color);
  512.   drawPoint(x+1,y+1,color);
  513.    
  514. }

  515. void QCRAM()  //清楚RAM
  516. {
  517.    uchar x,y;
  518.    uchar color=0;
  519.    for(x=0;x<=128;x++)
  520.      for(y=0;y<=80;y++)
  521.            drawPoint(x,y,color);
  522.           

  523. }

  524. #define SNAKE_Max_Long 20   //最大长度
  525. struct
  526. {
  527.         uchar X[SNAKE_Max_Long];
  528.         uchar Y[SNAKE_Max_Long];
  529.         uchar Long;   
  530. }Snake;        //小车结构体

  531. void Init_SNAKE(void)   
  532. {
  533.         uchar sum;
  534.         Snake.Long=2;                    //定义初始化小车的长度
  535.         for(sum=0;sum<Snake.Long;sum++)        //将小车给赋值
  536.         {
  537.                 Snake.X[sum]=sum+20;
  538.                 Snake.Y[sum]=20;
  539.         }                                                       
  540.         for(sum=0;sum<Snake.Long;sum++)        //将小车给画出来
  541.         {
  542.                 drawPoint_3(Snake.X[sum],Snake.Y[sum],1);
  543.         }                                                       
  544. }

  545. void keyscan()          //转弯检测
  546. {
  547.   if(!key1||!key2||!key3||!key4)
  548.   {
  549.     Run_SNAKE();
  550.            if(key1==0)
  551.                 {
  552.                           key1=1;
  553.                           a1=0;
  554.                           a2=0;
  555.                           a3=0;
  556.                   a4=1;                         
  557.                 }       
  558.         if(key2==0)
  559.                 {
  560.                       key2=1;
  561.                           a1=1;
  562.                           a2=0;
  563.                           a3=0;
  564.                           a4=0;
  565.                 }       
  566.         if(key3==0)
  567.                 {
  568.                           key3=1;
  569.                           a1=0;
  570.                           a2=1;
  571.                           a3=0;
  572.                           a4=0;
  573.                 }               
  574.         if(key4==0)
  575.                 {
  576.                           key4=1;
  577.                           a1=0;
  578.                           a2=0;
  579.                           a3=1;
  580.                           a4=0;
  581.                 }       
  582.    }       
  583. }       

  584. void Run_SNAKE(void)   //小车运动方向
  585. {
  586.         uchar sum=0;
  587.         /***小车的运动方向**/
  588.                         if(a1==1)
  589.                         {
  590.                            if(b1==1)
  591.                                 {
  592.                                            for(sum=0;sum<Snake.Long-1;sum++) // 向右 //小车身都是它前一段的小车身的位置
  593.                                 {
  594.                                      Snake.X[sum]=Snake.X[sum+1];
  595.                                      Snake.Y[sum]=Snake.Y[sum+1];
  596.                             }
  597.                
  598.                                 Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]+0;
  599.                                 Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]+1; //小车头向你要求的方向移动
  600.                                         }
  601.                                 if(b2==1)
  602.                                     {
  603.                                                 for(sum=0;sum<Snake.Long-1;sum++) //向左  //小车身都是它前一段的小车身的位置
  604.                                {
  605.                                      Snake.X[sum]=Snake.X[sum+1];
  606.                                  Snake.Y[sum]=Snake.Y[sum+1];
  607.                                }
  608.                
  609.                                Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]+0;
  610.                                Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]-1; //小车头向你要求的方向移动       
  611.                                         }
  612.                                  if(b3==1)
  613.                                     {
  614.                                                         for(sum=0;sum<Snake.Long-1;sum++)  //  向下  //小车身都是它前一段的小车身的位置
  615.                            {
  616.                                      Snake.X[sum]=Snake.X[sum+1];
  617.                                      Snake.Y[sum]=Snake.Y[sum+1];
  618.                                }
  619.                
  620.                                Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]-1;
  621.                                Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]+0; //小车头向你要求的方向移动
  622.                                         }
  623.                                  if(b4==1)
  624.                                     {
  625.                                                  for(sum=0;sum<Snake.Long-1;sum++)  //  向上  //小车身都是它前一段的小车身的位置
  626.                                {
  627.                                       Snake.X[sum]=Snake.X[sum+1];
  628.                                       Snake.Y[sum]=Snake.Y[sum+1];
  629.                                }

  630.                                Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]+1;
  631.                                Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]+0; //小车头向你要求的方向移动
  632.                                         }
  633.                                        
  634.                          if(!key1||!key2||!key3||!key4)
  635.                             {
  636.                           if(b1==1)
  637.                            {
  638.                                      b1=0;
  639.                                   b2=1;
  640.                                   b3=0;
  641.                                   b4=0;
  642.                            }
  643.                           else if(b2==1)
  644.                            {
  645.                                      b1=1;
  646.                                   b2=0;
  647.                                   b3=0;
  648.                                   b4=0;
  649.                            }
  650.                           else if(b3==1)
  651.                            {
  652.                                      b1=0;
  653.                                   b2=0;
  654.                                   b3=0;
  655.                                   b4=1;
  656.                            }
  657.                           else if(b4==1)
  658.                            {
  659.                                      b1=0;
  660.                                   b2=0;
  661.                                   b3=1;
  662.                                   b4=0;
  663.                            }   
  664.                             }
  665.                         }
  666.        

  667.                         if(a2==1)
  668.                         {
  669.                           if(b1==1)
  670.                                 {
  671.                                                  for(sum=0;sum<Snake.Long-1;sum++)  //  向下   //小车身都是它前一段的小车身的位置
  672.                            {
  673.                                      Snake.X[sum]=Snake.X[sum+1];
  674.                                      Snake.Y[sum]=Snake.Y[sum+1];
  675.                                }
  676.                
  677.                                Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]-1;
  678.                                Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]+0; //小车头向你要求的方向移动
  679.                                         }
  680.                                 if(b2==1)
  681.                                     {
  682.                                                  for(sum=0;sum<Snake.Long-1;sum++)  //  向上  //小车身都是它前一段的小车身的位置
  683.                                {
  684.                                       Snake.X[sum]=Snake.X[sum+1];
  685.                                       Snake.Y[sum]=Snake.Y[sum+1];
  686.                                }

  687.                                Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]+1;
  688.                                Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]+0; //小车头向你要求的方向移动
  689.                                         }
  690.                                  if(b3==1)
  691.                                     {                          
  692.                                                 for(sum=0;sum<Snake.Long-1;sum++) //向左   //小车身都是它前一段的小车身的位置
  693.                                {
  694.                                      Snake.X[sum]=Snake.X[sum+1];
  695.                                  Snake.Y[sum]=Snake.Y[sum+1];
  696.                                }
  697.                
  698.                                Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]+0;
  699.                                Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]-1; //小车头向你要求的方向移动
  700.                                         }
  701.                                   if(b4==1)
  702.                                     {
  703.                                                 for(sum=0;sum<Snake.Long-1;sum++) // 向右  //小车身都是它前一段的小车身的位置
  704.                                 {
  705.                                      Snake.X[sum]=Snake.X[sum+1];
  706.                                      Snake.Y[sum]=Snake.Y[sum+1];
  707.                             }
  708.                
  709.                                 Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]+0;
  710.                                 Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]+1; //小车头向你要求的方向移动
  711.                                         }                 
  712.                       if(!key1||!key2||!key3||!key4)
  713.                             {
  714.                                         if(b1==1)
  715.                            {
  716.                                      b1=0;
  717.                                   b2=0;
  718.                                   b3=0;
  719.                                   b4=1;
  720.                            }
  721.                           else if(b2==1)
  722.                            {
  723.                                      b1=0;
  724.                                   b2=0;
  725.                                   b3=1;
  726.                                   b4=0;
  727.                            }
  728.                           else if(b3==1)
  729.                            {
  730.                                      b1=1;
  731.                                   b2=0;
  732.                                   b3=0;
  733.                                   b4=0;
  734.                            }
  735.                           else if(b4==1)
  736.                            {
  737.                                      b1=0;
  738.                                   b2=1;
  739.                                   b3=0;
  740.                                   b4=0;
  741.                            }   
  742.                             }
  743.                         }

  744.                  
  745.                         if(a3==1)
  746.                         {
  747.                           if(b1==1)
  748.                                 {
  749.                                             for(sum=0;sum<Snake.Long-1;sum++)  //  向上 //小车身都是它前一段的小车身的位置
  750.                                {
  751.                                       Snake.X[sum]=Snake.X[sum+1];
  752.                                       Snake.Y[sum]=Snake.Y[sum+1];
  753.                                }

  754.                                Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]+1;
  755.                                Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]+0; //小车头向你要求的方向移动
  756.                                         }
  757.                                 if(b2==1)
  758.                                     {
  759.                                                         for(sum=0;sum<Snake.Long-1;sum++)  //  向下 //小车身都是它前一段的小车身的位置
  760.                            {
  761.                                      Snake.X[sum]=Snake.X[sum+1];
  762.                                      Snake.Y[sum]=Snake.Y[sum+1];
  763.                                }
  764.                
  765.                                Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]-1;
  766.                                Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]+0; //小车头向你要求的方向移动
  767.                                         }
  768.                                  if(b3==1)
  769.                                     {
  770.                                            for(sum=0;sum<Snake.Long-1;sum++) // 向右   //小车身都是它前一段的小车身的位置
  771.                                 {
  772.                                      Snake.X[sum]=Snake.X[sum+1];
  773.                                      Snake.Y[sum]=Snake.Y[sum+1];
  774.                             }
  775.                
  776.                                 Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]+0;
  777.                                 Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]+1; //小车头向你要求的方向移动
  778.                                         }
  779.                                  if(b4==1)
  780.                                     {
  781.                                            for(sum=0;sum<Snake.Long-1;sum++) //向左  //小车身都是它前一段的小车身的位置
  782.                                {
  783.                                      Snake.X[sum]=Snake.X[sum+1];
  784.                                  Snake.Y[sum]=Snake.Y[sum+1];
  785.                                }
  786.                
  787.                                Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]+0;
  788.                                Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]-1; //小车头向你要求的方向移动
  789.                                         }                 
  790.                          if(!key1||!key2||!key3||!key4)
  791.                             {
  792.                                         if(b1==1)
  793.                            {
  794.                                      b1=0;
  795.                                   b2=0;
  796.                                   b3=1;
  797.                                   b4=0;
  798.                            }
  799.                           else if(b2==1)
  800.                            {
  801.                                      b1=0;
  802.                                   b2=0;
  803.                                   b3=0;
  804.                                   b4=1;
  805.                            }
  806.                           else if(b3==1)
  807.                            {
  808.                                      b1=0;
  809.                                   b2=1;
  810.                                   b3=0;
  811.                                   b4=0;
  812.                            }
  813.                           else if(b4==1)
  814.                            {
  815.                                      b1=1;
  816.                                   b2=0;
  817.                                   b3=0;
  818.                                   b4=0;
  819.                            }   
  820.                             }
  821.                         }
  822.                

  823.                         if(a4==1)
  824.                         {
  825.                             if(b1==1)
  826.                                 {
  827.                                            for(sum=0;sum<Snake.Long-1;sum++) //向左  //小车身都是它前一段的小车身的位置
  828.                                {
  829.                                      Snake.X[sum]=Snake.X[sum+1];
  830.                                  Snake.Y[sum]=Snake.Y[sum+1];
  831.                                }
  832.                
  833.                                Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]+0;
  834.                                Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]-1; //小车头向你要求的方向移动
  835.                                         }
  836.                                 if(b2==1)
  837.                                     {
  838.                                             for(sum=0;sum<Snake.Long-1;sum++) // 向右  //小车身都是它前一段的小车身的位置
  839.                                 {
  840.                                      Snake.X[sum]=Snake.X[sum+1];
  841.                                      Snake.Y[sum]=Snake.Y[sum+1];
  842.                             }
  843.                
  844.                                 Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]+0;
  845.                                 Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]+1; //小车头向你要求的方向移动
  846.                                         }
  847.                                  if(b3==1)
  848.                                     {
  849.                                            for(sum=0;sum<Snake.Long-1;sum++)  //  向上 //小车身都是它前一段的小车身的位置
  850.                                {
  851.                                       Snake.X[sum]=Snake.X[sum+1];
  852.                                       Snake.Y[sum]=Snake.Y[sum+1];
  853.                                }

  854.                                Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]+1;
  855.                                Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]+0; //小车头向你要求的方向移动

  856.                                         }
  857.                                  if(b4==1)
  858.                                     {
  859.                                                 for(sum=0;sum<Snake.Long-1;sum++)  //  向下  //小车身都是它前一段的小车身的位置
  860.                            {
  861.                                      Snake.X[sum]=Snake.X[sum+1];
  862.                                      Snake.Y[sum]=Snake.Y[sum+1];
  863.                                }
  864.                
  865.                                Snake.X[Snake.Long-1]=Snake.X[Snake.Long-2]-1;
  866.                                Snake.Y[Snake.Long-1]=Snake.Y[Snake.Long-2]+0; //小车头向你要求的方向移动
  867.                                         }
  868.                          if(!key1||!key2||!key3||!key4)
  869.                             {
  870.                                         if(b1==1)
  871.                            {
  872.                                      b1=1;
  873.                                   b2=0;
  874.                                   b3=0;
  875.                                   b4=0;
  876.                            }
  877.                           else if(b2==1)
  878.                            {
  879.                                      b1=0;
  880.                                   b2=1;
  881.                                   b3=0;
  882.                                   b4=0;
  883.                            }
  884.                           else if(b3==1)
  885.                            {
  886.                                      b1=0;
  887.                                   b2=0;
  888.                                   b3=1;
  889.                                   b4=0;
  890.                            }
  891.                           else if(b4==1)
  892.                            {
  893.                                      b1=0;
  894.                                   b2=0;
  895.                                   b3=0;
  896.                                   b4=1;
  897.                            }   
  898.                             }
  899.                         }       
  900.        
  901. }       

  902. /*******************************************
  903. ********************************************
  904. *************小车部分***********************
  905. ********************************************
  906. ********************************************/

  907. /********外部中断定义*************/
  908. void ini()
  909. {
  910.    //EA=1;          //全局中断开
  911.    EX0=0;         //外部中断0开
  912.    IT0=1;         //边缘触发
  913.    //EX1=0;         //外部中断1开
  914.    //IT1=1;         //电平触发
  915. }


  916. /*****外部中断0函数*****/
  917. void ini_t0() interrupt 0
  918. {
  919.         bianma1--;
  920. }

  921. /********pwm中断调速定义*************/
  922. void pwm()
  923. {  
  924.    TMOD=0x01; /* 设定T0的工作模式为2 */  
  925.    TH0=(65536-100)/256; /* 装入定时器的初值 晶振20MHZ 每100us中断一次10次(即1MS)为1个PWM周期*/  
  926.    TL0=(65536-100)%256;  
  927.    EA=1; /* 开总中断 */  
  928.    ET0=1; /* 定时器0允许中断 */  
  929.    TR0=1; /* 启动定时器0 */  
  930.    PT0=1;//高优先级
  931. }


  932. /*****定时中断函数2*****/
  933. void timer0() interrupt 1 /* T0中断服务程序 */  
  934. {  
  935.        i++;
  936.        j++;
  937.        if(i<=m1) en1=1;
  938.           else en1=0;
  939.        if(j<=m2) en2=1;
  940.           else en2=0;
  941.            if(i==100)  {i=0;}
  942.        if(j==100)  {j=0;}
  943.        TH0=(65536-100)/256;
  944.        TL0=(65536-100)%256;
  945. }  

  946. //岔路口 转向记录
  947. void crossing(uchar save)
  948. {
  949.     if(save=='A'){strcat(road,"A");}
  950.     if(save=='B'){strcat(road,"B");}
  951.     if(save=='R'){strcat(road,"R");}
  952.     if(save=='L'){strcat(road,"L");}
  953.         if(save=='D'){strcat(road,"D");}
  954.     if(save=='0'){strcat(road,"\0");}
  955. }                

  956. //记忆路径播音
  957. void boyin(uchar save)
  958. {
  959.     if(save=='A'){stop();ISD1420p(3,1200);}
  960.     if(save=='B'){stop();ISD1420p(2,1200);}
  961.     if(save=='R'){stop();ISD1420p(1,1200);}
  962.     if(save=='L'){stop();ISD1420p(0,1200);}
  963.         if(save=='D'){stop();while(!markkey)  {logokey=0;DelayMs(3000) ;logokey=1;guo=0;}ISD1420p(2,1200);}
  964. }

  965. /*// 存入24c02
  966. void cunru24c02()
  967. {
  968.    uchar sum=0;
  969.    while(*p)
  970.     {
  971.            if(*p=='A')  cun24c02[sum]=0x01;
  972.        if(*p=='B')  cun24c02[sum]=0x02;
  973.        if(*p=='R')        cun24c02[sum]=0x03;
  974.        if(*p=='L')        cun24c02[sum]=0x04;
  975.            p++;
  976.            sum++;
  977.         }
  978.         cun24c02[sum]=0;
  979.         EA=0;//关掉中断       
  980.         ISendStr(0xae,80,cun24c02,15);            //写入24c02
  981.     DelayMs(10);                          //写入后必须延时等待24c02内部
  982.         EA=1;//开启中断
  983. }

  984. // 取出24c02
  985. void quchu24c02()
  986. {
  987.    uchar sum=0;
  988.    while(cun24c02[sum])
  989.     {
  990.            if(cun24c02[sum]==0x01)  strcat(p,"A");
  991.        if(cun24c02[sum]==0x02)  strcat(p,"B");
  992.        if(cun24c02[sum]==0x03)        strcat(p,"R");
  993.        if(cun24c02[sum]==0x04)        strcat(p,"L");
  994.            sum++;
  995.         }
  996.     strcat(p,"\0");
  997.         EA=0;//关掉中断       
  998.         IRcvStr(0xae,80,p,15);             //从24c02读出数据
  999.         EA=1;//开启中断
  1000. }        */


  1001. /******************************************************
  1002. *******************************************************
  1003. ************ISD1420p语音播报***************************
  1004. *******************************************************
  1005. *******************************************************/
  1006. sbit playe=P3^0;
  1007. uchar code temp[8]={0x00,0x10,0x20,0x30,0x40,0x50,0x70,0x90};
  1008. /* 0x00//左转                     延时400Ms
  1009.     0x10//右转                             延时400Ms
  1010.     0x20//掉头                       延时400Ms
  1011.         0x30//直走                       延时400Ms
  1012.     0x40//到达终点                    延时800Ms  
  1013.     0x50//最优路径计算完毕  延时1600Ms
  1014.     0x70//最优路径行驶             延时1600Ms
  1015.         0x90//智能迷宫小车            延时1600Ms         */
  1016. void ISD1420p(uchar t1,uint t2)
  1017. {                                                                                                                   
  1018.                 playe=1;
  1019.         write595(temp[t1]);
  1020.         playe=0;
  1021.         DelayMs(t2);
  1022.             DelayMs(t2);  
  1023.         playe=1;  
  1024.         /*        P1=0;
  1025.         playe=1;
  1026.         P1=temp[t1];
  1027.         playe=0;
  1028.         DelayMs(t2);
  1029.             DelayMs(t2);
  1030.         P1=0;
  1031.         playe=1;   */
  1032. }

  1033.    
  1034. /********************************************
  1035. *********************************************
  1036. *****************最优路线计算****************
  1037. *********************************************
  1038. *********************************************/
  1039. int pq(char s1[],char s2[],char ee)
  1040. {
  1041.     int opo=0;
  1042.     int w=0;
  1043.     int i;
  1044.     int k;
  1045.     int j;
  1046.     for(i=0;s1[i];i++)
  1047.     {
  1048.       j=i;
  1049.       for(k=0;s2[k];k++)
  1050.         if(s1[j]&&s1[j]==s2[k])j++;
  1051.            else break;
  1052.       if(!s2[k])
  1053.       {   
  1054.         opo=i;
  1055.          w++;
  1056.         if(ee==1)break;
  1057.       }
  1058. }
  1059. if(w==1)return opo;
  1060. else return -1;
  1061. }
  1062. char* str_text(){

  1063. int j,i,k,f=1,f2=1;//i用于计数  f内层标记 f2外层标记     
  1064. do{
  1065. for(i=0;i<9;i++,f=1)
  1066. {
  1067.   do
  1068.   {
  1069.    j=pq(road,aa[i],1);  //选出匹配字符串下标
  1070.        if(j==-1)break;
  1071.     else  
  1072.     {   road[j]=a[i][0];
  1073.      while(road[j+3]){road[j+1]=road[j+3];j++;}
  1074.      road[j+1]='\0';
  1075.     }  
  1076.   }while(1);//判断本次匹配替换是否结束,如果否 继续匹配并替换

  1077. }  //for循环结束

  1078. //*******校验
  1079. for(k=0;k<9;k++)
  1080. {
  1081.   j=pq(road,aa[k],1);
  1082.   if(j!=-1)
  1083.   {
  1084.    f2=1;break;  //判断是否仍然有匹配项目,如果有重新执行内层do~while语句
  1085.         }else{f2=0;}
  1086. }//校验for结束

  1087. }while(f2==1); //外层do while 用于校验

  1088. return road;  //road首地址
  1089.      //printf("%s\n",turn2);scanf("%s",c);
  1090. }

  1091. /******************************************************
  1092. *******************************************************
  1093. *************小车路径处理******************************
  1094. *******************************************************
  1095. *******************************************************/

  1096. /******************路口误差排除函数********************/
  1097. uchar you=0;


  1098. ………完整代码请下载附件………

复制代码



评分

参与人数 1黑币 +3 收起 理由
孤独者! + 3 赞一个!

查看全部评分

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

使用道具 举报

沙发
ID:79544 发表于 2017-11-4 13:59 | 只看该作者
谢谢楼主的分享!学习啦。电路图是用什么软件打开?
回复

使用道具 举报

板凳
ID:250660 发表于 2018-4-15 15:26 | 只看该作者
有最短路径吗
回复

使用道具 举报

地板
ID:333880 发表于 2018-5-20 18:27 | 只看该作者
一千多行代码,大哥,太六了
回复

使用道具 举报

5#
ID:104838 发表于 2018-5-20 18:58 | 只看该作者

一千多行代码,大哥,太六了
回复

使用道具 举报

6#
ID:340055 发表于 2018-5-30 18:51 | 只看该作者
谢谢分享
回复

使用道具 举报

7#
ID:437246 发表于 2018-12-1 17:27 | 只看该作者
谢谢楼主的分享!学习啦。谢谢!
回复

使用道具 举报

8#
ID:433074 发表于 2019-6-25 21:02 | 只看该作者
腾飞的龙 发表于 2017-11-4 13:59
谢谢楼主的分享!学习啦。电路图是用什么软件打开?

你是水军吧
回复

使用道具 举报

9#
ID:554617 发表于 2019-11-4 18:43 | 只看该作者
ad打开不能编辑
回复

使用道具 举报

10#
ID:640274 发表于 2019-11-18 22:59 | 只看该作者
太厉害了
回复

使用道具 举报

11#
ID:659466 发表于 2019-12-9 11:46 | 只看该作者
请问同样 发表于 2018-5-20 18:27
一千多行代码,大哥,太六了

他这个有没有遍历和迷宫的算法
回复

使用道具 举报

12#
ID:647880 发表于 2019-12-9 15:34 | 只看该作者
这也太专业了些。。。。。。
回复

使用道具 举报

13#
ID:658799 发表于 2020-1-8 09:56 | 只看该作者
一千多行代码,大哥,太六了
回复

使用道具 举报

14#
ID:684881 发表于 2020-2-7 21:45 | 只看该作者

谢谢楼主的分享!学习啦
回复

使用道具 举报

15#
ID:228376 发表于 2020-2-17 02:18 来自手机 | 只看该作者
谢谢分享
回复

使用道具 举报

16#
ID:853927 发表于 2020-12-3 18:08 | 只看该作者
除了厉害还是厉害
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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