📄 driver.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 + -