找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4535|回复: 7
收起左侧

基于51单片机的智能小车设计 蓝牙+避障 YY编写

[复制链接]
ID:259629 发表于 2017-12-10 17:54 | 显示全部楼层 |阅读模式
基于51单片机的智能小车设计 蓝牙+避障 YY编

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

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

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


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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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


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


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

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

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

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

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

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

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

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

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

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

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

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

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

使用道具 举报

ID:243549 发表于 2017-12-11 13:53 来自手机 | 显示全部楼层
你这个避障是超声波的吗?还是红外线的?
回复

使用道具 举报

ID:259629 发表于 2017-12-17 15:16 | 显示全部楼层
不忘初心666 发表于 2017-12-11 13:53
你这个避障是超声波的吗?还是红外线的?

超声波的
回复

使用道具 举报

ID:259619 发表于 2017-12-18 14:42 来自手机 | 显示全部楼层
楼主,定时器中断与串口中断不会起冲突了
回复

使用道具 举报

ID:259619 发表于 2017-12-18 15:39 来自手机 | 显示全部楼层
fhevan 发表于 2017-12-18 14:42
楼主,定时器中断与串口中断不会起冲突了

打错了,是会不会起冲突
回复

使用道具 举报

ID:274836 发表于 2018-1-17 21:38 | 显示全部楼层
大哥我这个动不了能帮我看看吗?

APP整合综合程序,步进小车.zip

90.38 KB, 下载次数: 4, 下载积分: 黑币 -5

单独功能的步进小车接线图.pdf

52.59 KB, 下载次数: 4, 下载积分: 黑币 -5

回复

使用道具 举报

ID:274836 发表于 2018-1-17 21:40 | 显示全部楼层
直流电机还是步进电机?
回复

使用道具 举报

ID:274836 发表于 2018-1-17 21:41 | 显示全部楼层
大哥我的动不了你帮我看看

单独功能的步进小车接线图.pdf

52.59 KB, 下载次数: 4, 下载积分: 黑币 -5

APP整合综合程序,步进小车.zip

90.38 KB, 下载次数: 4, 下载积分: 黑币 -5

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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