找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5419|回复: 1
收起左侧

51单片机智能小车红外遥控选择功能源码

[复制链接]
ID:113539 发表于 2016-4-11 19:15 | 显示全部楼层 |阅读模式
包含以下功能:1、人工操作(前进、后退、左转、右转)
2、超声波避障(包含距离的显示)
3、红外避障
源码:
/*******************************XB-4WD 智能小车参考程序****************************************
*  平台:XB-4WD + Keil4 + STC89C52
*  名称:小车超声波避障     
*  日期:2014-5-18
*   QQ : 61924336
**********************************************************************************************/

/**********************************************************************************************
**                                 智能小车接线说明
**********************************************************************************************/

/**********************************************************************************************
             电池盒                                        XB-L293D驱动板上的电池输入端子(蓝色)         
***********************************************************************************************
                红线(+)    -------------------------------    蓝色输入端子(+)
                 黑线(-)    -------------------------------    蓝色输入端子(-)
***********************************************************************************************        

/**********************************************************************************************
  XB-L293D驱动板上的5V电源输出排针                     XB-1A主板上的+5V电源输入排针         
***********************************************************************************************
                VCC          -------------------------------       +5V
                 GND          -------------------------------       GND
***********************************************************************************************        

/**********************************************************************************************
    XB-1A主板             XB-L293D驱动板(输入)           *      XB-L293D驱动板(输出)           电机
***********************************************************************************************
          P1.0    ---------    IN1                                   *                     OUT1      ---------    左上电机(+)
           P1.1    ---------    IN2                 *             OUT2      ---------    左上电机(-)
***********************************************************************************************                                                                                           *
          P1.2    ---------    IN3                                   *                     OUT3      ---------    左下电机(+)
           P1.3    ---------    IN4                 *             OUT4      ---------    左下电机(-)
***********************************************************************************************
          P1.4    ---------    IN5                                   *                     OUT5      ---------    右上电机(+)
           P1.5    ---------    IN6                 *             OUT6      ---------    右上电机(-)
***********************************************************************************************
          P1.6    ---------    IN7                                   *                     OUT7      ---------    右下电机(+)
           P1.7    ---------    IN8                 *             OUT8      ---------    右下电机(-)
***********************************************************************************************/

/***********************************************************************************************
            舵机模块                                             XB-1A主板         
************************************************************************************************
                红色线(电源正)    --------------------------    JPW(+5V)
                 棕色线(电源负)    --------------------------    JPW(GND)
                        橙色线(信号线)    --------------------------    P2.7
************************************************************************************************

/***********************************************************************************************
            超声波模块                                             XB-1A主板         
************************************************************************************************
                VCC     --------------------------------------    JPW(+5V)
                 TRIG    --------------------------------------    P2.1
                        ECHO    --------------------------------------    P2.0
                        GND     --------------------------------------    JPW(GND)
************************************************************************************************

        
/***********************************************************************************************
**                                    头文件
***********************************************************************************************/        
#include<AT89x51.H>
#include <intrins.h>
#define uchar unsigned char
#define uint  unsigned int
#define ulong  unsigned long
/**********************************************************************************************
**                                    舵机信号线(橙色)
**********************************************************************************************/
#define Sevro_moto_pwm     P2_7           
/**********************************************************************************************
**                                    超声波控制线
**********************************************************************************************/
#define  ECHO  P2_5                                                            //超声波接口定义                P2.1
#define  TRIG  P2_6                                                            //超声波接口定义                P2.0
#define Left_moto_pwm1          P2_0                     //PWM信号端
#define Left_moto_pwm2          P2_1                     //PWM信号端
#define Right_moto_pwm1          P2_2                     //PWM信号端
#define Right_moto_pwm2          P2_3                     //PWM信号端
#define Left_1_led        P3_4                     //左传感器      
#define Right_1_led       P3_5                     //右传感器
/**********************************************************************************************
**                                    蜂鸣器接口定义
**********************************************************************************************/
sbit FM = P3^6;                            //蜂鸣器接口
sbit Speed=P3^7;                                           //控制外部中断
/******************************************************************
**                       接线定义
******************************************************************/
#define Left_moto_go      {P1_0=1,P1_1=0,P1_2=1,P1_3=0;}    //左边两个电机向前走
#define Left_moto_back    {P1_0=0,P1_1=1,P1_2=0,P1_3=1;}         //左边两个电机向后转
#define Left_moto_Stop    {P1_0=0,P1_1=0,P1_2=0,P1_3=0;}    //左边两个电机停转                     
#define Right_moto_go     {P1_4=1,P1_5=0,P1_6=1,P1_7=0;}        //右边两个电机向前走
#define Right_moto_back   {P1_4=0,P1_5=1,P1_6=0,P1_7=1;}        //右边两个电机向前走
#define Right_moto_Stop   {P1_4=0,P1_5=0,P1_6=0,P1_7=0;}        //右边两个电机停转
/******************************************************************
**                       红外遥控器的相关定义
******************************************************************/
#define Imax 14000            //此处为晶振为11.0592时的取值,
#define Imin 8000            //如用其它频率的晶振时,
#define Inum1 1450            //要改变相应的取值。
#define Inum2 700
#define Inum3 3000


/**********************************************************************************************
**                                   变量定义
**********************************************************************************************/   
uchar disbuff[4]          ={ 0,0,0,0,};
uchar posit=0;

uchar pwm_val_steering  = 0;                                //变量定义
uchar push_val_steering =14;                                //舵机归中,产生约,1.5MS 信号
uchar pwm_val_left  =0;                                    //变量定义
uchar push_val_left =0;                                    //左电机占空比N/20
uchar pwm_val_right =0;
uchar push_val_right=0;                             //右电机占空比N/20
bit Right_moto_stop=1;
bit Left_moto_stop =1;
ulong S=0;
ulong S1=0;
ulong S2=0;
ulong S3=0;
ulong S4=0;
uint  time=0;                                            //时间变量
uint  timer=0;                                                //延时基准变量
uchar timer1=0;                                                //扫描时间变量        
uint num = 3;                                

uchar f=0;
uchar Im[4]={0x00,0x00,0x00,0x00};
uchar show[2]={0,0};
ulong m,Tc;
uchar IrOK;

bit flag;

uint shu[9]={1,2,3,4,5,6, 7,8,9};
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};         //0~9         共阳极数码管
uchar code chose[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};         //共阴极数码管


void ultrasonic( void );                        //超声波避障
void artificial( void );                        //人工操作小车
void control_menu(void );                        //主控菜单


/**********************************************************************************************
**                                    延时函数
**********************************************************************************************/
void delay(unsigned int k)          //延时函数
{   
     unsigned int x,y;
           for(x=0;x<k;x++)
             for(y=0;y<2000;y++);
}
void delayms(uint z)
{
uint x,y;
  for(x=z;x>0;x--)
  for(y=99;y>0;y--);
}
/**********************************************************************************************
**                                    启动测距信号
**********************************************************************************************/
void  StartModule()                       
{
  TRIG=1;                                       
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  TRIG=0;
}

/******************************************************************
**                       小车前进
******************************************************************/
void  run(void)
{
         push_val_left=8;
         push_val_right=8;
         Left_moto_go ;                        //左电机往前走
         Right_moto_go ;                //右电机往前走
}
/******************************************************************
**                       小车后退
******************************************************************/
void  backrun(void)
{
         push_val_left=8;
         push_val_right=8;
         Left_moto_back ;                //左电机后退
         Right_moto_back ;                //右电机后退   
}
/******************************************************************
**                       小车左转
******************************************************************/
void  leftrun(void)
{
         push_val_left=8;
         push_val_right=8;
         Right_moto_back ;                //右电机后退
         Left_moto_go ;                  //左电机前进
}
/******************************************************************
**                       小车右转
******************************************************************/
void  rightrun(void)
{
         push_val_left=8;
         push_val_right=8;
         Right_moto_go;                        //右电机前进
         Left_moto_back ;                //左电机停止
}
/******************************************************************
**                       小车停走
******************************************************************/
void  stoprun(void)
{
         push_val_left=8;
         push_val_right=8;
         Left_moto_Stop
         Right_moto_Stop;   
}
/**********************************************************************************************
**                                    数码管显示
**********************************************************************************************/

/**********************************************************************************************
**                                    显示数据的转换
**********************************************************************************************/
void display()
{  
        P0=table[disbuff[1]];
        P2_0 = 0;
        delayms(5);
        P2_0 = 1;
        P0=table[disbuff[0]];
        P2_1 = 0;
        delayms(5);
        P2_1 = 1;
        P0=table[disbuff[1]];
        P2_2 = 0;
        delayms(5);
        P2_2 = 1;
        P0=table[disbuff[2]];
        P2_3 = 0;
        delayms(5);
        P2_3 = 1;
}
/**********************************************************************************************
**                                    计算距离
**********************************************************************************************/
void Conut(void)                  
{
        while(!ECHO);                                //当RX为零时等待
        TR0=1;                                                //开启计数
        while(ECHO);                                //当RX为1计数并等待
        TR0=0;                                                //关闭计数
        time=TH0*256+TL0;                        //读取脉宽长度
        TH0=0;
        TL0=0;
        S=(time*1.7)/100;                        //算出来是CM
        disbuff[0]=S%1000/100;                //更新显示        百位
        disbuff[1]=S%1000%100/10;        //更新显示        十位
        disbuff[2]=S%1000%10 %10;        //更新显示        个位
}
/**********************************************************************************************
**                                    计算速度
**********************************************************************************************/
void speed(void)                  
{
        TR1=1;
        TH1=0;
        TL1=0;
        flag=0;
        while(flag==0);
        S=TH1*256+TL1;        
        disbuff[0]=S%1000/100;                //更新显示        百位
        disbuff[1]=S%1000%100/10;        //更新显示        十位
        disbuff[2]=S%1000%10 %10;        //更新显示        个位
}
/**********************************************************************************************
**                                    判断小车该往哪边走
**********************************************************************************************/
void judge(void)
{        
        if((S2<40)||(S4<40)){         //只要左右各有距离小于,30CM小车后退
                backrun();                           //后退
                timer=0;
                while(timer<=1000);
        }
        if(S2>S4){
                rightrun();                  //车的左边比车的右边距离小        右转        
                timer=0;
                while(timer<=800);
        }else{
                leftrun();                        //车的左边比车的右边距离大        左转
                timer=0;
                while(timer<=800);
        }
}
void judge1(void)
{        
        if((S2>S4)&&(S2 > 40)){
                rightrun();                  //车的左边比车的右边距离小        右转        
                timer=0;
                while(timer<=800);
        }else if((S2<=S4)&&(S4 > 40)){
                leftrun();                        //车的左边比车的右边距离大        左转
                timer=0;
                while(timer<=800);
        }
}


/**********************************************************************************************
**                                    左右超声波检测距离
**********************************************************************************************/
void  COMM( void )                       
{
        push_val_steering=5;                  //舵机向右转90度
        timer=0;
        while(timer<=3500);                         //延时400MS让舵机转到其位置                 4000
        StartModule();                                  //启动超声波测距
    Conut();                                           //计算距离
        display();                                        //显示距离
        S2=S;  

        push_val_steering=25;                  //舵机再向左转180度
        timer=0;
        while(timer<=3500);                         //延时400MS让舵机转到其位置
        StartModule();                                  //启动超声波测距
    Conut();                                          //计算距离
        display();                                        //显示距离
        S4=S;         

        push_val_steering=14;                  //舵机归中
        timer=0;
        while(timer<=3500);                         //延时400MS让舵机转到其位置
        StartModule();                                  //启动超声波测距
    Conut();                                          //计算距离
        display();                                        //显示距离
        S1=S;
        judge();
}
/*********************************************************************************************/
/*                    PWM调制电机转速                                                        */
/*********************************************************************************************/
/*                    舵机电机调速                                                           */
/* 调节steering_engine_left的值改变舵机转速,占空比                                           */

void pwm_Servomoto(void)
{   
    if(pwm_val_steering<=push_val_steering)
                   Sevro_moto_pwm=1;
        else
            Sevro_moto_pwm=0;
        if(pwm_val_steering>=100)
                pwm_val_steering=0;
}
/******************************************************************
**                       左电机调速
******************************************************************/
void pwm_out_left_moto(void)
{  
        if(Left_moto_stop){
            if(pwm_val_left<=push_val_left){
                        Left_moto_pwm1=1;
                        Left_moto_pwm2=1;
                }else {
                        Left_moto_pwm1=0;
                        Left_moto_pwm2=0;
                }
                if(pwm_val_left>=20)
                    pwm_val_left=0;
        }else{
                Left_moto_pwm1=0;
                Left_moto_pwm2=0;
        }
}
/******************************************************************
**                       右电机调速
******************************************************************/
void pwm_out_right_moto(void)
{
        if(Right_moto_stop){
            if(pwm_val_right<=push_val_right){
                    Right_moto_pwm1=1;
                        Right_moto_pwm2=1;
                }else {
                        Right_moto_pwm1=0;
                        Right_moto_pwm2=0;
                }
                if(pwm_val_right>=20)
                    pwm_val_right=0;
   }else {
       Right_moto_pwm1=0;
           Right_moto_pwm2=0;
   }
}
/**********************************************************************************************
**                              TIMER1中断服务子函数产生PWM信号                                                                 **
**********************************************************************************************/
/******************************************************************
**                       定时器0初始化
******************************************************************/
void timer0_Init(void)
{
        TMOD=0X01;
        TH0= 0XFc;                  //1ms定时
        TL0= 0X18;
        TR0= 1;
        ET0= 1;
        EA = 1;                           //开总中断        
}         
/******************************************************************
**                   定时器0中断服务子程序
******************************************************************/
void timer0()interrupt 1   using 2
{
     TH0=0XFc;         
         TL0=0X18;
         time++;
         pwm_val_left++;
         pwm_val_right++;
         pwm_out_left_moto();
         pwm_out_right_moto();
}
/******************************************************************
**                   定时器1中断服务子程序
******************************************************************/
void time1()interrupt 3   using 2
{        
     TH1=(65536-100)/256;          //100US定时
         TL1=(65536-100)%256;
         timer++;                                  //定时器100US为准。在这个基础上延时
         pwm_val_steering++;
         pwm_Servomoto();
         timer1++;                                 //2MS扫一次数码管
         if(timer1>=20){
                 timer1=0;
         }
}
/******************************************************************
**                       外部中断解码程序
******************************************************************/
void intersvr0(void) interrupt 0 using 1
{
        Tc=TH0*256+TL0;     //提取中断时间间隔时长
    TH0=0;
    TL0=0;              //定时中断重新置零
         if((Tc>Imin)&&(Tc<Imax)){
        m=0;
        f=1;
        return;
        }       //找到启始码
        if(f==1){
                if(Tc>Inum1&&Tc<Inum3) {
                        Im[m/8]=Im[m/8]>>1|0x80; m++;
                }
                if(Tc>Inum2&&Tc<Inum1) {
                        Im[m/8]=Im[m/8]>>1; m++; //取码
                }
                  if(m==32) {
                        m=0;  
                        f=0;
                        if(Im[2]==~Im[3]) {
                                IrOK=1;
                        }
                else IrOK=0;   //取码完成后判断读码是否正确
             }                  
   }        //准备读下一码
}
/******************************************************************
**                       红外线避障
******************************************************************/
void Infrared(void)
{
        timer0_Init();     
        while(1){
                if(IrOK==1) {
                                stoprun();
                                switch(Im[2]) {
                                        case 0x16:               
                                                                control_menu();         //返回主控菜单
                                                            break;
                                        default:
                                                                break;
                                }
                                IrOK=0;
                }
                if(Left_1_led==1&&Right_1_led==1)                              //左右边都检测不到红外,灯都是灭的
                          run();                                                //调用前进函数
                else{                          
                        if(Left_1_led==1&&Right_1_led==0){                  //右边边检测到红外,右边灯亮
                                leftrun();                                                       //调用小车左转函数
                        }  
                        if(Right_1_led==1&&Left_1_led==0){                  //左边检测到红外,左边灯亮         
                                rightrun();                                                           //调用小车右转函数
                        }
                        if(Right_1_led == 0 && Left_1_led == 0){        //左右检测到红外,左右灯亮
                                backrun();                                                                //小车后退
                        }
                }         
        }
}
/**********************************************************************************************
**                              超声波的避障代码
**********************************************************************************************/
void ultrasonic( void )
{  IrOK=0;
        TMOD=0X11;
        TH1=(65536-100)/256;          //100US定时
        TL1=(65536-100)%256;
        TR1= 1;ET1= 1;
        ET0= 1;TR0=1;
        m=0;f=0;
    IT0=1;EX0=1;   
    TH0=0;TL0=0;TR0=1;
        EA=1;
        delay(100);
        push_val_steering=14;                  //舵机归中
        while (1){
                        if(IrOK==1) {
                                stoprun();
                                switch(Im[2]) {
                                        case 0x16:               
                                                                control_menu();                                 //返回主控菜单
                                                            break;
                                        default:
                                                                break;
                                }
                                IrOK=0;
                        }
                if(timer>=200){                  //80MS检测启动检测一次         800
                        timer=0;
                        StartModule();                 //启动检测
                        Conut();                        //计算距离
                        display();
                        if(S<=40) {                        //距离小于40CM
                                stoprun();                //小车停止
                                COMM();                 //方向函数
                        } else
                                if(S>40){                //距离大于,40CM往前走
                                        run();
                                }
                }         
        }
}
/**********************************************************************************************
**                              人工操控小车代码
**********************************************************************************************/
void artificial( void )
{
        m=0;f=0;
    IT0=1;EX0=1;
    TMOD=0x11;  
    TH0=0;TL0=0;
    TR0=1;
        EA=1;        
        delay(100);        
        speed();
        display();
        while(1) {                       /*无限循环*/
                if(IrOK==1) {
                     switch(Im[2]) {
                                case 0x18:         run();                                 //前进
                                                     break;
                                case 0x52:         backrun();                  //后退        
                                                        break;
                                case 0x08:        leftrun();                         //左转
                                                        break;
                                case 0x5A:        rightrun();                 //右转
                                                        break;
                                case 0x1C:         stoprun();                        //停止
                                                        break;
                                case 0x16:         stoprun();
                                                        control_menu();                //返回主控菜单
                                                        break;
                                default:
                                                        break;
                        }
                        IrOK=0;
             }
        }   
}
/**********************************************************************************************
**                             小车主控菜单代码
**********************************************************************************************/
void control_menu(void )
{
        m=0;f=0;
    IT0=1;EX0=1;
    TMOD=0x11;  
    TH0=0;TL0=0;
    TR0=1;
        EA=1;        
        delay(100);         
        while(1){
                if(IrOK==1) {
                     switch(Im[2]) {
                                case 0x18:         push_val_steering=14;                  //舵机归中
                                                        artificial();                         //人工控制小车
                                                     break;
                                case 0x0C:
                                                        ultrasonic();                        //超声波避障
                                                        break;
                                case 0x5E:         
                                                        Infrared();                                //红外线避障
                                                        break;
                                case 0x08:         num = 4;
                                                        ultrasonic();                        //超声波红外线避障
                                                        break;
                                default:
                                                        break;
                        }
                        IrOK=0;
                }
        }
}
/**********************************************************************************************
**                                       主函数
**********************************************************************************************/
void main(void)
{
        while(1) {                       /*无限循环*/
                control_menu();                 //调用主控菜单
        }   

}

/**********************************************************************************************
**                                        END FILE
**********************************************************************************************/
        

评分

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

查看全部评分

回复

使用道具 举报

ID:207886 发表于 2017-9-29 17:29 | 显示全部楼层
有电路图吗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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