找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2641|回复: 2
收起左侧

基于51单片机的智能小车设计 蓝牙+避障源码

[复制链接]
ID:301051 发表于 2018-4-2 19:14 | 显示全部楼层 |阅读模式
基于51单片机的智能小车设计 蓝牙+避障 源码。

单片机源程序如下:
  1. //************************************************************************
  2. // 名称:基于51单片机的智能小车程序
  3. // 功能:1、蓝牙模式 2、避障模式
  4. // 作者:YY
  5. // 说明:上电后手机蓝牙打开后搜索HC-06 配对密码为1234
  6. //       然后打开配套的Android软件 点击右上角的连接
  7. //                         点击弹出的对话框 会提示 “ 连接成功 ” 就可以
  8. //       通过手机控制小车了 “ 1 ”模式切换 “ 2 ”增加车速档位“ 3 ”减小车速档位
  9. //************************************************************************

  10. #include <REGX52.H> //包含51单片机相关的头文件

  11. typedef unsigned int uint;
  12. typedef unsigned char uchar;
  13. /************************************************************************/
  14. /*                    PWM调制电机转速定义                                  */
  15. #define Left_moto_pwm     P1_6           //接驱动模块ENA        使能端,输入PWM信号调节速度
  16. #define Right_moto_pwm    P1_7           //接驱动模块ENB
  17. unsigned char pwm_val_left  =0;//变量定义
  18. unsigned char push_val_left =0;// 左电机占空比N/10
  19. unsigned char pwm_val_right =0;
  20. unsigned char push_val_right=0;// 右电机占空比N/10
  21. bit Right_moto_stop=1;
  22. bit Left_moto_stop =1;
  23. unsigned  int  time=0;
  24. /************************************************************************/
  25. /*                                小车接口定义                          */
  26. #define Left_moto_go      {P1_0=0,P1_1=1;} //P1_0 P1_1 接IN1  IN2    当 P1_0=0,P1_1=1; 时左电机前进
  27. #define Left_moto_back    {P1_0=1,P1_1=0;} //P1_0 P1_1 接IN1  IN2    当 P1_0=1,P1_1=0; 时左电机后退
  28. #define Left_moto_t                    {P1_0=1,P1_1=1;} //P1_0 P3_5 接IN1  IN2    当 P1_0=1,P3_5=1; 时左电机停止
  29. #define Right_moto_go     {P1_2=0,P1_3=1;} //P1_2 P1_3 接IN3  IN4           当 P1_2=0,P1_3=1; 时右电机前转
  30. #define Right_moto_back   {P1_2=1,P1_3=0;} //P1_2 P1_3 接IN3  IN4           当 P1_2=1,P1_3=0; 时右电机后退
  31. #define Right_moto_t      {P1_2=1,P1_3=1;} //P1_2 P1_3 接IN3  IN4           当 P1_2=1,P1_3=1; 时右电机停止
  32. #define ShowPort P0


  33. sbit LeftLed=P2^0;                        //定义左侧避障传感器接口 所用的传感器为 未感知障碍时为高电平 遇到障碍变为低电平
  34. sbit FontLed=P2^1;                                                                                                //定义前方避障传感器接口
  35. sbit RightLed=P2^2;                       //定义右侧避障传感器接口

  36. sbit Speker=P2^3;                                                                                                        //定义喇叭接口

  37. sbit WEI1=P2^7;                                                                                                                //定义显示接口
  38. sbit WEI2=P2^6;
  39. sbit WEI3=P2^5;
  40. sbit WEI4=P2^4;

  41. sbit LeftIR=P3^1;                         //定义前方左侧红外探头端口
  42. sbit FontIR=P3^2;                         //定义前方正前方红外探头端口
  43. sbit RightIR=P3^3;                        //定义前方右侧红外探头端口

  44. unsigned char temp = 1;
  45. unsigned char code  LedShowModeData[]={0xC0,0xF9,0xA4};//0,1,2共阳数码管
  46. unsigned char code  LedShowPwmData[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//0,1,2,3,4,5,6,7,8,9共阳数码管
  47. bit run_flag;
  48.                                                        
  49. /************************************************************************/
  50. /*                 蓝牙定义                               */
  51. #define left     'C'
  52. #define right    'D'
  53. #define up       'A'
  54. #define down     'B'
  55. #define stop     'F'
  56. #define switchmode'1'
  57. #define CarSpeedPlus '2'
  58. #define CarSpeedMinus '3'

  59. char code str[] =  "收到指令,向前!\n";
  60. char code str1[] = "收到指令,向后!\n";
  61. char code str2[] = "收到指令,向左!\n";
  62. char code str3[] = "收到指令,向右!\n";
  63. char code str4[] = "收到指令,停止!\n";

  64. bit  flag_REC=0;
  65. bit  flag    =0;  


  66. unsigned char  i=0;
  67. unsigned char  dat=0;
  68. unsigned char  buff[5]=0; //接收缓冲字节       
  69. unsigned char temppwm=8;

  70. /************************************************************************/
  71. /*                   延时程序                                */
  72. void delay_nus(unsigned int i)  //延时:i>=12 ,i的最小延时单12 us
  73. {
  74.   i=i/10;
  75.   while(--i);
  76. }   
  77. void delay_nms(unsigned int n)  //延时n ms
  78. {
  79.   n=n+1;
  80.   while(--n)  
  81.   delay_nus(900);         //延时 1ms,同时进行补偿
  82.   
  83. }

  84. /************************************************************************/
  85. /*                                显示部分                             */
  86. void Display()
  87. {
  88.         if(temppwm<10)
  89.         {
  90.                 ShowPort = LedShowModeData[temp];
  91.                 WEI1=0;
  92.                 WEI2=1;
  93.                 WEI3=1;
  94.                 WEI4=1;
  95.                 delay_nms(2);
  96.                 ShowPort = LedShowPwmData[temppwm];
  97.                 WEI1=1;
  98.                 WEI2=1;
  99.                 WEI3=1;
  100.                 WEI4=0;
  101.                 delay_nms(2);
  102.         }
  103.         else
  104.         {
  105.                 ShowPort = LedShowModeData[temp];
  106.                 WEI1=0;
  107.                 WEI2=1;
  108.                 WEI3=1;
  109.                 WEI4=1;
  110.                 delay_nms(1);
  111.                 ShowPort = LedShowPwmData[1];
  112.                 WEI1=1;
  113.                 WEI2=1;
  114.                 WEI3=0;
  115.                 WEI4=1;
  116.                 delay_nms(1);
  117.                 ShowPort = LedShowPwmData[0];
  118.                 WEI1=1;
  119.                 WEI2=1;
  120.                 WEI3=1;
  121.                 WEI4=0;
  122.                 delay_nms(1);
  123.         }
  124. }
  125. /************************************************************************/
  126. /*                   控制方向程序                                 */
  127. void tingzhi()
  128. {
  129.          push_val_left  =2;  //PWM 调节参数1-10   1为最慢,10是最快  改这个值可以改变其速度
  130.          push_val_right =2;         //PWM 调节参数1-10   1为最慢,10是最快         改这个值可以改变其速度
  131.          Left_moto_t ;                 //左电机停止
  132.          Right_moto_t ;         //右电机停止
  133. }

  134. void qianjin()
  135. {
  136.          push_val_left  =4;  //PWM 调节参数1-10   1为最慢,10是最快  改这个值可以改变其速度
  137.          push_val_right =4;         //PWM 调节参数1-10   1为最慢,10是最快         改这个值可以改变其速度
  138.          Left_moto_go ;                 //左电机前进
  139.          Right_moto_go ;         //右电机前进
  140. }

  141. void houtui()
  142. {
  143.          push_val_left  =4;  //PWM 调节参数1-10   1为最慢,10是最快  改这个值可以改变其速度
  144.          push_val_right =4;         //PWM 调节参数1-10   1为最慢,10是最快         改这个值可以改变其速度
  145.          Left_moto_back ;                 //左电机后退
  146.          Right_moto_back ;         //右电机后退
  147. }

  148. void zuozhuan()
  149. {
  150.          push_val_left  =4;  //PWM 调节参数1-10   1为最慢,10是最快  改这个值可以改变其速度
  151.          push_val_right =1;         //PWM 调节参数1-10   1为最慢,10是最快         改这个值可以改变其速度
  152.          Left_moto_back ;                 //左电机后退
  153.          Right_moto_go ;         //右电机前进
  154. }
  155. void weizuozhuan()
  156. {
  157.          push_val_left  =2;  //PWM 调节参数1-10   1为最慢,10是最快  改这个值可以改变其速度
  158.          push_val_right =1;         //PWM 调节参数1-10   1为最慢,10是最快         改这个值可以改变其速度
  159.          Left_moto_back ;                 
  160.          Right_moto_go ;       
  161. }
  162. void weiyouzhuan()
  163. {
  164.          push_val_left  =1;  //PWM 调节参数1-10   1为最慢,10是最快  改这个值可以改变其速度
  165.          push_val_right =2;         //PWM 调节参数1-10   1为最慢,10是最快         改这个值可以改变其速度
  166.          Left_moto_go ;               
  167.          Right_moto_back ;       
  168. }
  169. void youzhuan()
  170. {
  171.          push_val_left  =1;  //PWM 调节参数1-10   1为最慢,10是最快  改这个值可以改变其速度
  172.          push_val_right =4;         //PWM 调节参数1-10   1为最慢,10是最快         改这个值可以改变其速度
  173.          Left_moto_go ;                 //左电机前进
  174.          Right_moto_back ;         //右电机后退
  175. }

  176. /************************************************************************/
  177. /*                    PWM调制电机转速                                   */
  178. void Timer0_Init()
  179. {
  180.         TMOD=0X01;
  181.         TH0= 0XF8;                  //1ms定时
  182.         TL0= 0X30;
  183.         TR0= 1;
  184.         ET0= 1;
  185.         EA = 1;
  186. }

  187. /************************************************************************/
  188. /*                    左电机调速                                        */
  189. /*调节push_val_left的值改变电机转速,占空比            */
  190. void pwm_out_left_moto(void)
  191. {  
  192.    if(Left_moto_stop)
  193.     {
  194.     if(pwm_val_left <= push_val_left)
  195.         Left_moto_pwm=1;
  196.     else
  197.             Left_moto_pwm=0;
  198.         if(pwm_val_left>=10)
  199.             pwm_val_left=0;
  200.     }
  201.    else  Left_moto_pwm=0;
  202. }

  203. /******************************************************************/
  204. /*                    右电机调速                                  */  
  205. void pwm_out_right_moto(void)
  206. {
  207.   if(Right_moto_stop)
  208.     {
  209.     if(pwm_val_right<=push_val_right)
  210.         Right_moto_pwm=1;
  211.         else
  212.         Right_moto_pwm=0;
  213.         if(pwm_val_right>=10)
  214.             pwm_val_right=0;
  215.     }
  216.     else    Right_moto_pwm=0;
  217. }

  218. /***************************************************/
  219. ///*TIMER0中断服务子函数产生PWM信号*/
  220.         void timer0()interrupt 1   using 2
  221. {
  222.    TH0=0XF8;          //1Ms定时
  223.          TL0=0X30;
  224.          time++;
  225.          pwm_val_left++;
  226.          pwm_val_right++;
  227.          pwm_out_left_moto();
  228.          pwm_out_right_moto();
  229.          
  230. }       

  231. /************************************************************************/
  232. /*                    寻迹程序                                          */
  233. void xunji()
  234. {
  235.          Start:


  236.    if(LeftIR == 0 && FontIR == 1 && RightIR == 0)   
  237.    {
  238.       qianjin();                     
  239.       delay_nms (100);
  240.           goto NextRun;
  241.    }
  242.    
  243.           if(LeftIR == 1 && FontIR == 1 && RightIR == 0)
  244.    {
  245.       weiyouzhuan();                      //微右调
  246.       delay_nms (100);
  247.           goto NextRun;
  248.    }
  249.          
  250.    if(LeftIR == 1 && FontIR == 0 && RightIR == 0)
  251.    {
  252.       youzhuan();                      //右急转弯
  253.       delay_nms (100);
  254.           goto NextRun;
  255.    }
  256.          if(LeftIR == 0 && FontIR == 1 && RightIR == 1)
  257.    {
  258.       weizuozhuan();                      //微左调
  259.       delay_nms (100);
  260.           goto NextRun;
  261.    }
  262.    if(LeftIR == 0 && FontIR == 0 && RightIR == 1)
  263.    {
  264.       zuozhuan();                      //左急转弯
  265.       delay_nms (100);
  266.           goto NextRun;
  267.    }


  268.    goto Start;
  269.    NextRun:
  270.    tingzhi();
  271. }

  272. /************************************************************************/
  273. /*                    避障程序                                          */
  274. void bizhang()
  275. {
  276.          static uchar i;
  277.          run_flag=1;
  278.          qianjin();
  279.          if(LeftLed == 0)                          //如果前面避障传感器检测到障碍物
  280.    {
  281.                  tingzhi();                       //停止                                  
  282.                  for(i=0;i<50;i++)                                                                         //停止300MS   防止电机反相电压冲击  导致系统复位
  283.                  {
  284.                          delay_nms(3);
  285.                          Display();
  286.                  }
  287.           houtui();                                           //后退  
  288.          // delay_nms (500);                                           //后退1500MS
  289.                         for(i=0;i<80;i++)
  290.                  {
  291.                          delay_nms(5);
  292.                          Display();
  293.                  }
  294.           zuozhuan();                                           //
  295.          // delay_nms (500);
  296.                         for(i=0;i<80;i++)
  297.                  {
  298.                          delay_nms(5);
  299.                          Display();
  300.                  }
  301.    }
  302.    
  303.    else if(FontLed == 0)                          //如果前面避障传感器检测到障碍物
  304.    {
  305.                 tingzhi();                       //停止
  306.         //        delay_nms (300);                                           //停止300MS   防止电机反相电压冲击  导致系统复位
  307.                 for(i=0;i<50;i++)
  308.                  {
  309.                          delay_nms(3);
  310.                          Display();
  311.                  }
  312.           houtui();                                           //后退  
  313.         //  delay_nms (500);                                           //后退1500MS  
  314.                 for(i=0;i<80;i++)
  315.                  {
  316.                          delay_nms(5);
  317.                          Display();
  318.                  }
  319.           zuozhuan();                                           //
  320.         //  delay_nms (500);       
  321.                 for(i=0;i<80;i++)
  322.                  {
  323.                          delay_nms(5);
  324.                          Display();
  325.                  }
  326.    }
  327.          else if(RightLed == 0)                          //如果前面避障传感器检测到障碍物
  328.    {
  329.                 tingzhi();                       //停止
  330.         //        delay_nms (300);                                           //停止300MS   防止电机反相电压冲击  导致系统复位
  331.                 for(i=0;i<50;i++)
  332.                  {
  333.                          delay_nms(3);
  334.                          Display();
  335.                  }
  336.           houtui();                                           //后退  
  337. //          delay_nms (500);                                           //后退1500MS  
  338.                  for(i=0;i<80;i++)
  339.                  {
  340.                          delay_nms(5);
  341.                          Display();
  342.                  }
  343.           youzhuan();                                           //
  344. //          delay_nms (500);       
  345.                  for(i=0;i<80;i++)
  346.                  {
  347.                          delay_nms(5);
  348.                          Display();
  349.                  }
  350.    }
  351. }

  352. /************************************************************************/
  353. /*                                                            蓝牙部分                                */
  354. /************************************************************************/
  355. //字符串发送函数
  356. void send_str( )
  357.                                                          // 传送字串
  358. {
  359.         unsigned char i = 0;
  360.         while(str[i] != '\0')
  361. {
  362.         SBUF = str[i];
  363.         while(!TI);                                // 等特数据传送
  364.         TI = 0;                                        // 清除数据传送标志
  365.         i++;                                        // 下一个字符
  366. }       
  367. }

  368. void send_str1( )
  369.                                                          // 传送字串
  370. {
  371.         unsigned char i = 0;
  372.         while(str1[i] != '\0')
  373. {
  374.         SBUF = str1[i];
  375.         while(!TI);                                // 等特数据传送
  376.         TI = 0;                                        // 清除数据传送标志
  377.         i++;                                        // 下一个字符
  378. }       
  379. }       

  380. void send_str2( )
  381.                                                          // 传送字串
  382. {
  383.         unsigned char i = 0;
  384.         while(str2[i] != '\0')
  385. {
  386.         SBUF = str2[i];
  387.         while(!TI);                                // 等特数据传送
  388.         TI = 0;                                        // 清除数据传送标志
  389.         i++;                                        // 下一个字符
  390. }       
  391. }       
  392.                
  393. void send_str3()
  394.                                                          // 传送字串
  395. {
  396.         unsigned char i = 0;
  397.         while(str3[i] != '\0')
  398. {
  399.         SBUF = str3[i];
  400.         while(!TI);                                // 等特数据传送
  401.         TI = 0;                                        // 清除数据传送标志
  402.         i++;                                        // 下一个字符
  403. }       
  404. }       

  405. void send_str4()
  406.                                                          // 传送字串
  407. {
  408.         unsigned char i = 0;
  409.         while(str4[i] != '\0')
  410. {
  411.         SBUF = str4[i];
  412.         while(!TI);                                // 等特数据传送
  413.         TI = 0;                                        // 清除数据传送标志
  414.         i++;                                        // 下一个字符
  415. }       
  416. }       
  417. void Timer1_Init()
  418. {
  419.         TMOD=0x20;  
  420.         TH1=0xFd;                     //11.0592M晶振,9600波特率
  421.         TL1=0xFd;
  422.         SCON=0x50;  
  423.         PCON=0x00;
  424.         TR1=1;
  425.         ES=1;   
  426.         EA=1;
  427. }

  428. void sint() interrupt 4          //中断接收3个字节
  429. {

  430.     if(RI)                         //是否接收中断
  431.     {
  432.        RI=0;
  433.        dat=SBUF;
  434.        if(dat=='O'&&(i==0)) //接收数据第一帧
  435.          {
  436.             buff[i]=dat;
  437.             flag=1;        //开始接收数据
  438.          }
  439.        else
  440.       if(flag==1)
  441.      {
  442.       i++;
  443.       buff[i]=dat;
  444.       if(i>=2)
  445.       {i=0;flag=0;flag_REC=1 ;}  // 停止接收
  446.      }
  447.          }
  448. }

  449. void lanya()
  450. {
  451.        
  452.         if(flag_REC==1)                                    //
  453. {
  454.         flag_REC=0;
  455.         if(buff[0]=='O'&&buff[1]=='N')        //第一个字节为O,第二个字节为N,第三个字节为控制码
  456.         switch(buff[2])
  457.          {
  458.           case up :                                                    // 前进
  459.                 send_str();
  460.                 push_val_left  =temppwm;  //PWM 调节参数1-10   1为最慢,10是最快  改这个值可以改变其速度
  461.                 push_val_right =temppwm;         //PWM 调节参数1-10   1为最慢,10是最快         改这个值可以改变其速度
  462.           Left_moto_go ;                 //左电机前进
  463.     Right_moto_go ;         //右电机前进
  464.                 break;
  465.                
  466.                 case down:                                                // 后退
  467.                 send_str1();
  468.                 push_val_left  =temppwm;  //PWM 调节参数1-10   1为最慢,10是最快  改这个值可以改变其速度
  469.                 push_val_right =temppwm;         //PWM 调节参数1-10   1为最慢,10是最快         改这个值可以改变其速度
  470.           Left_moto_back ;                 
  471.     Right_moto_back ;         
  472.                 break;
  473.                
  474.                 case left:                                                // 左转
  475.                 send_str3();
  476.                 push_val_left  =temppwm;  //PWM 调节参数1-10   1为最慢,10是最快  改这个值可以改变其速度
  477.                 push_val_right =temppwm;         //PWM 调节参数1-10   1为最慢,10是最快         改这个值可以改变其速度
  478.           Left_moto_back ;               
  479.     Right_moto_go ;         

  480.                 break;
  481.                
  482.                 case right:                                                // 右转
  483.                 send_str2();
  484.                 push_val_left  =temppwm;  //PWM 调节参数1-10   1为最慢,10是最快  改这个值可以改变其速度
  485.                 push_val_right =temppwm;         //PWM 调节参数1-10   1为最慢,10是最快         改这个值可以改变其速度
  486.           Left_moto_go ;                 
  487.     Right_moto_back ;       

  488.                 break;
  489.                
  490.                 case stop:                                                // 停止
  491.                 send_str4();
  492.                 push_val_left  =2;  //PWM 调节参数1-10   1为最慢,10是最快  改这个值可以改变其速度
  493.           push_val_right =2;         //PWM 调节参数1-10   1为最慢,10是最快         改这个值可以改变其速度
  494.           Left_moto_t ;               
  495.           Right_moto_t ;         
  496.                 break;
  497.                
  498.                 case switchmode :                                                    // 切换工作模式
  499.                 temp++;
  500.                 Speker=~Speker;
  501.                 delay_nms(10);
  502.                 Speker=~Speker;
  503.                 break;
  504. ……………………

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

所有资料51hei提供下载:
基于51单片机的智能小车设计 蓝牙 避障 YY编写 2017.11.13.zip (49.29 KB, 下载次数: 55)
回复

使用道具 举报

ID:476031 发表于 2019-5-1 21:28 | 显示全部楼层
   if(dat=='O'&&(i==0)) //接收数据第一帧
为啥是O呢?
回复

使用道具 举报

ID:632112 发表于 2020-5-20 17:09 | 显示全部楼层
好资料,51黑有你更精彩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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