智能循迹小车C程序完美详尽
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
mid3 =m1; //黑线位置
right4=m0;
right5=m0;
TMOD|=0x01;
TH0=(65536-66)/256;
TL0=(65536-66)%256;
EA=1;
ET0=1;
TR0=1;
ENA=1; //使能端口,初始化
ENB=1;
}
//--------------------------------------------
/*------------------------------------------------------
-----------------------小车运行主程序-------------------
--------------------------------------------------------
#define m1 0
#define full_speed_left 40 //方便调节各个状态的占空比 ,可用参数组:(30,35,6,25,30,68000,27000,500);
#define full_speed_right 45//(40,45,6,25,30,68000,27000,500);
--------------------------------------------------------*/
#include<STC12C5A60S2.h>
#define uchar unsigned char
#define uint unsigned int
#define m0 1//黑线m1,白线m0
{
Duty_left =correct_speed;
Duty_right=full_speed_right;
IN1=1;
IN2=0;
IN3=1;
IN4=0;
}
//------------------------------------------------
void correct_right()//向右校正,赋值
{
if(right5==m1)
{
line_right();
goto label2;
}
}
delay(check_right);//左边遇到黑线时,左边出了黑线之后,继续延时一段时间,判断右边是否遇到黑线,
//若遇到黑线,执行line_right()函数
if(right5==m1)
{
line_right();
goto label3;
}
else if(left1==m1)
{line_left();
goto label3;}
}
else
if(right4==m1)//防止校正时,小车冲出过大,导致2,4号检测管屏蔽了两端检测管的检测,避免其走直线时出轨
while(right4==m1)
{correct_right();
sbit mid3 =P1^4;
sbit right4=P1^3;
sbit right5=P1^2;
void line_left();
void line_right();
void line_straight()reentrant;
//----------------------------------------
void straight()//直走,赋值
{
Duty_left =full_speed_left;//左右电机占空比初始化,调节直线运动速度
Duty_right=full_speed_right;//鉴于左右轮电机内部阻力不同,故占空比取不同值,这组值需要单独写程序取值
IN1=1;
IN2=0;
IN3=1;
简介:@模块组成:红外对管检测模块----五组对管,五个信号采集端口
直流电机驱动模块----驱动两个直流电机,另一个轮子用万向轮
单片机最小系统------用于烧写程序,控制智能小车运动
@功能简介:在白色地面或皮质上用黑色胶带粘贴出路线路径宽度微大于相邻检测管间距。
这样小车便可在其上循迹运行。
@补充说明:该程序采取“右优先”的原则:
TH0=(65536-66)/256;//取约150HZ,12M晶振,每次定时66us,分100次,这样开头定义的变量正好直接表示占空比的数值
TL0=(65536-66)%256;
}
//-----------------------------------------------
void correct_left()//向左校正,赋值
{
straight();
//delay(lenth);
while(right4==m0) //本来应该是用mid3,但是为了提高灵敏度,选择right4;向左时,可取left2对管
{turn_right();}
if(mid3==m1)
{line_straight();}
}
label3: ; //什么都不做
{
Duty_left =full_speed_left;
Duty_right=correct_speed;
IN1=1;
IN2=0;
IN3=1;
IN4=0;
}
//--------------------------------------------------
void turn_left()//左转,赋值
}
//-------------------------------------------------------------------------
void line_right() //右边有黑线时
{
straight();//这里的直走是在不管红外检测结果的直行
delay(lenth);
if(mid3==m1)
{
Duty_left =turn_speed_left;
Duty_right=turn_speed_right;
IN1=0;//转弯时一个正转,一个反转,
IN2=1;
IN3=1;
IN4=0;
}
//---------------------------------------------------
void turn_right()//右转,赋值
while(right4==m0)
{}
if(midr==m1)
{line_straight();}
}
}
//-----------------------------------------------------------------
void line_left() //左边出现黑线时
{
while(left1==m1)
goto label2;
}
if((mid3==m1)||(left2==m1)||(right4==m1)){line_straight();}
else
{
while(left2==m0)
{turn_left();}
if(midl==m1)
IN4=0;
}
//-----------------------------------------------------
void line_straight()reentrant //函数名后加reentrant可以递归调用,//一直走黑直线时
{
straight();
if(right5==m1){line_right();}
#define width 27000//500--》10-->2000--》60000--30000---》27000
#define check_right 500 //2000--》20--》200--》500
#define midl left1
#define midr right5
uchar Duty_left,Duty_right,i=0,j=0; //左右占空比标志,取1--100
sbit IN1=P2^0;
sbit IN2=P2^1;
sbit IN3=P2^2;
sbit IN4=P2^3;
sbit ENA=P1^0;
sbit ENB=P1^1;
//循迹口 五组红外对管,依次对应从左往右第1,2,3,4,5五组
sbit left1 =P1^6;
sbit left2 =P1^5;
2.假定:遇到白线输出0,遇到黑线输出1;
如果实际电路是:遇到白线输出1,遇到黑线输出0,
这种情况下只需要将第四,第五句改成:
#define m0 1
#define m1 0
即可。
3.说明1:直行---------------速度full_speed_left,full_speed_right.
转弯,调头速度------correct_speed_left,correct_speed_right.
else
if(left1==m1){line_left();}
else
if(left2==m1)//防止校正时,小车冲出过大,导致2,4号检测管屏蔽了两端检测管的检测,避免其走直线时出轨
while(left2==m1)
{correct_left();
if(right5==m1)
{
line_right();
#define correct_speed 6 //校正时的低速轮的占空比
#define turn_speed_left 25
#define turn_speed_right 30
#definelenth 68000//测试数据:10000--》100--》500--》2000--80000--76000--68000
即右边有黑线向右转,
若无,前方有黑线,向前走,
若无,左边有黑线,向左转,
若全无,从右方向后转。
程序开头定义的变量的取值是根据我的小车所调试选择好的,
如果采用本程序,请自行调试适合自己小车的合适参数值。
编者:陈尧,黄永刚(江苏大学电气学院二年级,三年级)
1.假定:IN1=1,IN3=1时电机正向转动,必须保证本条件
微小校正时---------高速轮full_speed_left,full_speed_right;
低速轮correct_speed.
可以通过调节第六,七,八,九,十条程序,改变各个状态
下的占空比(Duty cycle ),以求达到合适的转弯,直行速度
4.lenth----------length检测到黑线到启动转动的时间间隔
void delay(long int Delay_time)//延时函数
{
uint t=Delay_time;
while(t--);
}
//-----------------------------------------
void init()//定时器初始化
{
left1=m0; //初始化
left2=m0; //白线位置
if(right5==m1)
{ line_right(); goto label3;}
else if(left1==m1)
{line_left();goto label3;}
}
else
if((left1==m0)&&(left2==m0)&&(mid3==m0)&&(right4==m0)&&(right5==m0))
{
turn_right();//执行向右转的赋值
label:delay(width);//由width值决定转弯时mid3经过黑线宽度时所需要的时间
if(mid3==m0)
while(right4==m0)
{}
else
goto label;
}
Байду номын сангаасelse
if(mid3==m0)
{
turn_right();
5.width----------mid3在黑线上到脱离黑线的时间差
6.mid3-----------作为判断中心位置是否进入黑线的标志,由于运行的粗糙性和惯性,
常取其他对管的输出信号作为判断条件
7.check_right----若先检测到左边黑线,并且左边已出黑线,判断右端是否压黑线时间拖延
--------------------------------------------------------
{
Duty_left =turn_speed_left;
Duty_right=turn_speed_right;
IN1=1;//转弯时一个正转,一个反转,
IN2=0;
IN3=0;
IN4=1;
}
//-----------------------------------------------------
void time0(void)interrupt 1//中断程序
{
i++;//调速在中断中执行
j++;
if(i<=Duty_left)
ENA=1;
else ENA=0;
if(i>100)
{ENA=1;i=0;}
if(j<=Duty_right)
ENB=1;
else ENB=0;
if(j>100)
{ENB=1;j=0;}
right4=m0;
right5=m0;
TMOD|=0x01;
TH0=(65536-66)/256;
TL0=(65536-66)%256;
EA=1;
ET0=1;
TR0=1;
ENA=1; //使能端口,初始化
ENB=1;
}
//--------------------------------------------
/*------------------------------------------------------
-----------------------小车运行主程序-------------------
--------------------------------------------------------
#define m1 0
#define full_speed_left 40 //方便调节各个状态的占空比 ,可用参数组:(30,35,6,25,30,68000,27000,500);
#define full_speed_right 45//(40,45,6,25,30,68000,27000,500);
--------------------------------------------------------*/
#include<STC12C5A60S2.h>
#define uchar unsigned char
#define uint unsigned int
#define m0 1//黑线m1,白线m0
{
Duty_left =correct_speed;
Duty_right=full_speed_right;
IN1=1;
IN2=0;
IN3=1;
IN4=0;
}
//------------------------------------------------
void correct_right()//向右校正,赋值
{
if(right5==m1)
{
line_right();
goto label2;
}
}
delay(check_right);//左边遇到黑线时,左边出了黑线之后,继续延时一段时间,判断右边是否遇到黑线,
//若遇到黑线,执行line_right()函数
if(right5==m1)
{
line_right();
goto label3;
}
else if(left1==m1)
{line_left();
goto label3;}
}
else
if(right4==m1)//防止校正时,小车冲出过大,导致2,4号检测管屏蔽了两端检测管的检测,避免其走直线时出轨
while(right4==m1)
{correct_right();
sbit mid3 =P1^4;
sbit right4=P1^3;
sbit right5=P1^2;
void line_left();
void line_right();
void line_straight()reentrant;
//----------------------------------------
void straight()//直走,赋值
{
Duty_left =full_speed_left;//左右电机占空比初始化,调节直线运动速度
Duty_right=full_speed_right;//鉴于左右轮电机内部阻力不同,故占空比取不同值,这组值需要单独写程序取值
IN1=1;
IN2=0;
IN3=1;
简介:@模块组成:红外对管检测模块----五组对管,五个信号采集端口
直流电机驱动模块----驱动两个直流电机,另一个轮子用万向轮
单片机最小系统------用于烧写程序,控制智能小车运动
@功能简介:在白色地面或皮质上用黑色胶带粘贴出路线路径宽度微大于相邻检测管间距。
这样小车便可在其上循迹运行。
@补充说明:该程序采取“右优先”的原则:
TH0=(65536-66)/256;//取约150HZ,12M晶振,每次定时66us,分100次,这样开头定义的变量正好直接表示占空比的数值
TL0=(65536-66)%256;
}
//-----------------------------------------------
void correct_left()//向左校正,赋值
{
straight();
//delay(lenth);
while(right4==m0) //本来应该是用mid3,但是为了提高灵敏度,选择right4;向左时,可取left2对管
{turn_right();}
if(mid3==m1)
{line_straight();}
}
label3: ; //什么都不做
{
Duty_left =full_speed_left;
Duty_right=correct_speed;
IN1=1;
IN2=0;
IN3=1;
IN4=0;
}
//--------------------------------------------------
void turn_left()//左转,赋值
}
//-------------------------------------------------------------------------
void line_right() //右边有黑线时
{
straight();//这里的直走是在不管红外检测结果的直行
delay(lenth);
if(mid3==m1)
{
Duty_left =turn_speed_left;
Duty_right=turn_speed_right;
IN1=0;//转弯时一个正转,一个反转,
IN2=1;
IN3=1;
IN4=0;
}
//---------------------------------------------------
void turn_right()//右转,赋值
while(right4==m0)
{}
if(midr==m1)
{line_straight();}
}
}
//-----------------------------------------------------------------
void line_left() //左边出现黑线时
{
while(left1==m1)
goto label2;
}
if((mid3==m1)||(left2==m1)||(right4==m1)){line_straight();}
else
{
while(left2==m0)
{turn_left();}
if(midl==m1)
IN4=0;
}
//-----------------------------------------------------
void line_straight()reentrant //函数名后加reentrant可以递归调用,//一直走黑直线时
{
straight();
if(right5==m1){line_right();}
#define width 27000//500--》10-->2000--》60000--30000---》27000
#define check_right 500 //2000--》20--》200--》500
#define midl left1
#define midr right5
uchar Duty_left,Duty_right,i=0,j=0; //左右占空比标志,取1--100
sbit IN1=P2^0;
sbit IN2=P2^1;
sbit IN3=P2^2;
sbit IN4=P2^3;
sbit ENA=P1^0;
sbit ENB=P1^1;
//循迹口 五组红外对管,依次对应从左往右第1,2,3,4,5五组
sbit left1 =P1^6;
sbit left2 =P1^5;
2.假定:遇到白线输出0,遇到黑线输出1;
如果实际电路是:遇到白线输出1,遇到黑线输出0,
这种情况下只需要将第四,第五句改成:
#define m0 1
#define m1 0
即可。
3.说明1:直行---------------速度full_speed_left,full_speed_right.
转弯,调头速度------correct_speed_left,correct_speed_right.
else
if(left1==m1){line_left();}
else
if(left2==m1)//防止校正时,小车冲出过大,导致2,4号检测管屏蔽了两端检测管的检测,避免其走直线时出轨
while(left2==m1)
{correct_left();
if(right5==m1)
{
line_right();
#define correct_speed 6 //校正时的低速轮的占空比
#define turn_speed_left 25
#define turn_speed_right 30
#definelenth 68000//测试数据:10000--》100--》500--》2000--80000--76000--68000
即右边有黑线向右转,
若无,前方有黑线,向前走,
若无,左边有黑线,向左转,
若全无,从右方向后转。
程序开头定义的变量的取值是根据我的小车所调试选择好的,
如果采用本程序,请自行调试适合自己小车的合适参数值。
编者:陈尧,黄永刚(江苏大学电气学院二年级,三年级)
1.假定:IN1=1,IN3=1时电机正向转动,必须保证本条件
微小校正时---------高速轮full_speed_left,full_speed_right;
低速轮correct_speed.
可以通过调节第六,七,八,九,十条程序,改变各个状态
下的占空比(Duty cycle ),以求达到合适的转弯,直行速度
4.lenth----------length检测到黑线到启动转动的时间间隔
void delay(long int Delay_time)//延时函数
{
uint t=Delay_time;
while(t--);
}
//-----------------------------------------
void init()//定时器初始化
{
left1=m0; //初始化
left2=m0; //白线位置
if(right5==m1)
{ line_right(); goto label3;}
else if(left1==m1)
{line_left();goto label3;}
}
else
if((left1==m0)&&(left2==m0)&&(mid3==m0)&&(right4==m0)&&(right5==m0))
{
turn_right();//执行向右转的赋值
label:delay(width);//由width值决定转弯时mid3经过黑线宽度时所需要的时间
if(mid3==m0)
while(right4==m0)
{}
else
goto label;
}
Байду номын сангаасelse
if(mid3==m0)
{
turn_right();
5.width----------mid3在黑线上到脱离黑线的时间差
6.mid3-----------作为判断中心位置是否进入黑线的标志,由于运行的粗糙性和惯性,
常取其他对管的输出信号作为判断条件
7.check_right----若先检测到左边黑线,并且左边已出黑线,判断右端是否压黑线时间拖延
--------------------------------------------------------
{
Duty_left =turn_speed_left;
Duty_right=turn_speed_right;
IN1=1;//转弯时一个正转,一个反转,
IN2=0;
IN3=0;
IN4=1;
}
//-----------------------------------------------------
void time0(void)interrupt 1//中断程序
{
i++;//调速在中断中执行
j++;
if(i<=Duty_left)
ENA=1;
else ENA=0;
if(i>100)
{ENA=1;i=0;}
if(j<=Duty_right)
ENB=1;
else ENB=0;
if(j>100)
{ENB=1;j=0;}