⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 car.c

📁 这是我上次参加电子设计大赛的小车程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//#include<AT89x51hyq.h>
#include <reg52.h>
#include<intrins.h>

#define uchar unsigned char 
#define uint unsigned int 

#define DsDat P1_4  //显示数据
#define DsClk P1_5   //送数时钟
#define cd    P3_7  /*菜单位*/
#define qw    P1_3  /*字千位*/
#define bw    P1_2  /*字百位*/
#define sw    P1_1  /*字十位*/
#define gw    P1_0  /*字个位*/

#define hi0 0xce    //定时50us
#define lo0 0xce

#define hi1 0x3c    //定时50ms
#define lo1 0xb0

#define m1p P0_0       //电机左的PWM
#define m11 P0_1       //P0_1=1,P0_2=0电机正转;
#define m12 P0_2       //P0_1=0,P0_2=1电机反转;
#define m2p P0_3       //电机右的PWM
#define m21 P0_4       //P0_4=1,P0_5=0电机正转;
#define m22 P0_5       //P0_4=0,P0_5=1电机正转;
#define alarm P0_6     // P06=1报警;
#define key_en P0_7    //高电平时,封锁车轮脉冲,以免影响按键。
#define pian_L P2_0    //为1时偏左;
#define pian_R P2_1     //为1时偏右;
#define have_tie P2_2    //低电平时有铁; 
#define have_ai P2_3      //低电平时有障碍物; 
#define wheel_Pulse P3_3   //车轮脉冲;
#define light_L P2_5 
#define light_ok P2_4
#define light_R P2_6
#define light P2_7
#define ON_TIME 20
//////////////////////定义全局变量
uchar code ledk[27]={0x3F,0x06,0x5B,0x4F,0x66,0x6D, //0,1,2,3,4,5      
                         0x7D,0x07,0x7F,0x6F,0x77,0x7C, //6,7,8,9,A,B
						 0x39,0x5E,0x79,0x71,0x3d,0x76, //C(12),D,E,F,G(16),H(17),
                         0x38,0x5c,0x73,0x67,0x78,0x3e, //L(18),o(19),P(20),q(21),t(22),U(23),
						 0x6e,0x40,0x00};                //Y(24),-(25)," "(26)    

uchar disp[5]={9,0,0,0,0};



bit on_off=0,workmode;
long int  T1_count=0;
uchar T0_count=0,dis_count=0;
uchar speed1,speed2;
uchar whichset;
uint path_c;
uint s0;
uchar runmode;
uchar sp_c;
uchar spset;
uchar tie_num;
uint *p_array;      //用来指向array[6]的指针;
uint array[6];  //保存铁片的中心距离的数组;
bit tie_flag;
uchar led_no;


/////////////////////  定义小车运行模式
#define track_check 1
#define half_circle 2
#define bi_zheng 3
#define light_track 4
#define finish 5
//////////////////////////////////
void stop(uchar r);
void zc(uchar r);
void fc(uchar r);
void start(uchar r,uchar spset,bit zf);
void display();
void send(uchar sdata,uchar wei);
void fon_off(bit b,uchar wei);
void send_one(uchar cdata);
void delay(uchar time);
bit bittest(uchar cdata,uchar nbit);
uchar DecToHex();
uchar key();
void finishcacu();
void FTrack_check();
void Ftie_check();
void FHalf_circle();
void FBi_zheng();
void FLight_track();
void Ffinish();
void  HexToDec(uint xx);
main()
{ uchar i;
  TMOD=0x12;        //T0是定时器0方式2,8位自动装载;T1是定时器1方式1,16位计数;
  ET0=1;
  ET1=1;
  EX0=1;
  EA=1;
  PT1=1;
  s0=0;
  stop(0);
  stop(1);
  key_en=1;
  alarm=1;
  spset=120;
  sp_c=100;
  path_c=1000;    
  while(1)
   {
     display();
     switch(key())
      {
       case 1:                           //设置位;
              workmode=1;
              if(++whichset>4)
                  whichset=0;
              break;
      case 2:if(workmode==1)                //改数;
               if(++disp[whichset]>9)
                   disp[whichset]=0;
             break;

      case 3: workmode=0;
              switch(disp[0])
               {
                case 0:spset=DecToHex();break;        //速度初置设置;
                case 1:sp_c=DecToHex();break;        //速度差置设置;
                case 2:path_c=DecToHex();break;       //第二状态转换设置;
                case 9:
                       for(i=0;i<2;i++)               //起动鸣笛;
                        {
                          alarm=0;
                          display();
                        }
                       for(i=0;i<2;i++)               //关笛; 
                         {
                          alarm=1;
                          display();
                         }
                       for(i=0;i<200;i++)               //起动鸣笛;
                         {
                          alarm=0;
                          display();
                         } 
   					   alarm=1;  //关笛;准备开车
					   for(i=0;i<6;i++) //清参数数组
						 {
						   array[i]=0;
						 }
                       TR0=1;
                       TR1=1;
                       TH0=hi0;
                       TL0=lo0;
                       TH1=hi1;
                       TL1=lo1;
					   IT1=1;     //下降沿触发;
					   EX1=1;     //允许车轮记数
					   key_en=0;   //允许车轮脉冲
                       p_array=array;
                       start(0,spset,1);  
                       start(1,spset,1);
                       runmode=track_check; //预置运行模式为黑线跟踪             
                       while(1)   //进入运行的主循环
						{
						   switch(runmode)
                           {
                            case 1:FTrack_check();break;//黑线跟踪
                            case 2:FHalf_circle();break;//半圆跟踪
                            case 3:FBi_zheng();   break;//避障碍
                            case 4:FLight_track();break;//光跟踪入库
                            case 5:Ffinish();     break;//完成,显示参数
                            default :break;    
                            } 
                           disp[0]=runmode;//显示运行模式
  						   if(T1_count>1800)  //时间大于90秒则自动停车
						   {
							stop(0);
							stop(1);
							key_en=1;
						    TR0=0;
							TR1=0;
							EX0=0;
							runmode=finish;//运行到完成工序
						   }
						   display();
						}  //while(1)运行的主循环结束
					   break;  //内环case 9
                  }  //switch(disp[0])结束
			 break;    //外环Case 3确定键
			 default:break;		 
           }  //switch(key())
    
      }  //while(1) 

}
////////////////黑线跟踪函数//////////////////////////////////////////
void FTrack_check()  
{
  switch(P2&0x03)
   {  
    case 0x01:
                start(0,spset+sp_c,1);       //偏右;
                start(1,spset-sp_c,1);
                break;
    case 0x02:
                start(0,spset-sp_c,1);       //偏左;
                start(1,spset+sp_c,1);
                break;
      
    default:
               start(0,spset+sp_c,1);       //正位;
               start(1,spset+sp_c,1);
               break;
    }
   Ftie_check();//检测铁片
   P0_6=!tie_flag;  //检测到铁片时,"嘀"一声响
   if(s0>path_c) runmode=half_circle; //判断运行距离小车已驶出有铁片的直线段,
                                      //将运行模式转成半圆运行方式 
}
////////////检测铁片函数/////////////////////////////////////
void Ftie_check()
{  uchar temp;
  if(tie_flag)          //有铁片标志1
    {  if(have_tie==1)  //等到小车运行过铁片的尾端后
       {
          *p_array++=s0;   //把铁片的尾端运行距离数写入数组
           tie_flag=0;     //有铁片标志复位
           temp=(*(p_array-2)+*(p_array-1))/2;  //计算铁片中心离起点的距离
           HexToDec((temp*33)/100);    //转换成十进制
         }
		 return ;    
	 }
   else if(have_tie==0&&tie_num<3)    //若检测到铁片始端且铁片数量小于3片则
        {
           tie_num++;                 //铁片数加1
          *p_array++=s0;              //且把运行距离数写入数组,并把数级指针加1
           tie_flag=1;                //铁片标志置1
		   
        }
}           
//////////半圆跟踪//////////////////////////////////
void FHalf_circle()
{ uint temp;
    switch(P2&0x03)
   {  
    case 0x01:
                start(0,spset+sp_c,1);       //偏右;
                start(1,spset-sp_c,1);
                break;
    case 0x02:
                start(0,spset-sp_c,1);       //偏左;
                start(1,spset+sp_c,1);
                break;
      
    default:
               start(0,spset+sp_c,1);       //正位;
               start(1,spset+sp_c,1);
               break;
    }
  if(have_tie==0)  //若检测到铁片
    {
       stop(0);    //则停车
       stop(1);
       temp=T1_count;  //把现行时间先记录到Temp,T1_count在运行后每50mS自动加1(中断程序中执行)
       while(T1_count-temp<100)  //停车5S
        {
        HexToDec(s0);
        switch((T1_count-temp)/10) //每隔1S响一声喇叭
           {
             case 0:alarm=0;break; 
             case 1:alarm=1;break;
             case 2:alarm=0;break;
             case 3:alarm=1;break;
             case 4:alarm=0;break;
             case 5:alarm=1;break;
             case 6:alarm=0;break;
             case 7:alarm=1;break;   
             case 8,9:alarm=0;break;
            }
             display();
          }
           alarm=1;           //关喇叭
           start(0,spset+50,1);  //左转运行,修正车方向     
           start(1,spset-50,1);
           temp=T1_count;
         while(T1_count-temp<20) ////左转运行1S
            {
              display();   
            }
           runmode=bi_zheng;  //把运行方式转成避障模式  
           start(0,spset+sp_c,1);  //直行     
           start(1,spset+sp_c,1);
          
     }
}

//////////避障碍函数////////////////////////////////
void FBi_zheng()
{ uchar i;
  if(have_ai==0)  //若前有障碍物则
     {
        stop(1);  //左转
        while(have_ai==0)  //左转直到障碍物消失
           {
             display();
           } 
         for(i=0;i<200;i++)  //障碍物消失后再转一会,确保运行方向与障碍物平行
              {
                display(); 
               }
          start(0,spset+sp_c,1); //直行      
          start(1,spset+sp_c,1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -