找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机超声波避障智能小车(附带原理图+PCB文件)

  [复制链接]
跳转到指定楼层
楼主
功能:蓝牙遥控超声波避障oled屏幕显示
Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)


单片机源程序如下:
  1. #include<AT89x52.H>
  2. #include <intrins.h>   
  3. #include "oled.h"

  4. #define Left_moto_go      {P1_2=1,P1_3=0;}    //左边两个电机向前走
  5. #define Left_moto_back    {P1_2=0,P1_3=1;}         //左边两个电机向后转
  6. #define Left_moto_Stop    {P1_2=0,P1_3=0;}    //左边两个电机停转                     
  7. #define Right_moto_go     {P1_6=1,P1_7=0;}        //右边两个电机向前走
  8. #define Right_moto_back   {P1_6=0,P1_7=1;}        //右边两个电机向前走
  9. #define Right_moto_Stop   {P1_6=0,P1_7=0;}        //右边两个电机停转   

  10. #define  ECHO  P2_0                                   //超声波接口定义
  11. #define  TRIG  P2_1                                   //超声波接口定义
  12. #define Sevro_moto_pwm    P2_2         //接舵机信号端输入PWM信号调节速度
  13. #define BEEP                P2_3
  14. #define left     'C'
  15. #define right    'D'
  16. #define up       'A'
  17. #define down     'B'
  18. #define stop     'F'
  19. #define Car1     '2'           //手机软件1号键
  20. #define Beep     '5'           //手机软件5号键

  21.         unsigned char disbuff[4]          ={ 0,0,0,0,};
  22.            unsigned char pwm_val_left  = 0;//变量定义
  23.         unsigned char push_val_left =15;//舵机归中,产生约,1.5MS 信号
  24.                 unsigned int  time=0;                    //时间变量
  25.   unsigned int  timer=0;                        //延时基准变量
  26.                 unsigned long S=0;                                //计算出超声波距离值
  27.   unsigned long S1=0;
  28.                 unsigned long S2=0;
  29.         unsigned long S3=0;
  30.                 unsigned long S4=0;

  31.         bit  flag_REC=0;                                 //串行接收标去位
  32.         bit  flag    =0;  
  33.         bit  flag_xj =0;
  34.         bit  flag_bj =0;
  35.         
  36.         unsigned char  i=0;
  37.         unsigned char  dat=0;
  38.   unsigned char  buff[5]=0;       //接收缓冲字节

  39. /************************************************************************/        
  40. //延时函数        
  41.    void delay(unsigned int k)
  42. {   
  43.      unsigned int x,y;
  44.          for(x=0;x<k;x++)
  45.            for(y=0;y<2000;y++);
  46. }
  47. /************************************************************************/
  48. //前速前进
  49.      void  run(void)
  50. {
  51.          Left_moto_go ;   //左电机往前走
  52.          Right_moto_go ;  //右电机往前走
  53. }

  54. //前速后退
  55.      void  backrun(void)
  56. {

  57.          Left_moto_back ;   //左电机往前走
  58.          Right_moto_back ;  //右电机往前走
  59. }

  60. //左转
  61.      void  leftrun(void)
  62. {

  63.          Left_moto_back ;   //左电机往前走
  64.          Right_moto_go ;    //右电机往前走
  65. }

  66. //右转
  67.      void  rightrun(void)
  68. {

  69.          Left_moto_go ;   //左电机往前走
  70.          Right_moto_back ;  //右电机往前走
  71. }
  72. //STOP
  73.      void  stoprun(void)
  74. {
  75.          Left_moto_Stop ;   //左电机往前走
  76.          Right_moto_Stop ;  //右电机往前走
  77. }
  78.                 void   whistle(void)
  79. {
  80.                 BEEP=0;
  81. }
  82. /************************************************************************/
  83.      void  StartModule()                       //启动测距信号
  84.    {
  85.           TRIG=1;                                       
  86.           _nop_();
  87.           _nop_();
  88.           _nop_();
  89.           _nop_();
  90.           _nop_();
  91.           _nop_();
  92.           _nop_();
  93.           _nop_();
  94.           _nop_();
  95.           _nop_();
  96.           _nop_();
  97.           _nop_();
  98.           _nop_();
  99.           _nop_();
  100.           _nop_();
  101.           _nop_();
  102.           _nop_();
  103.           _nop_();
  104.           _nop_();
  105.           _nop_();
  106.           _nop_();
  107.           TRIG=0;
  108.    }
  109. /***************************************************/
  110.           void Conut(void)                   //计算距离
  111.         {
  112.           while(!ECHO);                       //当RX为零时等待
  113.           TR0=1;                               //开启计数
  114.           while(ECHO);                           //当RX为1计数并等待
  115.           TR0=0;                                   //关闭计数
  116.           time=TH0*256+TL0;                   //读取脉宽长度
  117.           TH0=0;
  118.           TL0=0;
  119.           S=(time*1.7)/100;        //算出来是CM
  120.                 OLED_ShowNum(103,4,S,3,16);//距离
  121.         }
  122.             
  123. /************************************************************************/

  124. void  COMM( void )                       
  125.   {
  126.                   push_val_left=10;          //舵机向左转90度
  127.                   timer=0;
  128.                   while(timer<=4000); //延时400MS让舵机转到其位置
  129.                   StartModule();          //启动超声波测距
  130.           Conut();                           //计算距离
  131.                   S2=S;  
  132.                         OLED_ShowNum(103,2,S2,3,16);//左侧距离
  133.                   push_val_left=20;          //舵机向右转90度
  134.                   timer=0;
  135.                   while(timer<=4000); //延时400MS让舵机转到其位置
  136.                   StartModule();          //启动超声波测距
  137.           Conut();                          //计算距离
  138.                   S4=S;         
  139.                         OLED_ShowNum(103,6,S4,3,16);//右侧距离

  140.                   push_val_left=15;          //舵机归中
  141.                   timer=0;
  142.                   while(timer<=4000); //延时400MS让舵机转到其位置
  143.                   StartModule();          //启动超声波测距
  144.           Conut();                          //计算距离
  145.                   S1=S;         

  146.           if((S2<20)||(S4<20)) //只要左右各有距离小于,20CM小车后退
  147.                   {
  148.                   backrun();                   //后退
  149.                   timer=0;
  150.                   while(timer<=4000);
  151.                   }
  152.                   
  153.                   if(S2>S4)                 
  154.                      {
  155.                                 rightrun();          //车的左边比车的右边距离小        右转        
  156.                         timer=0;
  157.                         while(timer<=400);
  158.                      }                                      
  159.                        else
  160.                      {
  161.                        leftrun();                //车的左边比车的右边距离大        左转
  162.                        timer=0;
  163.                        while(timer<=400);
  164.                      }
  165.                                              
  166. }
  167. /************************************************************************/
  168. /*                    PWM调制舵机信号                                 */
  169. /************************************************************************/
  170. /*                    左电机调速                                        */
  171. /*调节push_val_left的值改变电机转速,占空比            */
  172.                 void pwm_Servomoto(void)
  173. {  

  174.     if(pwm_val_left<=push_val_left)
  175.                Sevro_moto_pwm=1;
  176.         else
  177.                Sevro_moto_pwm=0;
  178.         if(pwm_val_left>=200)
  179.         pwm_val_left=0;

  180. }
  181. /***************************************************/
  182. ///*TIMER1中断服务子函数产生PWM信号*/
  183.          void time1()interrupt 3   using 2
  184. {        
  185.      TH1=(65536-100)/256;          //100US定时
  186.          TL1=(65536-100)%256;
  187.          timer++;                                  //定时器100US为准。在这个基础上延时
  188.          pwm_val_left++;
  189.          pwm_Servomoto();
  190. }

  191. /************************************************************************/
  192. void sint() interrupt 4          //中断接收3个字节
  193. {

  194.     if(RI)                         //是否接收中断
  195.     {
  196.        RI=0;
  197.        dat=SBUF;
  198.        if(dat=='O'&&(i==0)) //接收数据第一帧
  199.          {
  200.             buff[i]=dat;
  201.             flag=1;        //开始接收数据
  202.          }
  203.        else
  204.       if(flag==1)
  205.      {
  206.       i++;
  207.       buff[i]=dat;
  208.       if(i>=2)
  209.       {i=0;flag=0;flag_REC=1 ;}  // 停止接收
  210.      }
  211.          }
  212. }
  213. /*********************************************************************/                 
  214. /*--主函数--*/
  215.         void main(void)
  216. {
  217.         TMOD=0x11;  
  218.   TH1=(65536-100)/256;          //100US定时
  219.         TL1=(65536-100)%256;
  220.         TH0=0;
  221.         TL0=0;

  222.   T2CON=0x34;
  223.         T2MOD=0x00;
  224.         RCAP2H=0xFF;
  225.         RCAP2L=0xDC;
  226.   SCON=0x50;  
  227.   PCON=0x00;

  228.   PS=1;
  229.         TR1=1;
  230.         ET1=1;
  231.         ES=1;
  232.   EA=1;  
  233.         
  234.         delay(100);
  235.         OLED_Init();                        //初始化OLED  
  236.         OLED_Clear();
  237.         BEEP=1;
  238.   push_val_left=15;          //舵机归中
  239.         OLED_ShowCHinese(0,0,0);//信
  240.                 OLED_ShowCHinese(16,0,1);//息
  241.                 OLED_ShowString(32,0,"1902",16);
  242.                 OLED_ShowCHinese(64,0,2);//王
  243.                 OLED_ShowCHinese(80,0,3);//晨
  244.                 OLED_ShowCHinese(0,2,6);//左
  245.                 OLED_ShowCHinese(16,2,9);//侧
  246.                 OLED_ShowCHinese(32,2,4);//距
  247.                 OLED_ShowCHinese(48,2,5);//离
  248.                 OLED_ShowCHinese(64,2,10);//:
  249.                
  250.                 OLED_ShowCHinese(32,4,4);//距
  251.                 OLED_ShowCHinese(48,4,5);//离
  252.                 OLED_ShowCHinese(64,4,10);//:
  253.                
  254.                 OLED_ShowCHinese(0,6,7);//右
  255.                 OLED_ShowCHinese(16,6,9);//侧
  256.                 OLED_ShowCHinese(32,6,4);//距
  257.                 OLED_ShowCHinese(48,6,5);//离
  258.                 OLED_ShowCHinese(64,6,10);//:
  259.         while(1)                                                        /*无限循环*/
  260.         {
  261.                 while(flag_bj)                       /*无限循环*/
  262.            {
  263.              if(timer>=1000)          //100MS检测启动检测一次
  264.              {
  265.                timer=0;
  266.                    StartModule(); //启动检测
  267.            Conut();                  //计算距离
  268.            if(S<20)                  //距离小于20CM
  269.                    {
  270.                    stoprun();          //小车停止
  271.                    COMM();                   //方向函数
  272.                    }
  273.                    else
  274.                    if(S>30)                  //距离大于,30CM往前走
  275.                    run();
  276.              }

  277.                          if(flag_REC==1)
  278.                         {
  279.                           push_val_left=15;          //舵机归中
  280.                           stoprun();
  281.                           break;
  282.                         }
  283.           }
  284.           if(flag_REC==1)                                    //
  285.            {
  286.                 flag_REC=0;
  287.                 if(buff[0]=='O'&&buff[1]=='N')        //第一个字节为O,第二个字节为N,第三个字节为控制码
  288.                         BEEP=1;
  289.                 switch(buff[2])
  290.              {
  291.                       case up :                                                    // 前进
  292.                           flag_xj=0;
  293.                           flag_bj=0;
  294.                           run();
  295.                           break;

  296.                       case down:                                                // 后退
  297.                           flag_xj=0;
  298.                           flag_bj=0;
  299.                           backrun();
  300.                           break;

  301.                       case left:                                                // 左转
  302.                           flag_xj=0;
  303.                           flag_bj=0;
  304.                           leftrun();
  305.                           break;

  306.                       case right:                                                // 右转
  307.                           flag_bj=0;
  308.                           rightrun();
  309.                           break;

  310.                       case stop:                                                // 停止
  311.                           flag_bj=0;
  312.                           stoprun();
  313.                           break;

  314.                           case Car1:                                                //                 
  315.                           flag_bj=1;
  316.                           break;
  317.                                 
  318.                                 case Beep:
  319.                           flag_bj=0;
  320.                                 whistle();
  321.                           break;
  322.              }                 
  323.          }               
  324.         }
  325. }                                   
  326.         
复制代码
原理图和pcb下载: 原理图和PCB.7z (15.05 MB, 下载次数: 247)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:913671 发表于 2021-11-13 17:51 | 只看该作者
楼主这个非常全面
回复

使用道具 举报

板凳
ID:836340 发表于 2022-3-11 09:04 | 只看该作者
这个代码可以的
回复

使用道具 举报

地板
ID:1068002 发表于 2023-4-27 21:42 | 只看该作者
您好,请问这个可以做出实物吗?求实物
回复

使用道具 举报

5#
ID:109547 发表于 2023-5-18 23:14 | 只看该作者
应该是好东西
回复

使用道具 举报

6#
ID:1078477 发表于 2023-5-19 11:05 | 只看该作者
做出来了吗?效果如何?
回复

使用道具 举报

7#
ID:1083820 发表于 2023-6-16 08:56 | 只看该作者
压缩包内包含什么内容啊
回复

使用道具 举报

8#
ID:143767 发表于 2024-1-23 14:30 | 只看该作者
没有蓝牙APP,做了也没用
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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