智能循迹小车C程序(完美-详尽).doc
《智能循迹小车C程序(完美-详尽).doc》由会员分享,可在线阅读,更多相关《智能循迹小车C程序(完美-详尽).doc(7页珍藏版)》请在冰豆网上搜索。
![智能循迹小车C程序(完美-详尽).doc](https://file1.bdocx.com/fileroot1/2022-11/3/747c5a20-6586-4508-955e-d7f730cad706/747c5a20-6586-4508-955e-d7f730cad7061.gif)
/*------------------------------------------------------
-----------------------小车运行主程序-------------------
--------------------------------------------------------
简介:
@模块组成:
红外对管检测模块----五组对管,五个信号采集端口
直流电机驱动模块----驱动两个直流电机,另一个轮子用万向轮
单片机最小系统------用于烧写程序,控制智能小车运动
@功能简介:
在白色地面或皮质上用黑色胶带粘贴出路线路径宽度微大于相邻检测管间距。
这样小车便可在其上循迹运行。
@补充说明:
该程序采取“右优先”的原则:
即右边有黑线向右转,
若无,前方有黑线,向前走,
若无,左边有黑线,向左转,
若全无,从右方向后转。
程序开头定义的变量的取值是根据我的小车所调试选择好的,
如果采用本程序,请自行调试适合自己小车的合适参数值。
编者:
陈尧,黄永刚(江苏大学电气学院二年级,三年级)
1.假定:
IN1=1,IN3=1时电机正向转动,必须保证本条件
2.假定:
遇到白线输出0,遇到黑线输出1;
如果实际电路是:
遇到白线输出1,遇到黑线输出0,
这种情况下只需要将第四,第五句改成:
#definem01
#definem10
即可。
3.说明1:
直行---------------速度full_speed_left,full_speed_right.
转弯,调头速度------correct_speed_left,correct_speed_right.
微小校正时---------高速轮full_speed_left,full_speed_right;
低速轮correct_speed.
可以通过调节第六,七,八,九,十条程序,改变各个状态
下的占空比(Dutycycle),以求达到合适的转弯,直行速度
4.lenth----------length检测到黑线到启动转动的时间间隔
5.width----------mid3在黑线上到脱离黑线的时间差
6.mid3-----------作为判断中心位置是否进入黑线的标志,由于运行的粗糙性和惯性,
常取其他对管的输出信号作为判断条件
7.check_right----若先检测到左边黑线,并且左边已出黑线,判断右端是否压黑线时间拖延
--------------------------------------------------------
--------------------------------------------------------*/
#include
#defineucharunsignedchar
#defineuintunsignedint
#definem01//黑线m1,白线m0
#definem10
#definefull_speed_left40//方便调节各个状态的占空比,可用参数组:
(30,35,6,25,30,68000,27000,500);
#definefull_speed_right45 // (40,45,6,25,30,68000,27000,500);
#definecorrect_speed6//校正时的低速轮的占空比
#defineturn_speed_left25
#defineturn_speed_right30
#define lenth68000 //测试数据:
10000--》100--》500--》2000--80000--76000--68000
#definewidth27000 //500--》10-->2000--》60000--30000---》27000
#definecheck_right500//2000--》20--》200--》500
#definemidlleft1
#definemidrright5
ucharDuty_left,Duty_right,i=0,j=0;//左右占空比标志,取1--100
sbitIN1=P2^0;
sbitIN2=P2^1;
sbitIN3=P2^2;
sbitIN4=P2^3;
sbitENA=P1^0;
sbitENB=P1^1;
//循迹口五组红外对管,依次对应从左往右第1,2,3,4,5五组
sbitleft1=P1^6;
sbitleft2=P1^5;
sbitmid3=P1^4;
sbitright4=P1^3;
sbitright5=P1^2;
voidline_left();
voidline_right();
voidline_straight()reentrant;
//----------------------------------------
voiddelay(longintDelay_time)//延时函数
{
uintt=Delay_time;
while(t--);
}
//-----------------------------------------
voidinit() //定时器初始化
{
left1=m0;//初始化
left2=m0;//白线位置
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;
}
//--------------------------------------------
voidtime0(void)interrupt1 //中断程序
{
i++; //调速在中断中执行
j++;
if(i<=Duty_left)
ENA=1;
elseENA=0;
if(i>100)
{ENA=1;i=0;}
if(j<=Duty_right)
ENB=1;
elseENB=0;
if(j>100)
{ENB=1;j=0;}
TH0=(65536-66)/256; //取约150HZ,12M晶振,每次定时66us,分100次,这样开头定义的变量正好直接表示占空比的数值
TL0=(65536-66)%256;
}
//-----------------------------------------------
voidcorrect_left()//向左校正,赋值
{
Duty_left=correct_speed;
Duty_right=full_speed_right;
IN1=1;
IN2=0;
IN3=1;
IN4=0;
}
//------------------------------------------------
voidcorrect_right()//向右校正,赋值
{
Duty_left=full_speed_left;
Duty_right=correct_speed;
IN1=1;
IN2=0;
IN3=1;
IN4=0;
}
//--------------------------------------------------
voidturn_left()//左转,赋值
{
Duty_left=turn_speed_left;
Duty_right=turn_speed_right;
IN1=0; //转弯时一个正转,一个反转,
IN2=1;
IN3=1;
IN4=0;
}
//---------------------------------------------------
voidturn_right()//右转,赋值
{
Duty_left=turn_speed_left;
Duty_right=turn_speed_right;
IN1=1; //转弯时一个正转,一个反转,
IN2=0;
IN3=0;
IN4=1;
}
//-----------------------------------------------------
voidstraight() //直走,赋值
{
Duty_left=full_speed_left; //左右电机占空比初始化,调节直线运动速度
Duty_right=full_speed_right; //鉴于左右轮电机内部阻力不同,故占空比取不同值,这组值需要单独写程序取值
IN1=1;
IN2=0;
IN3=1;
IN4=0;
}
//-----------------------------------------------------
voidline_straight()reentrant//函数名后加reentrant可以递归调用,//一直走黑直线时
{
straight();
if(right5==m1){line_right();}
else
if(left1==m1){line_left();}
else
if(left2==m1) //防止校正时,小车冲出过大,导致2,4号检测管屏蔽了两端检测管的检测,避免其走直线时出轨
while(left2==m1)
{correct_left();
if(right5==m1)
{
line_right();
gotolabel3;
}
elseif(left1==m1)
{line_left();
gotolabel3;}
}
else
if(right4==m1) //防止校正时,小车冲出过大,导致2,4号检测管屏蔽了两端检测管的检测,避免其走直线时出轨
while(right4==m1)
{correct_right();