智能循迹小车c程序完美-详尽)
- 格式:doc
- 大小:28.00 KB
- 文档页数:7
/*------------------------------------------------------
-----------------------小车运行主程序-------------------
--------------------------------------------------------
简介:@模块组成:红外对管检测模块----五组对管,五个信号采集端口
直流电机驱动模块----驱动两个直流电机,另一个轮子用万向轮
单片机最小系统------用于烧写程序,控制智能小车运动 @功能简介:在白色地面或皮质上用黑色胶带粘贴出路线路径宽度微大于相邻检测管间距。
这样小车便可在其上循迹运行。
@补充说明:该程序采取“右优先”的原则:
即右边有黑线向右转,
若无,前方有黑线,向前走,
若无,左边有黑线,向左转,
若全无,从右方向后转。
程序开头定义的变量的取值是根据我的小车所调试选择好的,
如果采用本程序,请自行调试适合自己小车的合适参数值。
编者:陈尧,黄永刚(江苏大学电气学院二年级,三年级)
1.假定:IN1=1,IN3=1时电机正向转动,必须保证本条件
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.
微小校正时---------高速轮full_speed_left,full_speed_right;
低速轮correct_speed.
可以通过调节第六,七,八,九,十条程序,改变各个状态
下的占空比(Duty cycle ),以求达到合适的转弯,直行速度
4.lenth----------length检测到黑线到启动转动的时间间隔
5.width----------mid3在黑线上到脱离黑线的时间差
6.mid3-----------作为判断中心位置是否进入黑线的标志,由于运行的粗糙性和惯性,
常取其他对管的输出信号作为判断条件
7.check_right----若先检测到左边黑线,并且左边已出黑线,判断右端是否压黑线时间拖延--------------------------------------------------------
--------------------------------------------------------*/
#include
#define uchar unsigned char
#define uint unsigned int
#define m0 1//黑线m1,白线m0
#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);
#define correct_speed 6 //校正时的低速轮的占空比
#define turn_speed_left 25
#define turn_speed_right 30
#define lenth 68000 //测试数据:10000--》100--》500--》2000--80000--76000--68000 #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;
sbit mid3 =P1^4;
sbit right4=P1^3;
sbit right5=P1^2;
void line_left();
void line_right();
void line_straight()reentrant;
//----------------------------------------
void delay(long int Delay_time)//延时函数
{
uint t=Delay_time;
while(t--);
}
//-----------------------------------------
void init() //定时器初始化
{
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;
}
//--------------------------------------------
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;}
TH0=(65536-66)/256; //取约150HZ,12M晶振,每次定时66us,分100次,这样开头定义的变量正好直接表示占空比的数值
TL0=(65536-66)%256;
}
//-----------------------------------------------
void correct_left()//向左校正,赋值
{