原创 智能车 综合功能演示

2010-3-10 21:22 2246 5 6 分类: MCU/ 嵌入式

一、 实验简介:
本程序通过将以前所编写的分立程序通过有机结合,编制成一个大的应用系统。小车在完成自动防撞,防悬崖等动作外,还可以通过红外遥控器进行远程遥控。如果你对电脑编程很有趣兴的话,当然也可以通过电脑对串口进行编程。以方便通过电脑来进行对小车控制。在正常的运特过程中,还可以通过声控(拍手声)来对小车进行控制,每一种控制小车都会完成相应的功能。为了更清晰的看到小车运行过程状态,特将P1端口中的8个指示灯作为运行状态指示灯。以用来观察小车运行中的每一步。        
二、 实验原理图


点击看大图


三、 实现代码:
//===============================================================//
//  开发日期: 2009/01/30   编写综合功能演示子程序的最初代码确           //
//  修改日期:                                                           //
//  程序作者: guojun   益芯技术部                                 //
//  程序备注: 此程序仅为表现本机功能而演示用,当用作实际工程时请慎用.    //
//  特别声明: 此程序可作研究之用,但引用,转载,使用请注明出处.             //
//===============================================================//
#include <at89x51.h>                                   //包含51相关的头文件
typedef unsigned char uchar;                           //重定义char数据类型
typedef unsigned int uint;                                //重定义int数据类型
#define ShowPort P2                                   //定义数码管显示端口
uchar code  LedShowData[]={0x03,0x9F,0x25,0x0D,0x99,    //定义数码管显示数据
                            0x49,0x41,0x1F,0x01,0x19}; //0,1,2,3,4,5,6,7,8,9
static unsigned int RecvData;                             //定义接收红外数据变量
static unsigned char CountData;                          //定义红外个数计数变量
static unsigned char AddData;                            //定义自增变量
static unsigned int LedFlash;                             //定义闪动频率计数变量
unsigned char HeardData;                              //定义接收到数据的高位变量
bit RunFlag="0";                                       //定义运行标志位
/***********完成基本数据变量定义**************/
sbit S1State=P1^0;                                    //定义S1状态标志位
sbit S2State=P1^1;                                     //定义S2状态标志位
sbit B1State=P1^2;                                     //定义B1状态标志位
sbit IRState="P1"^3;                                     //定义IR状态标志位
sbit RunStopState="P1"^4;                                //定义运行停止标志位
sbit FontIRState="P1"^5;                                  //定义FontIR状态标志位
sbit LeftIRState="P1"^6;                                  //定义LeftIR状态标志位
sbit RightIRState="P1"^7;                              //定义RightIRState状态标志位
/*************完成状态指示灯定义*************/
sbit S1=P3^2;                                       //定义S1按键端口
sbit S2=P3^4;                                        //定义S2按键端口
/*************完成按键端口的定义*************/      
sbit LeftLed="P2"^0;                                  //定义前方左侧指示灯端口
sbit RightLed="P0"^7;                                  //定义前方右侧指示灯端口
/*************完成前方指示灯端口定义*********/
sbit LeftIR="P3"^5;                                   //定义前方左侧红外探头
sbit RightIR="P3"^6;                                  //定义前主右侧红外探头
sbit FontIR="P3"^7;                                    //定义正前方红外探头
/*************完成红外探头端口定义***********/
sbit M1A=P0^0;                                      //定义电机1正向端口
sbit M1B=P0^1;                                      //定义电机1反向端口
sbit M2A=P0^2;                                      //定义电机2正向端口
sbit M2B=P0^3;                                    //定义电机2反向端口
/*************完成电机端口定义***************/
sbit B1=P0^4;                                        //定义话筒传感器端口
sbit RL1=P0^5;                                       //定义光敏电阻端口
sbit SB1=P0^6;                                        //定义蜂鸣端口
/*********完成话筒,光敏电阻,蜂鸣器.端口定义**/
sbit IR1=P3^3;                                        //定义红外接收端口
/*********完成红外接收端口的定义*************/
void Delay()                                          //定义延时子程序
{ uint DelayTime="30000";                                //定义延时时间变量
  while(DelayTime--);                                  //开始进行延时循环
  return;                                             //子程序返回
}
void ControlCar(uchar CarType)                  //定义小车控制子程序
{
 M1A=0;                                    //将电机1正向电平置低
 M1B=0;                                    //将电机1反向电平置低
 M2A=0;                                    //将电机2正向电平置低
 M2B=0;                                    //将电机2反向电平置低
 LeftLed=1;                                  //关闭前方左侧指示灯
 RightLed=1;                                 //关闭前方右侧指示灯
 Delay();                                    //将此状态延时一段时间
 switch(CarType)                              //判断小车控制指令类型
 {  case 1: //前进                             //判断是否是前进
    { M1A=1;                                //将电机1正向端口置高
      M2A=1;                               //将电机2正向端口置高
      break;                                 //退出判断
    }
    case 2: //后退                             //判断是否是后退
    { M1B=1;                                //将电机1反向端口置高
      M2B=1;                               //将电机2反向端口置高
      LeftLed="0";                            //将前方左侧指示灯置低(亮)
      RightLed="0";                            //将前方右侧指示灯置低(亮)
      break;                                 //退出判断
    }
    case 3: //左转                             //判断是否是左转
    { M1B=1;                                //将电机1反向端口置高
      M2A=1;                               //将电机2正向端口置高
      LeftLed="0";                             //将前方左侧指示灯置低(亮)
      break;                                 //退出判断
    }
    case 4: //右转                             //判断是否是右转
    { M1A=1;                                //将电机1正向端口置高
      M2B=1;                               //将电机2反向端口置高
      RightLed="0";                            //将前方右侧指示灯置低(亮)
      break;                                 //退出判断
    }
    default:                                  //默认情况下的判断
    {
     break;                                  //直接退出判断
    }
 }
}
void Timer0_IR1() interrupt 1 using 3              //定义红外定时器子程序
{
 TH0=0xFF;                                  //向定时器定时间寄存器填入高八位值
 TL0=0x19;                                  //向定时器定时间寄存器填入低八位值
 AddData++;                                 //自增变量加1
}
void Int1_IR1() interrupt 2                       //定义红外接收中断子程序
{
 TR1=0;                                     //将定时/计数器1关闭
 IRState=!IRState;                             //将红外接收指示灯状态取反
 if(4==AddData) //0                            //判断接收到的数据是0
 {
  RecvData="RecvData" | 0;                       //判断到0就将当前位写0
  RecvData="RecvData" << 1;                     //将当前位向左移动1位
 }
 else if(8==AddData)//1                         //判断接收到的数据是1
 {
  RecvData="RecvData" | 1;                       //将当前位写1
  RecvData="RecvData" << 1;                     //将当前位向左移动1位
 }
 CountData++;                                //将红外接收位计数器加1
 if(CountData==8)                             //判断是否接收到8位数据
 {
  HeardData="RecvData";                    //是8位数据时,则将数据暂存到高位变量中
 }
 else if(CountData==16)                    //判断是否接收到16位数据
 {
  ET0=0;                                //关闭红外定时器0
  EX1=0;                                //关闭红外外部中断1
  TR1=1;                                //打开定时/计数器1
  AddData="0";                             //定时时间间隔变量清零
  if(HeardData==226 || HeardData==112)       //判断用户码是否正确
  {
    HeardData="RecvData";                   //取出接收到的低八位数据
    switch(HeardData)                      //判断低八位数据的值下列那一位
    {
      case 32: //电源                   //说明按下了电源键
    { //在这里填写你自己的代码          //根据你的功能自己写
      ControlCar(8);                     //将小车停止
      RunFlag==1;                      //将运行标志位置1
      break;                            //返回
    }
   case 46: //TV/AV                      //说明按下了TV/AV键
    { //在这里填写你自己的代码          //根据你的功能自己写
      break;                            //返回
    }
   case 0: //1                             //说明按下数字1键
    {ShowPort= LedShowData[1];           //数码管显示数字1
     ControlCar(1);                       //将小车置于前进状态
     break;                              //返回
    }
   case 8: //2                             //说明按下了数字2键
    {ShowPort= LedShowData[2];            //数码管显示数字2
     ControlCar(2);                        //将小车置于后退状态
     break;                               //返回
    }
          case 4: //3                       //说明按下了数字3键
    {ShowPort= LedShowData[3];          //数码管显示数字3
     ControlCar(3);                     //将小车置于左转状态
     break;                            //返回
    }
   case 12: //4                          //说明按下了数字4键
    {ShowPort= LedShowData[4];          //数码管显示数字4
     ControlCar(4);                      //将小车置于右转状态
     break;                             //返回
    }
   case 2: //5                           //说明按下了数字5键
    {ShowPort= LedShowData[5];          //数码管显示数字5
     break;                             //返回
    }
   case 10: //6                           //说明按下了数字6键
    {ShowPort= LedShowData[6];          //数码管显示数字6
     break;                             //返回
    }
          case 6: //7                         //说明按下了数字7键
          {ShowPort= LedShowData[7];       //数码管显示数字7
           break;                          //返回
          }
         case 14: //8                        //说明按下了数字8键
          {ShowPort= LedShowData[8];        //数码管显示数字8
           break;                         //返回
          }
         case 64: //9                        //说明按下了数字9键
          {ShowPort= LedShowData[9];       //数码管显示数字9
           break;                          //返回
          }
         case 72: //0/30                     //说明按下0/30键
          {ShowPort= LedShowData[0];       //数码管显示数字0
           break;                          //返回
          }
         case 68: //10+                     //说明按下10+键
          {//在这里填写你自己的代码       //根据你的功能写代码
           break;                          //返回
          }
         case 76: //20+                     //说明按下了20+键
          {//在这里填写你自己的代码     //根据你的功能写代码
           break;                        //返回
          }
         case 36: //CH-                     //说明按下了CH-键
          {//在这里填写你自己的代码       //根据你的功能写代码
     break;                            //返回
          }
        case 40: //CH+                      //说明按下了CH+键
          {//在这里填写你自己的代码         //根据你的功能写代码
     break;                          //返回
          }
      }
   }
   RecvData="0";                              //将接收到的数据清零
   CountData="0";                            //将接收计数器清零
   HeardData="0";                             //将接收高低数据变量清零
   return;                                   //返回
  }
  AddData="0";                               //将定时器计数器清零
  ET0=1;                                  //打开定时器中断
}
void ComBreak() interrupt 4                    //定义串口通信子程序
{unsigned char RecvData;                     //定义串口数据接收变量
 if(RI==1)                                  //判断是否接收数据
 { RecvData="SBUF";                          //将接收到的数据放入暂时变量
   if(RecvData<10)                          //判断接收到的数据是否小于10
   {
    ShowPort="LedShowData"[RecvData];        //将接收到的数据通过数码管显示出来
    ControlCar(RecvData);                    //将串口数据置于小于状态
   }
   SBUF="RecvData";                         //向电脑返回当前接收到的数据
   RI="0";                                   //清除接收中断标志位
 }
 if(TI==1)                                  //判断是否是发送中断
 {
   TI="0";                                   //清除发送中断标志位
 }
}
void main(void)                              //主程序入口
{
 bit ExeFlag="0";                              //定义可执行标志位变量
 RecvData=0;                               //将接收变量数值初始化
 CountData=0;                              //将计数器变量数值初始化
 AddData=0;                               //将定时器计数器初始化
 HeardData=0;                              //将高低计数器初始化
 LedFlash=1000;                            //对闪灯数据进行初始化
 TMOD=0x01;                             //选择定时器0为两个16位定时器
 TH0=0xFF;                               //对定时器进行计数值进行初始化
 TL0=0x19;                                //同上,时间大约为25uS
 TR0=1;                                   //同意开始定时器0
 EX1=1;                                   //同意开启外部中断1
 IT1=1;                                    //设定外部中断1为低边缘触发类型
 ET0=0;
 SCON=80;                                 //设置串口模式为8位数据
 TMOD=33;                                //设置定时/计数器模式
 TH1=0xFD;                                //给定时器1高八位初始化初值
 TL1=0xFD;                                //给定时器1低八位初始化初值
 TR1=1;                                   //开启定时器1
 ES=1;                                    //开启串口通信功能
 REN=1;                                  //开启接收中断标志
 EA=1;                                   //总中断开启
 ControlCar(1);                             //将小车置于前进状态
 ShowPort=LedShowData[0];                  //数码管显示数字0
小车前进时操作,后退、左转、右转等操作时,没有写相应的查询程序)


while(1)                                   //程序主循环
 {
   while(LedFlash--)                         //闪灯总延时
    { 
     if(IR1==0)                            //判断延时期间是否有红外信号输入
     {ExeFlag=1;                            //将可执行标志位置1
     }
  if(S1==0)                              //判断是否有S1按下
  { 
   ControlCar(8);                        //将小车置于停止状态
   RunFlag==1;                          //改变小车运行状态标志位
   S1State=!S1State;                      //改变S1按键标志位
   goto NextRun;                         //跳转到NextRun标签
  }
  if(S2==0)                              //判断是否有S2按下
  {
   ControlCar(1);                        //将小车置于前进状态
   RunFlag==0;                         //改变小车运行状态标志位
   S2State=!S2State;                      //改变S2按键标志位
   goto NextRun;                        //跳转到NextRun标签
  }
  FontIRState=FontIR;                //前方红外指示灯显示正前方红外探头状态
  LeftIRState=LeftIR;                 //左侧红外指示灯显示前方左侧红外探头状态
  RightIRState=RightIR;               //右侧红外指示灯显示前主右侧红外探头状态
     if(FontIR==0 || LeftIR==1 || RightIR==1)  //判断正前方,前左侧,前右侧红外探头状态
     {ControlCar(2);                     //改变小车状态为后退
      SB1=!SB1;                   //将蜂鸣器取反
      Delay();                             //调用延时子程序
      SB1=!SB1;                   //将蜂鸣器取反
   Delay();                       //调用延时子程序
   SB1=!SB1;                         //将蜂鸣器取反
      Delay();                             //调用延时子程序
   SB1=!SB1;                        //将蜂鸣器取反
   Delay();                           //调用延时子程序
   SB1=!SB1;                         //将蜂鸣器取反
   Delay();                         //调用延时子程序
   SB1=!SB1;                         //将蜂鸣器取反
   Delay();                           //调用延时子程序
   SB1=!SB1;                         //将蜂鸣器取反
   ControlCar(3);                    //改变小车左转状态
   Delay();                       //调用延时子程序
   SB1=!SB1;                    //将蜂鸣器取反
   Delay();                   //调用延时子程序
   SB1=!SB1;                    //将蜂鸣器取反
   Delay();                         //调用延时子程序
   SB1=!SB1;                         //将蜂鸣器取反
   Delay();                            //调用延时子程序
   SB1=!SB1;                      //将蜂鸣器取反
   Delay();                      //调用延时子程序
   SB1=!SB1;                    //将蜂鸣器取反
   ControlCar(1);                  //改变小车为前进状态
   SB1=1;                       //关闭蜂鸣器声音
     }
    if(B1==0)                         //判断是否有话筒信号输入
    { if(RunFlag==0)                    //判断小车当前的运行标志位
      { ControlCar(8);                    //将小车置于停止状态
     RunFlag=1;                  //改变小车运行标志位
   }
   else
   { ControlCar(1);                   //将小车置于前进状态
     RunFlag=0;                     //改变小车运行标志位
   }
   B1State=!B1State;                   //将话筒信号指示灯取反
    }
  }
NextRun:                               //跳转标签
  if(RunFlag==0)                        //判断运行标志位
  {
   RunStopState=!RunStopState;           //改变小车运行停止状态标志位
  }
  else
  {
   RunStopState=1;                         //将运行停止状态标志位置1
  }
  LedFlash=1000;                             //运行闪动时间重设定
  if(ExeFlag==0)                            //判断可执行标志位
  {
   EX1=1;                                 //开启外部中断1
   TR1=1;                                 //开启定时/计数器1
  }
  ExeFlag=0;                                //可执行标志位置0
 }
}
四、 运行效果:
程序运行效果:将小车置于一个桌面上(桌面请不要使用黑色)。打开电源的开关,小车开始前进运行,同时运行指示灯闪亮,这时如果前方有障碍物(或走到悬崖处),小车将会先进行后退一段时间,并有蜂鸣器报警,再向左转一段时间,最后开始向前运行、左转、后退、右转、可以通过前方指示灯来观察。这时你可以能过声控(如拍手声)来让小车停止和开启.同时你也可以用遥控来控制小车的运行。按“1”,小车将向前运行,按“2”小车将后退,按“3”小车将左转,按“4”小车将右转.按其它(0-9)键,小车数管码显示相应的数字符号。按电源键,小车将会停止运行。同也可以用电脑将小车发送数字信号。其数码管也将显示相应的数字(0-9)。并执行相应的功能。当然S1、S2也是起作用,分别用于控制小车的停止和开启。(注意:操作时应在小车前进时操作,后退、左转、右转等操作时,没有写相应的查询程序)
三、 实现代码:

#include <at89x51.h>                                   //包含51相关的头文件
typedef unsigned char uchar;                           //重定义char数据类型
typedef unsigned int uint;                                //重定义int数据类型
#define ShowPort P2                                   //定义数码管显示端口
uchar code  LedShowData[]={0x03,0x9F,0x25,0x0D,0x99,    //定义数码管显示数据
                            0x49,0x41,0x1F,0x01,0x19}; //0,1,2,3,4,5,6,7,8,9
static unsigned int RecvData;                             //定义接收红外数据变量
static unsigned char CountData;                          //定义红外个数计数变量
static unsigned char AddData;                            //定义自增变量
static unsigned int LedFlash;                             //定义闪动频率计数变量
unsigned char HeardData;                              //定义接收到数据的高位变量
bit RunFlag=0;                                       //定义运行标志位
/***********完成基本数据变量定义**************/
sbit S1State=P1^0;                                    //定义S1状态标志位
sbit S2State=P1^1;                                     //定义S2状态标志位
sbit B1State=P1^2;                                     //定义B1状态标志位
sbit IRState=P1^3;                                     //定义IR状态标志位
sbit RunStopState=P1^4;                                //定义运行停止标志位
sbit FontIRState=P1^5;                                  //定义FontIR状态标志位
sbit LeftIRState=P1^6;                                  //定义LeftIR状态标志位
sbit RightIRState=P1^7;                              //定义RightIRState状态标志位
/*************完成状态指示灯定义*************/
sbit S1=P3^2;                                       //定义S1按键端口
sbit S2=P3^4;                                        //定义S2按键端口
/*************完成按键端口的定义*************/       
sbit LeftLed=P2^0;                                  //定义前方左侧指示灯端口
sbit RightLed=P0^7;                                  //定义前方右侧指示灯端口
/*************完成前方指示灯端口定义*********/
sbit LeftIR=P3^5;                                   //定义前方左侧红外探头
sbit RightIR=P3^6;                                  //定义前主右侧红外探头
sbit FontIR=P3^7;                                    //定义正前方红外探头
/*************完成红外探头端口定义***********/
sbit M1A=P0^0;                                      //定义电机1正向端口
sbit M1B=P0^1;                                      //定义电机1反向端口
sbit M2A=P0^2;                                      //定义电机2正向端口
sbit M2B=P0^3;                                    //定义电机2反向端口
/*************完成电机端口定义***************/
sbit B1=P0^4;                                        //定义话筒传感器端口
sbit RL1=P0^5;                                       //定义光敏电阻端口
sbit SB1=P0^6;                                        //定义蜂鸣端口
/*********完成话筒,光敏电阻,蜂鸣器.端口定义**/
sbit IR1=P3^3;                                        //定义红外接收端口
/*********完成红外接收端口的定义*************/
void Delay()                                          //定义延时子程序
{ uint DelayTime=30000;                                //定义延时时间变量
  while(DelayTime--);                                  //开始进行延时循环
  return;                                             //子程序返回
}
void ControlCar(uchar CarType)                  //定义小车控制子程序
{
 M1A=0;                                    //将电机1正向电平置低
 M1B=0;                                    //将电机1反向电平置低
 M2A=0;                                    //将电机2正向电平置低
 M2B=0;                                    //将电机2反向电平置低
 LeftLed=1;                                  //关闭前方左侧指示灯
 RightLed=1;                                 //关闭前方右侧指示灯
 Delay();                                    //将此状态延时一段时间
 switch(CarType)                              //判断小车控制指令类型
 {  case 1: //前进                             //判断是否是前进
    { M1A=1;                                //将电机1正向端口置高
      M2A=1;                               //将电机2正向端口置高
      break;                                 //退出判断
    }
    case 2: //后退                             //判断是否是后退
    { M1B=1;                                //将电机1反向端口置高
      M2B=1;                               //将电机2反向端口置高
      LeftLed=0;                            //将前方左侧指示灯置低(亮)
      RightLed=0;                            //将前方右侧指示灯置低(亮)
      break;                                 //退出判断
    }
    case 3: //左转                             //判断是否是左转
    { M1B=1;                                //将电机1反向端口置高
      M2A=1;                               //将电机2正向端口置高
      LeftLed=0;                             //将前方左侧指示灯置低(亮)
      break;                                 //退出判断
    }
    case 4: //右转                             //判断是否是右转
    { M1A=1;                                //将电机1正向端口置高
      M2B=1;                               //将电机2反向端口置高
      RightLed=0;                            //将前方右侧指示灯置低(亮)
      break;                                 //退出判断
    }
    default:                                  //默认情况下的判断
    {
     break;                                  //直接退出判断
    }
 } 
}
void Timer0_IR1() interrupt 1 using 3              //定义红外定时器子程序

 TH0=0xFF;                                  //向定时器定时间寄存器填入高八位值
 TL0=0x19;                                  //向定时器定时间寄存器填入低八位值
 AddData++;                                 //自增变量加1
}
void Int1_IR1() interrupt 2                       //定义红外接收中断子程序
{
 TR1=0;                                     //将定时/计数器1关闭
 IRState=!IRState;                             //将红外接收指示灯状态取反
 if(4==AddData) //0                            //判断接收到的数据是0
 {
  RecvData=RecvData | 0;                       //判断到0就将当前位写0
  RecvData=RecvData << 1;                     //将当前位向左移动1位
 }
 else if(8==AddData)//1                         //判断接收到的数据是1
 {
  RecvData=RecvData | 1;                       //将当前位写1
  RecvData=RecvData << 1;                     //将当前位向左移动1位
 }
 CountData++;                                //将红外接收位计数器加1
 if(CountData==8)                             //判断是否接收到8位数据
 {
  HeardData=RecvData;                    //是8位数据时,则将数据暂存到高位变量中
 }
 else if(CountData==16)                    //判断是否接收到16位数据
 {
  ET0=0;                                //关闭红外定时器0
  EX1=0;                                //关闭红外外部中断1
  TR1=1;                                //打开定时/计数器1
  AddData=0;                             //定时时间间隔变量清零
  if(HeardData==226 || HeardData==112)       //判断用户码是否正确
  {
    HeardData=RecvData;                   //取出接收到的低八位数据
    switch(HeardData)                      //判断低八位数据的值下列那一位
    {
      case 32: //电源                   //说明按下了电源键
    { //在这里填写你自己的代码          //根据你的功能自己写
      ControlCar(8);                     //将小车停止
      RunFlag==1;                      //将运行标志位置1
      break;                            //返回
    }
   case 46: //TV/AV                      //说明按下了TV/AV键
    { //在这里填写你自己的代码          //根据你的功能自己写
      break;                            //返回
    }
   case 0: //1                             //说明按下数字1键
    {ShowPort= LedShowData[1];           //数码管显示数字1
     ControlCar(1);                       //将小车置于前进状态
     break;                              //返回
    }
   case 8: //2                             //说明按下了数字2键
    {ShowPort= LedShowData[2];            //数码管显示数字2
     ControlCar(2);                        //将小车置于后退状态
     break;                               //返回
    }
          case 4: //3                       //说明按下了数字3键
    {ShowPort= LedShowData[3];          //数码管显示数字3
     ControlCar(3);                     //将小车置于左转状态
     break;                            //返回
    }
   case 12: //4                          //说明按下了数字4键
    {ShowPort= LedShowData[4];          //数码管显示数字4
     ControlCar(4);                      //将小车置于右转状态
     break;                             //返回
    }
   case 2: //5                           //说明按下了数字5键
    {ShowPort= LedShowData[5];          //数码管显示数字5
     break;                             //返回
    }
   case 10: //6                           //说明按下了数字6键
    {ShowPort= LedShowData[6];          //数码管显示数字6
     break;                             //返回
    }
          case 6: //7                         //说明按下了数字7键
          {ShowPort= LedShowData[7];       //数码管显示数字7
           break;                          //返回
          }
         case 14: //8                        //说明按下了数字8键
          {ShowPort= LedShowData[8];        //数码管显示数字8
           break;                         //返回
          }
         case 64: //9                        //说明按下了数字9键
          {ShowPort= LedShowData[9];       //数码管显示数字9
           break;                          //返回
          }
         case 72: //0/30                     //说明按下0/30键
          {ShowPort= LedShowData[0];       //数码管显示数字0
           break;                          //返回
          }
         case 68: //10+                     //说明按下10+键
          {//在这里填写你自己的代码       //根据你的功能写代码
           break;                          //返回
          }
         case 76: //20+                     //说明按下了20+键
          {//在这里填写你自己的代码     //根据你的功能写代码
           break;                        //返回
          }
         case 36: //CH-                     //说明按下了CH-键
          {//在这里填写你自己的代码       //根据你的功能写代码
     break;                            //返回
          }
        case 40: //CH+                      //说明按下了CH+键
          {//在这里填写你自己的代码         //根据你的功能写代码
     break;                          //返回
          }
      }
   }
   RecvData=0;                              //将接收到的数据清零
   CountData=0;                            //将接收计数器清零
   HeardData=0;                             //将接收高低数据变量清零
   return;                                   //返回
  }
  AddData=0;                               //将定时器计数器清零
  ET0=1;                                  //打开定时器中断
}
void ComBreak() interrupt 4                    //定义串口通信子程序
{unsigned char RecvData;                     //定义串口数据接收变量
 if(RI==1)                                  //判断是否接收数据
 { RecvData=SBUF;                          //将接收到的数据放入暂时变量
   if(RecvData<10)                          //判断接收到的数据是否小于10
   {
    ShowPort=LedShowData[RecvData];        //将接收到的数据通过数码管显示出来
    ControlCar(RecvData);                    //将串口数据置于小于状态
   }
   SBUF=RecvData;                         //向电脑返回当前接收到的数据
   RI=0;                                   //清除接收中断标志位
 }
 if(TI==1)                                  //判断是否是发送中断
 {
   TI=0;                                   //清除发送中断标志位
 }
}
void main(void)                              //主程序入口
{
 bit ExeFlag=0;                              //定义可执行标志位变量
 RecvData=0;                               //将接收变量数值初始化
 CountData=0;                              //将计数器变量数值初始化
 AddData=0;                               //将定时器计数器初始化
 HeardData=0;                              //将高低计数器初始化
 LedFlash=1000;                            //对闪灯数据进行初始化
 TMOD=0x01;                             //选择定时器0为两个16位定时器
 TH0=0xFF;                               //对定时器进行计数值进行初始化
 TL0=0x19;                                //同上,时间大约为25uS
 TR0=1;                                   //同意开始定时器0
 EX1=1;                                   //同意开启外部中断1
 IT1=1;                                    //设定外部中断1为低边缘触发类型
 ET0=0; 
 SCON=80;                                 //设置串口模式为8位数据
 TMOD=33;                                //设置定时/计数器模式
 TH1=0xFD;                                //给定时器1高八位初始化初值
 TL1=0xFD;                                //给定时器1低八位初始化初值
 TR1=1;                                   //开启定时器1
 ES=1;                                    //开启串口通信功能
 REN=1;                                  //开启接收中断标志
 EA=1;                                   //总中断开启
 ControlCar(1);                             //将小车置于前进状态
 ShowPort=LedShowData[0];                  //数码管显示数字0
 while(1)                                   //程序主循环
 {
   while(LedFlash--)                         //闪灯总延时
    { 
     if(IR1==0)                            //判断延时期间是否有红外信号输入
     {ExeFlag=1;                            //将可执行标志位置1
     }
  if(S1==0)                              //判断是否有S1按下
  { 
   ControlCar(8);                        //将小车置于停止状态
   RunFlag==1;                          //改变小车运行状态标志位
   S1State=!S1State;                      //改变S1按键标志位
   goto NextRun;                         //跳转到NextRun标签
  }
  if(S2==0)                              //判断是否有S2按下
  {
   ControlCar(1);                        //将小车置于前进状态
   RunFlag==0;                         //改变小车运行状态标志位
   S2State=!S2State;                      //改变S2按键标志位
   goto NextRun;                        //跳转到NextRun标签
  }
  FontIRState=FontIR;                //前方红外指示灯显示正前方红外探头状态
  LeftIRState=LeftIR;                 //左侧红外指示灯显示前方左侧红外探头状态
  RightIRState=RightIR;               //右侧红外指示灯显示前主右侧红外探头状态
     if(FontIR==0 || LeftIR==1 || RightIR==1)  //判断正前方,前左侧,前右侧红外探头状态
     {ControlCar(2);                     //改变小车状态为后退
      SB1=!SB1;                   //将蜂鸣器取反
      Delay();                             //调用延时子程序
      SB1=!SB1;                   //将蜂鸣器取反
   Delay();                       //调用延时子程序
   SB1=!SB1;                         //将蜂鸣器取反
      Delay();                             //调用延时子程序
   SB1=!SB1;                        //将蜂鸣器取反
   Delay();                           //调用延时子程序
   SB1=!SB1;                         //将蜂鸣器取反
   Delay();                         //调用延时子程序
   SB1=!SB1;                         //将蜂鸣器取反
   Delay();                           //调用延时子程序
   SB1=!SB1;                         //将蜂鸣器取反
   ControlCar(3);                    //改变小车左转状态
   Delay();                       //调用延时子程序
   SB1=!SB1;                    //将蜂鸣器取反
   Delay();                   //调用延时子程序
   SB1=!SB1;                    //将蜂鸣器取反
   Delay();                         //调用延时子程序
   SB1=!SB1;                         //将蜂鸣器取反
   Delay();                            //调用延时子程序
   SB1=!SB1;                      //将蜂鸣器取反
   Delay();                      //调用延时子程序
   SB1=!SB1;                    //将蜂鸣器取反
   ControlCar(1);                  //改变小车为前进状态
   SB1=1;                       //关闭蜂鸣器声音
     }
    if(B1==0)                         //判断是否有话筒信号输入
    { if(RunFlag==0)                    //判断小车当前的运行标志位
      { ControlCar(8);                    //将小车置于停止状态
     RunFlag=1;                  //改变小车运行标志位
   }
   else
   { ControlCar(1);                   //将小车置于前进状态
     RunFlag=0;                     //改变小车运行标志位
   }
   B1State=!B1State;                   //将话筒信号指示灯取反
    }
  }
NextRun:                               //跳转标签
  if(RunFlag==0)                        //判断运行标志位
  {
   RunStopState=!RunStopState;           //改变小车运行停止状态标志位
  }
  else
  {
   RunStopState=1;                         //将运行停止状态标志位置1
  }
  LedFlash=1000;                             //运行闪动时间重设定
  if(ExeFlag==0)                            //判断可执行标志位
  {
   EX1=1;                                 //开启外部中断1
   TR1=1;                                 //开启定时/计数器1
  }
  ExeFlag=0;                                //可执行标志位置0
 }
}
四、 运行效果:
程序运行效果:将小车置于一个桌面上(桌面请不要使用黑色)。打开电源的开关,小车开始前进运行,同时运行指示灯闪亮,这时如果前方有障碍物(或走到悬崖处),小车将会先进行后退一段时间,并有蜂鸣器报警,再向左转一段时间,最后开始向前运行、左转、后退、右转、可以通过前方指示灯来观察。这时你可以能过声控(如拍手声)来让小车停止和开启.同时你也可以用遥控来控制小车的运行。按“1”,小车将向前运行,按“2”小车将后退,按“3”小车将左转,按“4”小车将右转.按其它(0-9)键,小车数管码显示相应的数字符号。按电源键,小车将会停止运行。同也可以用电脑将小车发送数字信号。其数码管也将显示相应的数字(0-9)。并执行相应的功能。当然S1、S2也是起作用,分别用于控制小车的停止和开启

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户1547065 2010-3-7 18:39

写得不错
相关推荐阅读
用户267451 2010-03-10 21:31
Quartus II软件使用详细的步骤说明(3)
8.按照自己的想法,在新建的VHDL文件中编写VHDL程序。9.代码书写结束后,选择Processing>Start Compilation对编写的代码进行编译,直到编译通过。10.编译通过后,...
用户267451 2010-03-10 21:29
Quartus II软件使用详细的步骤说明(2)
5.按默认选项,点击【Next】出现新建工程以前所有的设定信息,如图2.1.6所示,点击Finish完成新建工程的建立,如图2.1.7所示。6.点击File>New,新建一个VHDL文件。如图2...
用户267451 2010-03-04 11:58
智能车 串口通信程序演示
一、 实验简介:本程序通过数码管,LED指示灯的闪亮来表示当前串口通信的结果,串口通信使单片机与电脑之间通信的桥梁,通过对它的学习,可以很好的用电脑来进行单片机的控制,及对单片机数据的采集。因此串口通...
用户267451 2010-02-28 21:54
智能车 红外遥控器解码程序演示
一、 实验简介:本程序主要将现在比较常用M50462遥控器进行解码,将解码后的数据通过P2端口的数码管显示出来,为了更好的看到运行过程,特加了三个指示灯用来指示当前运行状态。P10闪亮,表示程序正在运...
用户267451 2010-02-28 21:52
智能车 红外反射与直流电机驱动演示
一、 实验简介:本程序通过前端,底端的红外发射头和接收头来判断小车的运行轨迹,当前与底端发生信号输入时,信号将被单片机接收,单片机来控制机器按照写好的程序开始运行。同时为达到好的效果,加入声音识别与蜂...
EE直播间
更多
我要评论
1
5
关闭 站长推荐上一条 /3 下一条