求简易智能小车c51程序

简易智能小车——2003年全国大学生电子设计竞赛,谁有c51源程序啊?小弟急用!!

  系统的单片机程序

  #include "reg52.h"
  #define det_Dist 2.55 //单个脉冲对应的小车行走距离,其值为车轮周长/4
  #define RD 9 //小车对角轴长度
  #define PI 3.1415926
  #define ANG_90 90
  #define ANG_90_T 102
  #define ANG_180 189

  /*============================全局变量定义区============================*/
  sbit P10=P1^0; //控制继电器的开闭
  sbit P11=P1^1; //控制金属接近开关
  sbit P12=P1^2; //控制颜色传感器的开闭
  sbit P07=P0^7; //控制声光信号的开启
  sbit P26=P2^6; //接收颜色传感器的信号,白为0,黑为1
  sbit P24=P2^4; //左
  sbit P25=P2^5; //右 接收左右光传感器的信号,有光为0

  unsigned char mType=0; //设置运动的方式,0 向前 1 向左 2 向后 3 向右
  unsigned char Direction=0; //小车的即时朝向 0 朝上 1 朝左 2 朝下 3 朝右
  unsigned sX=50; unsigned char sY=0; //小车的相对右下角的坐标 CM(sX,sY)

  unsigned char StartTask=0; //获得铁片后开始执行返回卸货任务,StartTask置一
  unsigned char Inter_EX0=0; // 完成一个完整的任务期间只能有一次外部中断
  // Inter_EX0记录外部中断0的中断状态
  // 0 动作最近的前一次未中断过,
  // 1 动作最近的前一次中断过

  unsigned char cntIorn=0; //铁片数
  unsigned char bkAim=2; //回程目的地,0为A仓库,1为B仓库,2为停车场,
  //(在MAIN中接受铁片颜色判断传感器的信号来赋值)
  unsigned char Light_Flag=0;//进入光引导区的标志(1)

  unsigned int cntTime_5Min=0;//时间周期数,用于 T0 精确定时
  unsigned int cntTime_Plues=0; //霍尔开关产生的脉冲数
  /*============================全局变量定义区============================*/

  /*------------------------------------------------*/
  /*-----------------通用延迟程序-------------------*/
  /*------------------------------------------------*/

  void delay(unsigned int time) // time*0.5ms延时
  {
  unsigned int i,j;

  for(j=0;j<time;j++)
  {
  for(i=0;i<60;i++)
  {;}
  }
  }

  /*-----------------------------------------------*/
  /*-------------------显示控制模块----------------*/
  /*-----------------------------------------------*/

  /*数码管显示,显示铁片的数目(设接在P0,共阴)*/
  void Display(unsigned char n)
  {
  char Numb[12]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x37,0x77};

  P0=Numb[n];

  }

  /*-----------------------------------------------*/
  /*-------------------传感器模块------------------*/
  /*-----------------------------------------------*/

  /*光源检测程序: */
  /*用于纠正小车运行路线的正确性*/
  unsigned char LightSeek()
  { void Display(unsigned char);

  bit l,r;
  l=P24;
  r=P25;

  if(l==0&&r==1)
  {
  //Display(1);
  return (3); //偏左,向右开
  }
  if(r==0&&l==1)
  {
  //Display(3);
  return(1); //偏右,向左开

  }
  if((l==1&&r==1)||(l==0&&r==0))
  {//Display(9);
  return(0); //没有偏离,前进
  }

  }

  /*铁片检测程序: */
  /*判断铁片的颜色,设定bkAim,0为A仓库,1为B仓库,2为停车场*/
  void IornColor()
  {
  delay(4000);
  bkAim=(int)(P26);
  Display((int)(P26)+2);
  }

  /*-----------------------------------------------*/
  /*------------------运动控制模块-----------------*/
  /*-----------------------------------------------*/

  /*====基本动作层:完成基本运动动作的程序集====*/

  /*运动调整程序: */
  /*对小车的运动进行微调*/
  void ctrMotor_Adjust(unsigned char t)
  {
  if(t==0)
  {
  P2=P2&240|11; //用来解决两电机不对称的问题
  delay(6);
  }
  if(t==3)
  {
  P2=P2&250; //向左走
  delay(1);
  }
  if(t==1)
  {
  P2=(P2&245);
  delay(1); //向右走
  }

  P2=((P2&240)|15);
  delay(10);
  }

  /*直走程序: */
  /*控制小车运动距离,dist为运动距离(cm),type为运动方式(0 2)*/
  /*只改变小车sX 和 sY的值而不改变Direction的值. */
  void ctrMotor_Dist(float dist,unsigned char type)
  {unsigned char t=0;
  mType=type;
  P2=((P2&240)|15);
  cntTime_Plues=(int)(dist/det_Dist);

  while(cntTime_Plues)
  {
  if(Inter_EX0==1&&StartTask==0)
  {
  cntTime_Plues=0;
  break;
  }
  if(Light_Flag==1) t=LightSeek();

  if(type==0) //向前走
  {
  P2=P2&249;
  delay(40);
  ctrMotor_Adjust(t);
  }
  if(type==2) //向后退
  {
  P2=P2&246;
  delay(50);
  ctrMotor_Adjust(t);
  }

  P2=((P2&240)|15);
  if(mType==2) delay(60);//刹车制动 0.5ms
  else delay(75);
  }

  }

  /*拐弯程序: */
  /*控制小车运动角度,type为运动方式(1 3) */
  /*只改变小车Direction的值而不改变sX 和 sY的值*/
  void ctrMotor_Ang(unsigned char ang,unsigned char type,unsigned char dir)
  {
  unsigned char i=0;
  mType=type;
  P2=((P2&240)|15);
  cntTime_Plues=(int)((PI*RD*90/(180*det_Dist)*1.2)*ang/90);

  while(cntTime_Plues)
  {
  if(Inter_EX0==1&&StartTask==0)
  {
  cntTime_Plues=0;
  break;
  }
  if(type==1) //向左走
  {
  P2=P2&250;
  delay(100);
  ctrMotor_Adjust(0);
  }
  if(type==3) //向右走
  {
  P2=P2&245;
  delay(100);
  ctrMotor_Adjust(0);
  }

  P2=((P2&240)|15);
  delay(50);//刹车制动 0.5ms
  }
  if(!(Inter_EX0==1&&StartTask==0))
  {
  Direction=dir;
  }

  }

  /*====基本路线层:描述小车基本运动路线的程序集====*/

  /*当小车到达仓库或停车场时,放下铁片或停车(0,1为仓库,2为停车场)*/
  void rchPlace()
  {unsigned int time,b,s,g;

  time=(int)(cntTime_5Min*0.065535);//只有一个数码管时,轮流显示全过程秒数 个 十 百
  b=time%100;
  s=(time-b*100)%100;
  g=(time-b*100-s*10)%10;

  if(bkAim==2)
  {
  //到达停车场了,停车
  EA=0;
  P2=((P2&240)|15);
  while(1)
  {
  Display(10); //N
  delay(2000);
  Display(cntIorn);
  delay(2000);
  Display(11);//A
  delay(2000);
  Display(b);
  delay(2000);
  Display(s);
  delay(2000);
  Display(g);
  delay(2000);
  }
  }
  else
  {
  if(Inter_EX0==1&&StartTask==1)P10=0; //到达仓库,卸下铁片
  }

  }

  /*无任务模式: */
  /*设置小车的固定运动路线,未发现铁片时的运动路线*/
  void BasicRoute()
  { //Light_Flag=1;
  ctrMotor_Dist(153,0);
  //Light_Flag=0;
  ctrMotor_Ang(ANG_90,1,1);
  ctrMotor_Dist(100-sX,0);
  ctrMotor_Dist(125,2);
  ctrMotor_Dist(73,0);
  ctrMotor_Ang(ANG_90,1,2);
  //Light_Flag=1;
  ctrMotor_Dist(153,0);
  //Light_Flag=0;
  ctrMotor_Ang(ANG_180,1,0);
  rchPlace();

  }

  /*任务模式: */
  /*设置小车的发现铁片后的运动路线*/
  void TaskRoute()
  {
  //基本运行路线表,记载拐弯 0 向前 1 左拐 2 向后 3 右拐,正读去A区;反读去B区
  StartTask=1;

  ctrMotor_Ang(ANG_90_T,1,2);

  if(bkAim==1) //仓库A
  {
  ctrMotor_Dist(10,0);
  P2=((P2&240)|15);
  delay(60);
  ctrMotor_Ang(ANG_90_T,1,3);
  ctrMotor_Dist(100-sX,2);

  ctrMotor_Ang(ANG_90_T,1,2);
  Light_Flag=1;
  ctrMotor_Dist(153,2);
  Light_Flag=0;
  // ctrMotor_Ang(208,1,0);
  }
  else if(bkAim==0) //仓库B
  {
  ctrMotor_Dist(10,0);
  P2=((P2&240)|15);
  delay(60);
  ctrMotor_Ang(ANG_90_T,1,3);
  ctrMotor_Dist(100-sX,0);
  ctrMotor_Ang(ANG_90_T,1,0);
  Light_Flag=1;
  ctrMotor_Dist(153,2);
  Light_Flag=0;
  //ctrMotor_Ang(208,1,0);
  }

  delay(5000);

  rchPlace();

  }

  /*---------------------------------------------*/
  /*-------------------主程序段------------------*/
  /*---------------------------------------------*/
  void main()
  {
  delay(4000);

  P2=0xff; //初始化端口
  P07=0;
  P1=0;

  TMOD=0x01; //初始化定时器0/1 及其中断
  TL0=0;
  TH0=0;
  TR0=1;
  ET0=1;
  ET1=1;

  IT0=1; //初始化外部中断
  EX0=1;

  IT1=1;
  EX1=1;

  EA=1;
  P11=1;

  while(1)
  {
  Display(cntIorn);
  bkAim=2;

  BasicRoute();

  if(Inter_EX0==1)
  {
  TaskRoute();//按获得铁片后的路线运动
  IE0=0;
  EX0=1;
  }
  Inter_EX0=0;

  }
  }

  /*----------------------------------------------------*/
  /*----------------------中断程序段--------------------*/
  /*----------------------------------------------------*/

  /*定时器0中断程序: */
  /*当时间过了5分钟,则就地停车并进入休眠状态*/
  void tmOver(void) interrupt 1
  {
  cntTime_5Min++;
  TL0=0;
  TH0=0;

  if(cntTime_5Min>=4520)
  {
  Display(5);
  P2=((P2&240)|15);
  EA=0; //停车程序
  P07=1;
  delay(4000);
  PCON=0X00;
  while(1);
  }

  }

  /*外部中断0中断程序: */
  /*发现铁片,发出声光信号并将铁片吸起,发光二极管和蜂鸣器*/
  /*并联在一起(设接在P07). 0为A仓库,1为B仓库,2为停车场*/
  void fndIorn(void) interrupt 0
  {
  unsigned char i;

  P10=1;
  P2=((P2&240)|15); //停车
  P07=1;
  delay(1000);//刹车制动 0.5ms
  P07=0;

  Inter_EX0=1;

  cntIorn++;
  Display(cntIorn);

  for(i=0;i<40;i++)
  {
  P2=P2&249;
  delay(2);
  P2=((P2&240)|15);
  delay(2);
  }

  P2=P2&249;
  delay(100);
  P2=((P2&240)|15); //停车

  IornColor(); //判断铁片黑白,设置bkAim

  for(i=0;i<95;i++)
  {
  P2=P2&249;
  delay(3);
  P2=((P2&240)|15);
  delay(2);
  }
  P2=((P2&240)|15); //停车
  delay(4000); //把铁片吸起来
  EX0=0;

  }

  /*外部中断1中断程序: */
  /*对霍尔开关的脉冲记数,对小车的位置进行记录,以便对小车进行定位*/
  void stpMove(void) interrupt 2
  {
  cntTime_Plues--;

  if(Direction==0) //向上
  {
  if(mType==0) sY+=det_Dist;
  else if(mType==2)
  sY-=det_Dist;
  }
  else if(Direction==1) //向左
  {
  if(mType==0) sX+=det_Dist;
  else if(mType==2)
  sX-=det_Dist;
  }
  else if(Direction==2) //向下
  {
  if(mType==0) sY-=det_Dist;
  else if(mType==2)
  sY+=det_Dist;
  }
  else if(Direction==3) //向右
  {
  if(mType==0) sX-=det_Dist;
  else if(mType==2)
  sX+=det_Dist;
  }
  }
温馨提示:内容为网友见解,仅供参考
无其他回答
相似回答