给女朋友调的循迹车。。。
/*
*******************************************************************************
* 文件名:main.c
* 描 述:寻迹小车
* 作 者:刘悦
* 版本号:v1.2
* 日 期: 2018年5月11日
* 备 注:注意了,所有的左右都是传感器位于自己前方看的!
*******************************************************************************
*/
#include <stc12.h>
//关于寻迹、蓝牙,取消哪个宏定义表示选择哪项模式
#define TRACE
#define BLUETOOTH
//电机引脚定义
sbit MotorRight_P = P1^0;//右电机正相
sbit MotorRight_N = P1^1;//右电机反相
sbit MotorLeft_P = P1^2;//左电机正相
sbit MotorLeft_N = P1^3;//左电机反相
//红外传感器检测引脚定义
//左右的序号分别从中间往两边开始1.2
sbit Left1 = P1^7;
sbit Left2 = P1^4;
sbit Right1 = P1^6;
sbit Right2 = P1^5;
//数据类型定义
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
//电机运动相关的宏定义
#define MotorLeft_Go() {MotorLeft_P =1; MotorLeft_N =0;}//左电机正转
#define MotorLeft_Back() {MotorLeft_P =0; MotorLeft_N =1;}//左电机反转
#define MotorLeft_Stop() {MotorLeft_P =0; MotorLeft_N =0;}//左电机停止
#define MotorRight_Go() {MotorRight_P=1; MotorRight_N=0;}//右电机正转
#define MotorRight_Back() {MotorRight_P=0; MotorRight_N=1;}//右电机反转
#define MotorRight_Stop() {MotorRight_P=0; MotorRight_N=0;}//右电机停止
//函数声明
void GoStaright();
void Back();
void TurnAdvanceLeft();
void TurnAdvanceRight();
void TurnNormalLeft();
void TurnNormalRight();
void Stop();
void Timer0Init(void);
void UartInit(void);
void main()
{
u8 TypeFlag=2; //左强拐-0 左普拐-1 直走-2 右普拐-3 右强拐-4
char ch;
EA = 1;
Timer0Init();
UartInit();
while(1)
{
//蓝牙模式
#ifdef BLUETOOTH//蓝牙
if(RI)
{
RI = 0;
ch = SBUF;
}
if(ch == 'g') GoStaright();
else if(ch == 'b') Back();
else if(ch == 'l') TurnNormalLeft();
else if(ch == 'r') TurnNormalRight();
// else Stop();
#endif
//寻迹模式
#ifdef TRACE
//另一种方案
else if((Left2==1)&&(Left1==1)&&(Right1==1)&&(Right2==1))
//if((Left2==1)&&(Left1==1)&&(Right1==1)&&(Right2==1))
{
TurnNormalRight();
TypeFlag = 3;
}
//直行
else if((Left2==0)&&(Left1==1)&&(Right1==1)&&(Right2==0))
{
GoStaright();
TypeFlag = 2;
}
else if((Left2==0)&&(Left1==0)&&(Right1==1)&&(Right2==0))
{
GoStaright();
TypeFlag = 2;
}
else if((Left2==0)&&(Left1==1)&&(Right1==0)&&(Right2==0))
{
GoStaright();
TypeFlag = 2;
}
//左转
else if((Left2==1)&&(Left1==1)&&(Right1==1)&&(Right2==0))
{
TurnAdvanceLeft();
TypeFlag = 0;
}
else if((Left2==1)&&(Left1==0)&&(Right1==0)&&(Right2==0))
{
TurnAdvanceLeft();
TypeFlag = 0;
}
else if((Left2==1)&&(Left1==1)&&(Right1==0)&&(Right2==0))
{
TurnNormalLeft();
TypeFlag = 1;
}
else if((Left2==1)&&(Left1==0)&&(Right1==1)&&(Right2==0))
{
TurnAdvanceLeft();
TypeFlag = 0;
}
//右转
else if((Left2==0)&&(Left1==1)&&(Right1==1)&&(Right2==1))
{
TurnAdvanceRight();
TypeFlag = 4;
}
else if((Left2==0)&&(Left1==0)&&(Right1==0)&&(Right2==1))
{
TurnAdvanceRight();
TypeFlag = 4;
}
else if((Left2==0)&&(Left1==1)&&(Right1==0)&&(Right2==1))
{
TurnAdvanceRight();
TypeFlag = 4;
}
else if((Left2==0)&&(Left1==0)&&(Right1==1)&&(Right2==1))
{
TurnNormalRight();
TypeFlag = 3;
}
//都没检测到时,为防止车抖动,可继续执行上次的动作
else if((Left2==0)&&(Left1==0)&&(Right1==0)&&(Right2==0))
{
if(TypeFlag == 0)
{
TurnAdvanceLeft();
}
else if(TypeFlag == 1)
{
TurnNormalLeft();
}
else if(TypeFlag == 2)
{
GoStaright();
}
else if(TypeFlag == 3)
{
TurnNormalRight();
}
else if(TypeFlag == 4)
{
TurnAdvanceRight();
}
}
//其余所有情况均直行
else
{
GoStaright();
}
#endif
}
}
void UartInit(void) //4800bps@12.000MHz
{
PCON |= 0x80; //使能波特率倍速位SMOD
SCON = 0x50; //8位数据,可变波特率
// AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T
// AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xF3; //设定定时初值
TH1 = 0xF3; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
}
void Timer0Init(void) //10微秒@12.000MHz
{
// AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0xF6; //设置定时初值
TH0 = 0xFF; //设置定时初值
TF0 = 0; //清除TF0标志
ET0 = 1; //关闭定时器0中断
TR0 = 1; //定时器0开始计时
}
void GoStaright()
{
static unsigned char Clck = 0;
u16 OutPWM_L=12,OutPWM_R=15;
TL0 = 0xF6; //设置定时初值
TH0 = 0xFF; //设置定时初值
if(Clck++ >= 100) Clck = 0;//100us +1 1ms清零一次
if(Clck<OutPWM_L)
{
MotorLeft_Go();
}
else
{
MotorLeft_Stop();
}
if(Clck<OutPWM_R)
{
MotorRight_Go();
}
else
{
MotorRight_Stop();
}
}
void Back()
{
static unsigned char Clck = 0;
u16 OutPWM_L=12,OutPWM_R=15;
TL0 = 0xF6; //设置定时初值
TH0 = 0xFF; //设置定时初值
if(Clck++ >= 100) Clck = 0;//100us +1 1ms清零一次
if(Clck<OutPWM_L)
{
MotorLeft_Back();
}
else
{
MotorLeft_Stop();
}
if(Clck<OutPWM_R)
{
MotorRight_Back();
}
else
{
MotorRight_Stop();
}
}
void TurnAdvanceRight()
{
static unsigned char Clck = 0;
u16 OutPWM_L=15,OutPWM_R=15;
TL0 = 0xF6; //设置定时初值
TH0 = 0xFF; //设置定时初值
if(Clck++ >= 100) Clck = 0;//100us +1 1ms清零一次
if(Clck<OutPWM_L)
{
MotorLeft_Go();
}
else
{
MotorLeft_Stop();
}
if(Clck<OutPWM_R)
{
MotorRight_Back();
}
else
{
MotorRight_Stop();
}
}
void TurnAdvanceLeft()
{
static unsigned char Clck = 0;
u16 OutPWM_L=15,OutPWM_R=15;
TL0 = 0xF6; //设置定时初值
TH0 = 0xFF; //设置定时初值
if(Clck++ >= 100) Clck = 0;//100us +1 1ms清零一次
if(Clck<OutPWM_L)
{
MotorLeft_Back();
}
else
{
MotorLeft_Stop();
}
if(Clck<OutPWM_R)
{
MotorRight_Go();
}
else
{
MotorRight_Stop();
}
}
void TurnNormalRight()
{
static unsigned char Clck = 0;
u16 OutPWM_L=15,OutPWM_R=15;
TL0 = 0xF6; //设置定时初值
TH0 = 0xFF; //设置定时初值
if(Clck++ >= 100) Clck = 0;//100us +1 1ms清零一次
if(Clck<OutPWM_L)
{
MotorLeft_Go();
}
else
{
MotorLeft_Stop();
}
MotorRight_Stop();
}
void TurnNormalLeft()
{
static unsigned char Clck = 0;
u16 OutPWM_L=15,OutPWM_R=15;
TL0 = 0xF6; //设置定时初值
TH0 = 0xFF; //设置定时初值
if(Clck++ >= 100) Clck = 0;//100us +1 1ms清零一次
MotorLeft_Stop();
if(Clck<OutPWM_R)
{
MotorRight_Go();
}
else
{
MotorRight_Stop();
}
}
void Stop()
{
MotorLeft_Stop();
MotorRight_Stop();
}