AVR自动循迹小车的设计
一、设计要求
(1)自动寻迹小车从安全区域启动。
(2)小车按指定路线运行,自动区分直线轨道和弯路轨道,在指定弯路处拐弯,实现灵活前进、转弯、倒退等功能,在轨道上划 出设定的地图。
(3)小车完成指定运行任务后,自动返回出发起点,自动倒车,入库
一般寻迹是指小车在黑色地板上循白线行走,通常采取的方法是红外探测法,即利用红外线在不同颜色的物体表面具有不同反射性质的特点,在小车行驶中不断向地面发射红外光,当红外光遇到白色轨迹时发生漫反射,反射光被装在小车上的接收管接收;如果遇到黑色地板则红外光被吸收,接收管接收不到红外光。单片机以是否收到反射回来的红外光为依据来确定白线的位置和小车的行走路线。红外探测器探测距离有限,一般最大不应超过3cm。下面是小车底盘示意图:
根据要求,设计的系统主要由控制器模块、电源模块、寻迹传感器模块、直流电机及其驱动模块、电压比较模块等构成。
二、方案设计
经过反复考虑论证,制定了左右两轮分别驱动,后万向轮转向的方案。即左右轮分别用两个转速和力矩基本完全相同的直流电机进行驱动,车体尾部装一个万向轮。这样,当两个直流电机转向相反、转速相同时就可以实现电动车的原地旋转,由此可以轻松实现小车坐标不变的90度和180度转弯。安装时保证两个驱动电机同轴。当小车前进时,左右两驱动轮与后万向轮形成了三点结构。这种结构使得小车在前进时比较平稳,可以避免出现后轮过低而使左右两驱动轮驱动力不够的情况。为了防止小车重心的偏移,后万向轮起支撑作用。 车架材料选择有机玻璃,它比塑料车架更加牢固,比铁制小车更轻便,美观。
三、程序设计
#include<mega128.h>
#include "delay.h"
#define left1 PORTC.0
#define left2 PORTC.1
#define min PORTC.2
#define right1 PORTC.3
#define right2 PORTC.4
#define Turn_Left PORTC.5
#define Turn_Right PORTC.6
#define u8 unsigned char
#define u16 unsigned int
void Init_IO(void)
{
DDRC = DDRC&0xe0; //将C端口低5位定义为输入,浮空
PORTC = 0xe0;//
DDRB = 0xff; //将B端口设为输出模式
PORTB = 0xff;
PORTA = 0xff;
DDRA = 0xff;
}
void Adjust_Speed(u8 Left_Speed,u8 Right_Speed)
{
OCR1A = (u16)Right_Speed*10 ;//Left_Speed:1--100,为右电机占空比
OCR1B = (u16)Left_Speed*10;//Right_Speed:1--100,为左电机的占空比
}
void Init_Timer1(void)
{ u16 i,j;
i = 300; //实际测试发现1600时电机速度还是很快的。
j = 300;
TCCR1A = 0xa0;//相位与频率修正PWM,TOP值为ICR1,向上计数匹配清零,向下计数匹配时置1
TCCR1B = 0x12;//系统时钟8分频,A,B同时输出PWM
OCR1A = i; //右电机
OCR1B = j; //在电机
ICR1 = 1000;
}
void main(void)
{
Init_IO();
Init_Timer1();
while(1)
{
if(PINC==0xfb)//只有中间循迹管检测到黑线11011
{
Adjust_Speed(30,30);//前进
PORTA = 0xfe;
}
if(PINC==0xf9)//中间和左边第二个循迹管检测到黑线10011
{
Adjust_Speed(20,60);//左转
// delay_ms(5);
PORTA = 0xfd;
}
if(PINC==0xfd)//左边第二个循迹管检测到黑线10111
{
Adjust_Speed(15,65);//左转
//delay_ms(5);
PORTA = 0xfb;
}
if(PINC==0xfc)//左边两个同时检测到黑线00111
{
Adjust_Speed(15,70);//左转
PORTA = 0xf7;
}
if(PINC==0xfe)//左边第一个循迹管检测到黑线01111
{
Adjust_Speed(15,85);//左转
// delay_ms(5);
PORTA = 0xef;
}
if(PINC==0xf3)//中间和右边第二个循迹管检测到黑线11001
{
Adjust_Speed(35,15);//右转
PORTA = 0xdf;
}
if(PINC==0xf7)//右边第二个循迹管检测到黑线11101
{
Adjust_Speed(70,13);//右转
PORTA = 0xbf;
}
if(PINC==0xe7)//右边两个检测到黑线11100
{
Adjust_Speed(75,13);//右转
PORTA = 0x7f;
}
if(PINC==0xef)//右边第一个检测到黑线11110
{
Adjust_Speed(96,12);//右转
PORTA = 0xfc;
}
if(PINC==0xe3)//右侧三个循迹管同时检测到黑线(直角)11000
{
Adjust_Speed(40,0);//右转
PORTA = 0xf8;
}
if(PINC==0xe7)//左侧三个循迹管同时检测到黑线(直角)00011左转
{
Adjust_Speed(0,40);//左转
PORTA = 0xf0;
}
if(PINC==0xe0)//5个循迹管同时检测到交叉00000直走
{
Adjust_Speed(25,25);//直走
PORTA = 0xe0;
}
// if(PINC==0xff)
// {
// Adjust_Speed(0,100);//直走
// PORTA = 0xc0;
//}
}
}
|