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

📄 driver.c

📁 全国电子设计大赛:智能电动车的设计.实现功能:以AT89C52单片机为核心
💻 C
字号:
//*************************************************************************************************
//  Module Name :  Driver.C
//  CreateDate  :  2005-05-14
//  ModifData   :  2005-07-18
//  Description :  
//  Author      :  李远正
//  Version     :  V3.0
//*************************************************************************************************
// 
#include <C8051F020.H> 
#include <intrins.h> 
#include <absacc.h> 
#include "Function.H"
#include "12C887.H"     // Save temporary data 
#include "WriteFile.H"  // Send data to USB devices
#include "Driver.H" 

//=================================================================================================
// Global VARIABLES 
//=================================================================================================
// 
#define STATE_FlagRight0     0x01      // 
#define STATE_FlagRight1     0x02      // 
#define STATE_FlagLeft0      0x03      // 
#define STATE_FlagLeft1      0x04      // 
#define STATE_FlagCenter     0x05      // 

//=================================================================================================
// 8位脉冲宽度调制 
void Forward ( unsigned char speed ) { PWM8( 1,0 ); PWM8( 0,speed ); forward  = 1; backward  = 0; }// 前进的速度 
void Backward( unsigned char speed ) { PWM8( 0,0 ); PWM8( 1,speed ); forward  = 0; backward  = 1; }// 后退的速度 
void CarStop( void ) { PWM8( 0,0 ); PWM8( 1,0 ); PWM8( 2,0 ); PWM8( 3,0 );}    // 停车 
void TurnRight( unsigned char speed ) { PWM8( 2,0 ); PWM8( 3,speed ); turnleft = 1; turnright = 0; }// 左拐弯 
void TurnLeft ( unsigned char speed ) { PWM8( 3,0 ); PWM8( 2,speed ); turnleft = 0; turnright = 1; }// 右拐弯 

//=================================================================================================
//							  	          中断程序
//=================================================================================================
// 计算路程 
// 
void Timer1_ISR( void ) interrupt 3
{
	
	if     ( forward  ) DistanceCount += 1;      // 1/6 of the loop 
	else if( backward ) DistanceCount -= 1;      // 1/6 of the loop 

    DISTANCE  = DistanceCount/6*LOOP;            // 距离校正 
	DISTANCE += DistanceCount%6*(LOOP/6); 
}

//=================================================================================================
//							  	          小车驱动程序
//=================================================================================================
// 
void CarDriver( void )
{
	unsigned char DISTANCE_H, DISTANCE_L; 
	unsigned char Parameter; 

	#define	MetalDistance_H    DISTANCE_H      // 节约两个变量单元 
	#define	MetalDistance_L    DISTANCE_L

	if( Start && Stop )           // 启动引导 
	{
	    Start = 1; Stop = 0;

		DistanceCount = 0; DISTANCE      = 0;
		SECTION = 'A';
		JourneyTime = 0;
		MetalNumber = 0; MetalDistance1 = 0; MetalDistance2 = 0; 
	}
    else if( Start && !Stop )     // Car start 
	{
		Parameter = LightRight; 

	    time_now = time_buf[0]%10;             // 秒钟计时 
		if( time_now ^ time_old ) JourneyTime++; // 行程计时 
		time_old = time_now; 

		//---------------------------------------------------------------------
		// 检测是否偏离轨道 
		if( !Center     ) Flag_Center     = 1; // 检测到中央光电 
		else              Flag_Center     = 0; 
		if( !LeftOver0  ) Flag_LeftOver0  = 1; // 检测到右边光电0 
		else              Flag_LeftOver0  = 0; 
		if( !LeftOver1  ) Flag_LeftOver1  = 1; // 检测到左边光电1 
		else              Flag_LeftOver1  = 0; 
		if( !RightOver0 ) Flag_RightOver0 = 1; // 检测到右边光电0 
		else              Flag_RightOver0 = 0; 
		if( !RightOver1 ) Flag_RightOver1 = 1; // 检测到右边光电1 
		else              Flag_RightOver1 = 0; 

		if( Barrier     ) Flag_Barrier    = 1; // 在 C 道区检测道前方有障碍物 
		else              Flag_Barrier    = 0;

		//---------------------------------------------------------------------
		// 保存最后一次的状态 
		if     ( Flag_LeftOver1  ) CarStatus = STATE_FlagLeft1;      // 优先 
		else if( Flag_RightOver1 ) CarStatus = STATE_FlagRight1;     // 
		else if( Flag_LeftOver0  ) CarStatus = STATE_FlagLeft0;      // 
		else if( Flag_RightOver0 ) CarStatus = STATE_FlagRight0;     // 
		else if( Flag_Center     ) CarStatus = STATE_FlagCenter;     // 

		//---------------------------------------------------------------------
		// 前进驱动 
		switch( SECTION )
		{
		    case  'A': // Start the car 
					   //----------------------------------
					   // 前进过程中检测到内侧光电,
					   // 相应操作:小转弯 
					   if( Flag_LeftOver0 | Flag_RightOver0 )
					   {
					       if( Flag_LeftOver0 )
						   {
						       turnleft = 1; turnright = 0; 
							   TurnLeft( SPEED ); 
						   }
						   else if( Flag_RightOver0 )
						   {
						       turnleft = 0; turnright = 1; 
							   TurnRight( SPEED ); 
						   }
					   }
					   // 前进过程中检测到外侧光电,
					   // 相应操作:大转弯 
					   else if(  Flag_LeftOver1 | Flag_RightOver1 )
					   {
					       if( Flag_LeftOver1 )
						   {
						       turnleft = 1; turnright = 0; 
							   TurnLeft( SPEED1 ); 
						   }
						   else if( Flag_RightOver1 )
						   {
						       turnleft = 0; turnright = 1; 
							   TurnRight( SPEED1 ); 
						   }
					   }
					   // 转弯到中央光电为止 
					   else if( Flag_Center )
					   {
					       PWM8( 2,0 ); PWM8( 3,0 );
					   }
					   //---------------------------------------------------------------------
		               // A 道区检测到金属片, 进行连续声光报警, 并记录金属片的位置  
		               if( (!Metal) && (!Flag_Metal) ) // 检测到金属片的起始点 
		               {
		                   Flag_Metal = 1;  // 检测到金属片在 SECTION A 

			               MetalNumber++;   // 记录金属片数目 
			               Write12C887RAM( IRON_NUMBER_RANGE, MetalNumber ); 

			               LED_OUT_ACT( );  // Enable LED 
			               ALARM_ACT( );    // Enable Alarm

			               MetalStartPoint = DISTANCE; // 记录金属片的起点位置 
		               }
		               else if( Metal && Flag_Metal )  // 检测到金属片的终点 
		               {
		                   Flag_Metal = 0;      // Reset for next cycle 

		                   LED_OUT_INACT( );    // Disable LED
			               ALARM_INACT( );      // Disable Alarm

			               MetalEndPoint = DISTANCE;   // 记录金属片的终点位置 
			               MetalEndPoint = (MetalEndPoint - MetalStartPoint)/2 + MetalStartPoint;  // 计算出金属片中点位置 
			               MetalDistance_H = ( unsigned char )_iror_( MetalEndPoint, 8 );  
			               MetalDistance_L = ( unsigned char )MetalEndPoint & 0xFF; 

			               switch( MetalNumber )       // 存储金属片的位置 
			               {
			                   case 1: Write12C887RAM( DISTANCE_RANGE_1_H, MetalDistance_H ); 
			                           Write12C887RAM( DISTANCE_RANGE_1_L, MetalDistance_L ); 
									   MetalDistance1 = MetalEndPoint; 
				                       break;
				               case 2: Write12C887RAM( DISTANCE_RANGE_2_H, MetalDistance_H ); 
			                           Write12C887RAM( DISTANCE_RANGE_2_L, MetalDistance_L ); 
									   MetalDistance2 = MetalEndPoint; 
				                       break;
				               case 3: Write12C887RAM( DISTANCE_RANGE_3_H, MetalDistance_H ); 
			                           Write12C887RAM( DISTANCE_RANGE_3_L, MetalDistance_L ); 
				                       break;
				               default:break; 
			               }
		               }
					   //----------------------------------
					   // 准备进入 B 道区 
					   if( DISTANCE > SECTION_BPoint ) 
					   {
					       SECTION = 'B'; 
						   TimeBPoint = JourneyTime; 
					   }

			           break;
			case  'B': //---------------------------------------------------------------------
			           if( !B_SECTION ) // 刚进入 B 区,先向左转预准备 
					   {
					       B_SECTION = 1; 
					       TurnLeft( 250 ); 
					   }
					   //----------------------------------
					   // 前进过程中检测到内侧光电,
					   // 相应操作:小转弯 
					   if( Flag_LeftOver0 | Flag_RightOver0 )
					   {
					       if( Flag_LeftOver0 )
						   {
						       turnleft = 1; turnright = 0; 
							   TurnLeft( SPEED ); 
						   }
						   else if( Flag_RightOver0 )
						   {
						       turnleft = 0; turnright = 1; 
							   TurnRight( SPEED ); 
						   }
					   }
					   // 前进过程中检测到外侧光电,
					   // 相应操作:大转弯 
					   else if(  Flag_LeftOver1 | Flag_RightOver1 )
					   {
					       if( Flag_LeftOver1 )
						   {
						       turnleft = 1; turnright = 0; 
							   TurnLeft( SPEED1 ); 
						   }
						   else if( Flag_RightOver1 )
						   {
						       turnleft = 0; turnright = 1; 
							   TurnRight( SPEED1 - 20 ); 
						   }
					   }
					   // 转弯到中央光电为止 
					   else if( Flag_Center )
					   {
					       if( DISTANCE < SECTION_BCPoint )
						   {
					           PWM8( 2,0 ); PWM8( 3,0 );
						   }
					   }
					   //----------------------------------
					   // For test ... 
					   // 当没有检测到黑线的时候的处理 
					   if( (!Flag_LeftOver0) | (!Flag_LeftOver1) | (!Flag_RightOver0) | (!Flag_RightOver1) | (!Flag_Center) )
					   {
					       switch( CarStatus )
						   {
						       case STATE_FlagLeft0 : TurnLeft( SPEED1 ); break; 
							   case STATE_FlagLeft1 : TurnLeft( 250 );    break; 
							   case STATE_FlagRight0: if( DISTANCE < SECTION_BCPoint ) TurnRight( SPEED - 20 );
							                          else if( DISTANCE > SECTION_BCPoint )
													  {
													      PWM8( 2,0 ); PWM8( 3,0 );
														  TurnLeft( SPEED - 50 );
													  }   
													  break; 
							   case STATE_FlagRight1: if( DISTANCE < SECTION_BCPoint ) TurnRight( SPEED - 20 );
							                          else if( DISTANCE > SECTION_BCPoint )
													  {
													      PWM8( 2,0 ); PWM8( 3,0 );
														  TurnLeft( SPEED - 50 );
													  } 
													  break; 
							   case STATE_FlagCenter: 
							                          if( DISTANCE < SECTION_BCPoint )
													  {
													      PWM8( 2,0 ); PWM8( 3,0 );
													  }
							                          break; 

							   default: break;
						   }
					   }
					   //---------------------------------------------------------------------
		               // B 道区检测到金属片, 进入 C 道区 
		               if( (!Metal) && (!Flag_Metal) ) // 检测到金属片的起始点 
		               {
					       SECTION = 'C'; 
						   SECTION_CPoint = DISTANCE;  // 记录 C 点位置 

						   SetSQW( 15 );         // 2 Hz 
						   LED_GLITTER_ACT( );   // LED 闪烁控制 
						   ALARM_ACT( );         // Enable Alarm 
						   TimeCPoint = JourneyTime; 

						   forward = backward = turnright = turnleft = 0;
						   Flag_LeftOver0 = Flag_RightOver0 = 0;
						   CarStop( ); 
					   }
			           break;
			case  'C': //---------------------------------------------------------------------
		               // 计算在 C 道区内所走的路程 
					   DISTANCE_C = DISTANCE - SECTION_CPoint;  
					   
					   //---------------------------------------------------------------------
		               // 在 C 点停车 5 秒,并进行断续的声光信息 , TimeCPoint;
					   if( (JourneyTime - TimeCPoint) > 4 )
					   {
					       LED_GLITTER_INACT( ); // Disable LED 
					       ALARM_INACT( );       // Disable Alarm   Flag_CArea

						   if( DISTANCE_C < 10 ) // 引导小程序 
						   {
						       TurnLeft( 250 ); 
						       Forward ( SPEED ); 
						   }

						   //----------------------------------------
						   // 分段进行控制 
						   // 段 1 
						   else if( DISTANCE_C < 800 )
						   {
						       if( LightRight > 80 ) Flag_CArea = 1;
							   if( Flag_CArea ) 
							      if( (LightLeft < 30) && ( LightCenter < 20 ) )
								  {
								      Flag_CArea = 0;
									  TurnRight( SPEED1 - 30 ); 
									  Forward ( SPEED - 5 );    // Slow down 
								  }
						   }
						   // 段 2 
						   else if( DISTANCE_C < 10000 )
						   {
						       if( LightLeft > LightRight ) 
							   {
							       temp = LightLeft - LightRight; 
								   TurnLeft( temp * 3 ); 
							   }
						       else if( LightLeft < LightRight  )
   							   {
							       temp = LightRight - LightLeft;
								   TurnRight( temp * 3 ); 
							   }
							   if( DISTANCE_C > 3100 )
							   {
							       Start = 0; Stop = 0;
								   forward = backward = turnright = turnleft = 0;
								   Flag_LeftOver0 = Flag_RightOver0 = 0;
								   CarStop( ); 

								   SECTION = 'D';
							   }
						   }
					   }

			           break;
			default:   break;
		}

		
		//---------------------------------------------------------------------
		// 行驶时间达到 90 秒自动停车 
		if( JourneyTime > 90 )     
		{
		    Start = 0; Stop = 0;
			forward = backward = turnright = turnleft = 0;
			Flag_LeftOver0 = Flag_RightOver0 = 0;
			CarStop( ); 
		}
	}
	else if( !Start && !Stop )  // Car stop 
	{
		    Stop = 1;       
			CarStop( ); 

			B_SECTION = 0;                                       // Reset for next journey 
			SECTION   = 'A'; 

			SetSQW( 0 );    // None Hz 

			Flag_Metal  = 0;

			DISTANCE_H = ( unsigned char )_iror_( DISTANCE, 8 ); // 存储路程长度 
			DISTANCE_L = ( unsigned char )DISTANCE & 0xFF;
			Write12C887RAM( DISTANCE_RANGE_H,DISTANCE_H );
			Write12C887RAM( DISTANCE_RANGE_L,DISTANCE_L );

			Write12C887RAM( JOURNEY_TIME_RANGE, JourneyTime );   // 存储时间长度 
	}

	//---------------------------------------------------------------------
	// Write file to USB device 
	// Detect the connect of USB 
	if( (mIntStatus == ERR_USB_CONNECT) && !Write )  // USB connected ,but have not writed file to it 
	{
	    Write  = 1; 
		FileProcess( );
	}
	else if ( (mIntStatus == ERR_DISK_DISCON) && Write ) 
	{
	    Write  = 0;   // Reset for next time 
	}

	//---------------------------------------------------------------------
	// 
}



⌨️ 快捷键说明

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