小车循迹原理Word下载.docx

上传人:b****5 文档编号:20721712 上传时间:2023-01-25 格式:DOCX 页数:21 大小:222.03KB
下载 相关 举报
小车循迹原理Word下载.docx_第1页
第1页 / 共21页
小车循迹原理Word下载.docx_第2页
第2页 / 共21页
小车循迹原理Word下载.docx_第3页
第3页 / 共21页
小车循迹原理Word下载.docx_第4页
第4页 / 共21页
小车循迹原理Word下载.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

小车循迹原理Word下载.docx

《小车循迹原理Word下载.docx》由会员分享,可在线阅读,更多相关《小车循迹原理Word下载.docx(21页珍藏版)》请在冰豆网上搜索。

小车循迹原理Word下载.docx

图中循迹传感器共安装4个,全部在一条直线上。

其中InfraredMR与InfraredML为第一级方向控制传感器,InfraredSR与InfraredSL为第二级方向控制传感器。

小车行走时,始终保持黑线(如图2中所示的行走轨迹黑线)在InfraredMR和InfraredML这两个第一级传感器之间,当小车偏离黑线时,第一级探测器一旦探测到有黑线,单片机就会按照预先编定的程序发送指令给小车的控制系统,控制系统再对小车路径予以纠正。

若小车回到了轨道上,即4个探测器都只检测到白纸,则小车会继续行走;

若小车由于惯性过大依旧偏离轨道,越出了第一级两个探测器的探测范围,这时第二级动作,再次对小车的运动进行纠正,使之回到正确轨道上去。

可以看出,第二级方向探测器实际是第一级的后备保护,从而提高了小车循迹的可靠性。

4.软件控制

其程序控制框图如图3。

小车进入循迹模式后,即开始不停地扫描与探测器连接的单片机I/O口,一旦检测到某个I/O口有信号,即进入判断处理程序(switch),先确定4个探测器中的哪一个探测到了黑线,如果InfraredML(左面第一级传感器)或者InfraredSL(左面第二级传感器)探测到黑线,即小车左半部分压到黑线,车身向右偏出,此时应使小车向左转;

如果是InfraredMR(右面第一级传感器)或InfraredSR(右面第二级传感器)探测到了黑线,即车身右半部压住黑线,小车向左偏出了轨迹,则应使小车向右转。

在经过了方向调整后,小车再继续向前行走,并继续探测黑线重复上述动作。

由于第二级方向控制为第一级的后备,则两个等级间的转向力度必须相互配合。

第二级通常是在超出第一级的控制范围的情况下发生作用,它也是最后一层保护,所以它必须要保证小车回到正确轨迹上来,则通常使第二级转向力度大于第一级,即level2>

level1(level1、level2为小车转向力度,其大小通过改变单片机输出的占空比的大小来改变),具体数值在实地实验中得到。

专家点评:

根据本文所讲述的方法,我们可以较容易地做出按照一定轨迹行走的智能电动小车。

但是按照该方法行走的小车如果是走直线,有可能会是蛇形前进。

为了使小车能够按轨迹行走的更流畅,可以在软件编程时运用一些简单的算法。

例如,在对小车进行纠偏时,适当提前停止纠偏,而不要等到小车完全不偏时再停止,以防止小车的过冲。

电源电路:

由于本系统需要电池供电,我们考虑了如下几种方案为系统供电。

方案1:

采用10节1.5V干电池供电,电压达到15V,经7812稳压后给支流电机供电,然后将12V电压再次降压、稳压后给单片机系统和其他芯片供电。

但干电池电量有限,使用大量的干电池给系统调试带来很大的不便,因此,我们放弃了这种方案。

方案2:

采用3节4.2V可充电式锂电池串联共12.6V给直流电机供电,经过7812的电压变换后给支流电机供电,然后将12V电压再次降压、稳压后给单片机系统和其他芯片供电。

锂电池的电量比较足,并且可以充电,重复利用,因此,这种方案比较可行。

但锂电池的价格过于昂贵,使用锂电池会大大超出我们的预算,因此,我们放弃了这种方案。

方案3:

采用12V蓄电池为直流电机供电,将12V电压降压、稳压后给单片机系统和其他芯片供电。

蓄电池具有较强的电流驱动能力以及稳定的电压输出性能。

虽然蓄电池的体积过于庞大,在小型电动车上使用极为不方便,但由于我们的车体设计时留出了足够的空间,并且蓄电池的价格比较低。

因此我们选择了此方案。

综上考虑,我们选择了方案3。

这个黑呼呼的东西,让我们可爱的小车变得很难看。

稳压模块:

采用两片7812将电压稳压至12V后给直流电机供电,然后采用一片7809将电压稳定至9V,最后经7805将电压稳至5V,给单片机系统和其他芯片供电,但7809和7805压降过大,使7809和7805消耗的功率过大,导致7809和7805发热量过大,因此,我们放弃了这种方案。

采用两片7812将电压稳压至12V后给直流电机供电,然后采用2576将电压稳至5V。

2576的输出电流最大可至3A,完全满足系统要求。

综上考虑,我们选择了方案2。

稳压模块如下图:

(左图:

稳压模块)

循迹传感器模块

用光敏电阻组成光敏探测器。

光敏电阻的阻值可以跟随周围环境光线的变化而变化。

当光线照射到白线上面时,光线发射强烈,光线照射到黑线上面时,光线发射较弱。

因此光敏电阻在白线和黑线上方时,阻值会发生明显的变化。

将阻值的变化值经过比较器就可以输出高低电平。

但是这种方案受光照影响很大,不能够稳定的工作。

因此我们考虑其他更加稳定的方案。

用红外发射管和接收管自己制作光电对管寻迹传感器。

红外发射管发出红外线,当发出的红外线照射到白色的平面后反射,若红外接收管能接收到反射回的光线则检测出白线继而输出低电平,若接收不到发射管发出的光线则检测出黑线继而输出高电平。

这样自己制作组装的寻迹传感器基本能够满足要求,但是工作不够稳定,且容易受外界光线的影响,因此我们放弃了这个方案。

用RPR220型光电对管。

RPR220是一种一体化反射型光电探测器,其发射器是一个砷化镓红外发光二极管,而接收器是一个高灵敏度,硅平面光电三极管。

RPR220采用DIP4封装,其具有如下特点:

∙塑料透镜可以提高灵敏度。

∙内置可见光过滤器能减小离散光的影响。

∙体积小,结构紧凑。

∙当发光二极管发出的光反射回来时,三极管导通输出低电平。

此光电对管调理电路简单,工作性能稳定。

此我们选择了方案3。

安装后效果如下图:

下图是电压比较器:

电设小车循迹模块

2007-10-1414:

06

//包含所需头文件

#include<

ioM16v.h>

macros.h>

#include"

time1_init.h"

motor.h"

#defineahead1

#definebackwards0

#definecompare(x,y)(x<

y?

1:

0)

#definemid0X17

/*****************************初始化函数********************************/

//端口初始化

voidport_init(void)

{

PORTA=0x00;

DDRA 

=0x00;

PORTB=0x00;

DDRB 

=0x08;

PORTC=0x00;

DDRC 

PORTD=0x00;

DDRD 

}

voidtimer0_init(void)

TCCR0 

//停止定时器

TCNT0 

//初始值

OCR0 

=0x17;

//匹配值

TIMSK|=0x00;

//中断允许

=0x7D;

//启动定时器

voidadc_init(void)

//adc转换初始化

ADCSRA=0x00;

//禁止AD转换

ADCSRA|=BIT(ADIF);

ADMUX=0X46;

SFIOR|=0x00;

ACSR=0x80;

//禁止模拟比较器

ADCSRA=0xE7;

voidinit_devices(void)

CLI();

//禁止所有中断

MCUCR 

MCUCSR=0x80;

//禁止JTAG

GICR 

port_init();

timer0_init();

timer1_init();

adc_init();

SEI();

//开全局中断

/**********************************************************************/

/*****选择前端传感器用ucharstart_head_sensor(void)*****************************

选择后端传感器用ucharstart_back_sensor(void)

/*****使用角度传感器用uintcord_sensor(void)********************************************/

uintsensor_head[3],sensor_back[3],cord;

//存储6个传感器AD转换的值

ucharoffset;

//黑线偏移小车中心轴的距离

uintsensor_compare_head[3]={300,300,300},sensor_compare_back[3]={300,300,300};

//判断黑线是否位于传感器下的阈值

ucharstart_head_sensor(void)

uchari,j=0,sum=0;

ADMUX=0X40;

ADCSRA=0xC7;

while(ADCSRA&

BIT(ADSC));

for(i=0;

i<

3;

i++)

ADMUX=0X40+i;

//启用前端传感器0,1,2通道

ADCSRA=0xC7;

while(ADCSRA&

sensor_head[i]=ADC;

}

for(i=3;

i;

i--)

if(compare(sensor_head[i-1],sensor_compare_head[i-1]))

{

sum+=i-1;

j++;

}

if(j)

offset=sum*2/j;

ADCSRA=0xE7;

returnoffset;

ucharstart_back_sensor(void)

ADMUX=0X43;

ADMUX=0X43+i;

sensor_back[i]=ADC;

for(i=3;

if(compare(sensor_back[i-1],sensor_compare_back[i-1]))

if(j)offset=sum*2/j;

ADCSRA=0XE7;

//角度传感器滤波函数

uint 

cord_sensor(void)

uchari;

uintmax=0,min=1023,sum=0;

5;

ADCSRA|=BIT(ADIF);

while(!

(ADCSRA&

BIT(ADIF)));

cord=ADC;

sum+=cord;

max=(max>

cord)?

max:

cord;

min=(min<

min:

return(sum-max-min)/3;

voiddirec_ctrl(ucharx,uchary)

if(y)

if(x==0)OCR0=mid+3;

if(x==4)OCR0=mid-3;

if(x==2)OCR0=mid;

elseOCR0=mid+x-2;

voidmenmber_path(void)

ucharj;

uinti;

uintmax_head[3]={0,0,0},min_head[3]={1023,1023,1023},max_back[3]={0,0,0},min_back[3]={1023,1023,1023};

for(i=4000;

start_head_sensor();

for(j=0;

j<

j++)

max_head[j]=(max_head[j]>

sensor_head[j])?

max_head[j]:

sensor_head[j];

min_head[j]=(min_head[j]<

min_head[j]:

}

start_back_sensor();

max_back[j]=(max_back[j]>

sensor_back[j])?

max_back[j]:

sensor_back[j];

min_back[j]=(min_back[j]<

min_back[j]:

for(j=0;

sensor_compare_head[j]=(max_head[j]+min_head[j])/2;

sensor_compare_back[j]=(max_back[j]+min_back[j])/2;

/***********************前端同时检测到黑线判断函数****************************************/

ucharhead_sensor_all(void)

if(compare(sensor_head[0],sensor_compare_head[0]) 

&

&

compare(sensor_head[1],sensor_compare_head[1])&

compare(sensor_head[2],sensor_compare_head[2]))

return1;

else

return0;

ucharback_sensor_all(void)

if(compare(sensor_back[0],sensor_compare_back[0]-30) 

compare(sensor_back[1],sensor_compare_back[1]-30)&

compare(sensor_back[2],sensor_compare_back[2]-30))

/**********************前端循迹函数**************************************************/

voidsearch_path_ahead(ucharspeed)

motor_autorun(ahead,speed);

while

(1)

{

if(head_sensor_all())

motor_stop();

return;

direc_ctrl(offset,1);

/**********************后端循迹函数*******************************************/

voidsearch_path_backward(ucharspeed)

motor_autorun(0,speed);

if(back_sensor_all())

else

direc_ctrl(offset,0);

#include<

reg51.h>

#defineTH0_TL0(65536-1000)//设定中断的间隔时长

unsignedcharcount0=0;

unsignedcharcount1=0;

bitFlag=1;

//电机正反转标志位,1正转,0反转

sbitKey_add=P1^4;

//电机减速

sbitKey_dec=P1^5;

//电机加速

sbitKey_turn=P1^6;

//电机换向

sbitPWM1=P3^6;

//PWM通道1

sbitPWM2=P3^7;

//PWM通道2

unsignedcharTime_delay;

//函数声明

voidDelay(unsignedcharx);

voidMotor_speed_high(void);

voidMotor_speed_low(void);

voidMotor_turn(void);

voidTimer0_init(void);

/******************************************************************************/

voidDelay(unsignedcharx)//延时处理

Time_delay=x;

while(Time_delay!

=0);

voidTimer0_int(void)interrupt1using1//定时0中断处理

TR0=0;

TL0+=(TH0_TL0+9)%256;

TH0+=(TH0_TL0+9)/256+(char)CY;

TR0=1;

if(Time_delay!

=0)//延时函数用

Time_delay--;

if(Flag==1)//电机正转

PWM1=0;

if(++count1<

count0)

PWM2=1;

PWM2=0;

if(count1>

=100)

count1=0;

else//电机反转

PWM1=1;

}//反转

voidMotor_speed_high(void)//按键处理加pwm占空比,电机加速

if(Key_add==0)

Delay(10);

count0

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 交通运输

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1