找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4365|回复: 4
收起左侧

单片机蓝牙避障小车程序

[复制链接]
ID:215520 发表于 2019-2-20 16:35 | 显示全部楼层 |阅读模式
(1)、手机APP控制,无线蓝牙控制
(2)、自动避障,遇到障碍物自动躲避
(3)、带刹车灯,转向灯,和倒车蜂鸣器提示
(4)、带两个自由度的机械手

制作出来的实物图如下:

小车正面

小车正面

小车前面

小车前面

小车后面

小车后面


单片机代码:
#include <reg52.h>

sbit Servo=P0^0;

sbit IN1=P1^2;
sbit IN2=P1^3;
sbit IN3=P1^4;
sbit IN4=P1^5;

sbit LLED=P2^0;
sbit RLED=P2^1;
sbit SLED=P2^4;
sbit BUZZER=P2^5;
sbit PWM1=P2^6;
sbit PWM2=P2^7;

sbit INT_0=P3^2;
sbit INT_1=P3^3;



        #define Left_led       { LLED=0;}          //左转向灯
        #define Right_led      { RLED=0;}          //右转向灯
                                #define Stop_led        { SLED=0;}          //刹车灯        

                          #define SLeft_led       { LLED=1;}          //停左转向灯
        #define SRight_led      { RLED=1;}          //停右转向灯                                
                                #define SStop_led       { SLED=1;}          //停刹车灯


        #define Left_moto_go      {IN1=0,IN2=1;}        //左边两个电机向前走
        #define Left_moto_back    {IN1=1,IN2=0;}        //左边两个电机向后转
        #define Left_moto_Stop    {IN1=0,IN2=0;}        //左边两个电机停转                     
        #define Right_moto_go     {IN3=1,IN4=0;}        //右边两个电机向前走
        #define Right_moto_back   {IN3=0,IN4=1;}        //右边两个电机向后走
        #define Right_moto_Stop   {IN3=0,IN4=0;}        //右边两个电机停转
        #define SBUZZER            {BUZZER=0;}          //蜂鸣器响
        #define SSBUZZER           {BUZZER=1;}          //蜂鸣器不响


                                #define uchar unsigned char
                                #define unit unsigned int



                bit bdata gbFlag;

  unsigned char  i=0;
        unsigned char  dat;
        unsigned char time1;        
        unsigned char time2;                                       
  char num1=0,dis1=1;
  char num2=0,dis2=1;                                
        void delay(unsigned int z);
  void delay_us(unsigned int aa);



/************************************************************************/        
/*--延时函数--*/
   void delay(unsigned int k)
{   
     unsigned int x,y;
           for(x=0;x<k;x++)
           for(y=0;y<2000;y++);
}

/************************************************************************/
/*--功能定义函数--*/



//刹车
     void  stoprun(void)
{

           Left_moto_Stop ;   //左电机STOP
           Right_moto_Stop ;  //右电机STOP
}
//刹车灯
    void stopled(void)
{

    Stop_led;
          delay(10);
                SStop_led;         
}



//前进
     void  run(void)
{

           Left_moto_go ;   //左电机往前走
           Right_moto_go ;  //右电机往前走               
     delay(20);
     stoprun();

}

//后退
     void  backrun(void)
{

           Left_moto_back ;   //左电机往后退
           Right_moto_back ;  //右电机往后退
           SBUZZER;
           Stop_led;        
           delay(20);
           SSBUZZER;
                 SStop_led;
           stoprun();
}

//左转
     void  leftrun(void)
{

           Left_moto_back ;   //左电机往后走
           Right_moto_go ;  //右电机往前走
           delay(10);
           stoprun();
}
//左转向灯
    void leftled(void)
{

          Left_led ; //左转向灯开
                delay(5);
          SLeft_led;  //左转向灯关
          delay(5);
}


//右转
     void  rightrun(void)
{

           Left_moto_go ;   //左电机往前走
           Right_moto_back ;  //右电机往后走
           delay(10);
           stoprun();
}
//右转向灯
    void   rightled(void)
{

          Right_led ;   //右转向灯开
          delay(5);
          SRight_led;    //右转向灯关
          delay(5);
}
/*********************************************************************/                 
/*--scan1函数--*/
void scan1()            //如果收到01,则X舵机加   
{        
        if(gbFlag)      //如果为1,则PWM+
        {
                //num1++;
                if(num1>=60)
                        num1=60;
                else
                        num1++;
                dis1=num1;
                leftled();
        }
        else        //否则PWM-
        {
                //num1--;
                if(num1<=0)
                        num1=0;
                else
                        num1--;
                dis1=num1;
                rightled();
        }
}

/*********************************************************************/                 
/*--scan2函数--*/
//void scan2()
//{
//if(gbFlag)         //如果收到07,则Y舵机加
//        {
//                        num2++;
//                if(num2>=60)
//                        num2=60;
//                        dis2=num2;
//        }
//    else               
//        {          num2--;
//                if(num2<=0)
//                        num2=0;
//                        dis2=num2;                                 
//        }
//}
void scan2()            //如果收到03,则Y舵机加   
{        
        if(gbFlag)       //如果为1,则PWM+
        {
                //num1++;
                if(num2>=60)
                        num2=60;
                else
                        num2++;
                dis2=num2;
                leftled();
        }
        else             //否则PWM-
        {
                //num1--;
                if(num2<=0)
                        num2=0;
                else
                        num2--;
                dis2=num2;
                rightled();
        }
}

/*********************************************************************/                 
/*--choose1函数--*/
void choose1(void)
{

                Servo=0;     //舵机关

}
/*********************************************************************/                 
/*--choose2函数--*/
void choose2(void)
{

                Servo=1;     //舵机开

}

/*********************************************************************/                 
/*--主函数--*/
        void main()
{

          PS=1;       //中断优先级T0,T2低
                PX0=1;
                PX1=1;
    PT0=0;
          PT2=0;

          TMOD=0x21;       //设置定时器1为方式2,定时器0工作方式1        
                TH0=(65536-50)/256; //0xff;        //(65536-1000)/256;   //赋初值定时
                TL0=(65536-50)%256;  //0xf7;        //(65536-1000)%256;   //0.01ms
          TH1=0xfd;                     //11.0592M晶振,9600波特率
    TL1=0xfd;        //装初值
                RCAP2H=(65536-50)/256;  //0xff;        //(65536-10)/256;//赋初值定时
                RCAP2L=(65536-50)%256;  //0xf7;        //(65536-10)%256;//0.01ms        
          TH2=RCAP2H;         //
          TL2=RCAP2L;        //赋初值定时


    TR1=1;           //启动定时器
          REN=1;           //使能接收
    SM0=0;  
    SM1=1;           //设置串口为工作方式1        
          EA=1;            //打开总中断开关
          ES=1;            //打开串口中断开关
                ET0=1;           //开定时器0中断
                ET2=1;           //开定时器2中断               
                TR0=1;           //启动定时器0
                TR2=1;           //启动定时器2               



          EX0=1;          //允许INT0中断
          EX1=1;          //允许INT1中断
          IT0=1;          //外中断0边沿触发
          IT1=1;          //外中断1边沿触发
          while(1) ;       //等待中断

}
/*********************************************************************/                 
/*--返回数据函数--*/
//void putchar (unsigned char c)
//{
//  SBUF=c;
//        while(TI==0);    //等待发送完成
//  TI=0;            //清除TI标志准备下一次发送

//}
//   void main()
//         {
//         init();
//         while(1)
//                {
//           if(R_sign)
//                 {
//                         putchar(dat);  //将接受到的字符发回
//                         R_sign=0;
//                 }

//         }
//                 
//         }
//                 

/*********************************************************************/                 
/*--避障函数--*/
void int0(void)        interrupt 0 using 1      //外中断0服务子函数
{
  backrun();         //后退
        while(INT_0==0)    //还在障碍物范围内继续后退
        backrun();


}         
void int1(void)        interrupt 2 using 1         //外中断1服务子函数
{

  run();              //后退
        while(INT_1==0)     //还在障碍物范围内继续后退
  run();


}
/*********************************************************************/                 
/*--PWM1函数--*/
void timer0()interrupt 1 using 2
        {
    TR0=1;  //打开定时器0
    TH0=(65536-50)/256;   //0xff;        //(65536-1000)/256;//赋初值定时
    TL0=(65536-50)%256;   //0xf7;        //(65536-1000)%256;//0.05ms

                TR0=0;   //关闭定时器0
    TR2=1;   //打开定时器2               
                time1++;
                if(time1>=100)time1=0;//5KHZ
                if(time1<=dis1)PWM1=1;//占空比0~60%
                else PWM1=0;

        }
/*********************************************************************/                 
/*--PWM2函数--*/
void timer2()interrupt 5 using 2
        {

    TR2=1;                      //开定时器2
                TF2=0;                     //中断时软清
                RCAP2H=(65536-50)/256;  //0xff;        //(65536-50)/256;//赋初值定时
                RCAP2L=(65536-50)%256;  //0xf7;        //(65536-50)%256;//0.05ms        
          TH2=RCAP2H;         //
          TL2=RCAP2L;        //赋初值定时
                TR2=0;                     //关定时器2
                TR0=1;                     //开定时器0

                time2++;
                if(time2>=100)time2=0;       //5KHZ
                if(time2<=dis2)PWM2=1;      //占空比0~60%
                else PWM2=0;

        }
/*********************************************************************/                 
/*--通讯函数--*/

void ser() interrupt 4 using 3
{
          ES=0;   
    RI=0;       //将接受中断标志位清零
    dat=SBUF;   // 将接受到的数据赋值给dat   



                switch(dat)
             {
                      case 0x02:                                                 // 前进
                                                choose1();
                                                run();
                                                break;

                      case 0x08:                                                // 后退
                                                choose1();
                              backrun();
                              break;

                      case 0x06:                                                // 左转
                                                choose1();
                              leftrun();
                                    leftled();        
                              break;

                      case 0x04:                                                // 右转
                                                choose1();
                              rightrun();
                                    rightled();
                              break;

                      case 0x05:                                                // 功能键
                                                gbFlag=~gbFlag;     //状态取反
            stopled();
                              break;

                                        case 0x01:           //X舵机加(减)
                                                choose2();         //舵机开
                                          scan1();                              
                                                break;

                                        case 0x03:           //Y舵机加(减)
            choose2();           
                                          scan2();                                             
                                                break;



                            default : break;

             }

      ES=1;


}




评分

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

查看全部评分

回复

使用道具 举报

ID:462283 发表于 2019-3-1 17:20 | 显示全部楼层
好东西
回复

使用道具 举报

ID:482955 发表于 2019-3-1 20:42 | 显示全部楼层
请问硬件电路原理图方便贴出来吗?
回复

使用道具 举报

ID:482955 发表于 2019-3-1 20:43 | 显示全部楼层
请问原理图方便贴出来吗?
回复

使用道具 举报

ID:382454 发表于 2019-3-1 22:37 来自手机 | 显示全部楼层
这个挺有戏的
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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