自动避障红外电动小车C51程序
#define Busy 0x80 //用于检测LCD状态字中的Busy标识
sbit c=P1^2; //转向灯使能端
uchar code talk1[]={"backward"};
uchar code talk2[]={"forward"};
uchar code talk3[]={"Turnleft"};
****************************/
void infrared_ray()interrupt 0 using 3
{ uchar i=90;
flage=0x01; //接受标志位
while(i--); //减小灵敏度
EX0=0; //关掉中断,等到发射方波后才开启,处于别动
}
//延时子程序
LCD_Data = WCLCD;
LCD_RS= 0;
LCD_RW= 0;
LCD_E = 0; //延时,为了安全
LCD_E = 0;
LCD_E = 0; //延时
LCD_E = 1;
}
void LCDInit(void) //LCD初始化
{
Delay400Ms();
LCD_Data = 0;
WriteCommandLCD(0x38,0); //三次显示模式设置,不检测忙信号
//右边有障碍物,左转
else if(temp==0x02) {control(2,dj_state3,right_light ); temp =0x00;}
//两个方向都有障碍物,后退,右转
else if(temp==0x03) {control(10,dj_state4,back_light );
while(TempCycA--)
{ TempCycB=7269;
while(TempCycB--);
}
}
//LCD读状态
unsigned char ReadStatusLCD(void)
{
LCD_Data = 0xFF;
LCD_RS = 0;
LCD_RW = 1;
LCD_E = 0;
LCD_E = 0;
WriteCommandLCD(0x01,1); //显示清屏
delay(100);
P2=dj_state1;
DisplayListChar(0,0,8,talk2,false);
while(1)
{ move_car(); //主要控制部分
delay(200000);//延时
}
}
{ if (X <= 0x0F) //X坐标应小于0xF
{ DisplayOneChar(X, Y, DData[i]); //显示单个字符
if(n==true)Delay400Ms();
X++;
}
}
}
/****************************
红外线接收子程序,利用了中断的下降沿触发方式
自动避障红外电动小车C51程序
#include"reg51.h"
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define left_infrare 0
#define right_infrare 1
#define dj_state1 0X5F //前进
****************************************/
void seng_wave(uchar timer,bit n)//timer通过载波发射信号的时间,n->左右发射管的选择
{ uchar i;
P1 |= 0X04; //ledcs=1为74ls573为11脚为高电平时数据直接输出,为低时把数据锁存住,即保持
IE |= 0X01;
P0 |=0x0c; //04
for(i=timer;i>0;i--)
{ if(n)P0^=0x08; //右发射管通过载波发射信号//00
else P0^=0x04; //左发射管通过载波发射信号//0c
delay(100); //这里控制着灵敏度(控制38khz的方波的多少)和距离
}
//按指定位置显示一串字符(只能写一行);
void DisplayListChar(uchar X, uchar Y,uchar ListLength, uchar *DData,uchar n)
{ uchar i;
Y &= 0x01;
X &= 0x0F; //限制X不能大于15,Y不能大于1
for(i=0;i<ListLength;i++)
#define right_light 0XaF //右转向灯0xaf,两个是0xbf
#define back_light 0XcF //刹车灯即后灯
#define front_light 0x3f //前灯
#define light_on 0xff //开所有灯
#define true 1
#define false 0
seng_wave(1,right_infrare); //向下为中断开启有关闭后,要执行的语句
if(flage==0x01){temp|=0x02;flage=0x00;}
//左边有障碍物,右转
if(temp==0x01){control(2,dj_state2,left_light); temp =0x00;}
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y)
X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80; //算出LCD的指令码
WriteCommandLCD(X, 0); //这里不检测忙信号,发送地址码
WriteDataLCD(DData);
case dj_state3: { DisplayListChar(3,1,8,talk3,false);}break;
case dj_state4: { DisplayListChar(3,1,7,talk1,false); }break;
default :break;
}
for(i=n;i>0;i--)
LCD_RW =0;
LCD_E = 0; //若晶振速度太高可以在这后加小的延时
LCD_E = 0; //延时,为了安全
LCD_E = 0; //延时
LCD_E = 1;
}
//LCD写指令
void WriteCommandLCD(unsigned char WCLCD,BuysC)
{
if (BuysC) ReadStatusLCD(); //根据需要检测忙,BuysC为0时忽略忙检测
void move_car(void)
{
uchar temp =0x00;
//左边红外管发射
seng_wave(1,left_infrare); //向下为中断开启有关闭后,要执行的语句
if(flage==0x01){temp|=0x01;flage=0x00;}
//右边红外管发射
delay(30);
P0=0x0f;
P1&=0XFB;
delay(100);
DisplayListChar(0,0,7,talk2,false);
}
}
/****************************************
避障主要控制部分
*****************************************/
{ uchar i;
// P1|=0x04;
light_control(light); //led转向指示灯
delay(100);
P2 =dj_state; //电机的方向控制
WriteCommandLCD(0x01,1); //LCD显示清屏
switch(dj_state)
{ case dj_state2 :{ DisplayListChar(3,1,10,talk4,false);}break;
#define dj_state2 0X4F //右转
#define dj_state3 0X1F //左转
#define dj_state4 0X0F //后退
#define dj_state5 0XfF //停车
#define light_off 0x0f //关转向灯
#define left_light 0X5F //左转向灯两个是5f
control(5,dj_state2,right_light ); temp =0x00;}
}
void main(void)
{ Init0(); //中断初始化
P1 |= 0X04; //开锁存器的控制位
P0 = 0xFf; //数据口的清零
P1&=0XFB; //关锁存器的控制位
LCDInit(); //LCD初始化
Delay5Ms();
WriteCommandLCD(0x38,0);
Delay5Ms();
WriteCommandLCD(0x38,0);
Delay5Ms();
WriteCommandLCD(0x38,1); //显示模式设置,开始要求每次检测忙信号
WriteCommandLCD(0x08,1); //关闭显示
WriteCommandLCD(0x01,1); //显示清屏
基于单片机的智能避障小车设计(C51语言编程)【开题报告】
开题报告电气工程及其自动化基于单片机的智能避障小车设计(C51语言编程)一、课题研究意义及现状随着电子技术的飞速发展,电子产品也越来越智能化和微型化。
世界玩具市场也因此越来越向电子化发展。
根据美国玩具协会调查统计,近年来全球的玩具市场越来越大,但是全球玩具市场的结构却发生了比较巨大的变换。
传统玩具的市场份额也在逐年的减少,智能电子玩具的市场份额则越来越多。
美国电子玩具工业的发展在21世纪出现了一个最大的变革,那就是科技(尤其是互联网)在玩具中的应用。
这种改变给玩具工业带来了无限机遇和挑战,美国的玩具市场由1996年的227亿美元到2005年的230亿美元。
并且在这些玩具中75%是装有电子设备的高科技玩具,电子玩具的兴起代表着玩具发展的“新时代”的开始。
因此,传统玩具中的益智玩具销售将领先。
给传统的洋娃娃、毛绒玩具安装上IC,将成一种潮流,机器人玩具过去由于生产成本高,外表缺吸引力,导致发展缓慢,随着生产成本的降低,外形的改进,教育性机器人玩具可能放异彩。
我们已经有理由相信:电子玩具的兴起代表着玩具发展的“新时代”的开始,电子玩具多彩的艺术表现形式是吸引孩子们到百货店挑选玩具的兴趣所在。
这些数据的表明,高新电子玩具已经成为玩具市场的主流。
在这些电子玩具中,智能小车是一个非常热门的玩具产品,智能小车,也称轮式机器人,是一种以汽车电子为背景,涵盖控制、模式识别、传感技术、电子、电气、计算机、机械等多学科的科技创意性设计,一般主要由路径识别、速度采集、角度控制及车速控制等模块组成。
我国是世界最大的玩具制造国和出口国,但是我国的玩具大部分都是以低廉的劳动力以及传统玩具来取得的,在高新技术以及玩具的附加值上不能与其他国家相比,随着当今智能玩具的发展,国内的玩具结构必须要做出改变,我们必须利用科技创新来提高玩具的附加值。
因此,高科技含量的电子互动式玩具必须是中国未来发展的趋势。
本次课题准备设计一种能够实时采集传感器信号、智能分析外部环境以及自动实现方向控制等功能的智能小车。
基于51单片机的自动避障感光小车
目录1 引言 (1)2 方案设计与论证 (1)2.1 主控系统 (1)2.2 电机驱动模块 (2)2.3 电源模块 (3)2.4 避障模块 (3)2.5 感光模块 (3)2.6 自动停车模块 (4)3 硬件设计 (4)3.1 总体设计 (4)3.2 驱动电路 (5)3.3 超声波避障模块 (5)3.4 光敏电阻感光模块 (5)3.5 停车模块 (6)4 软件设计 (6)4.1主程序流程图 (6)4.2 避障功能设计 (7)4.3感光功能设计 (11)5 系统的仿真与调试 (14)5.1概述 (14)5.2避障功能的仿真 (16)5.3感光模块的仿真 (17)6 总结 (19)参考文献 (20)致谢 (22)附录A 源程序清单 (23)附录B 电路硬件仿真图 (27)1 引言在科学探险和现实救助中经常会遇到一些人类无法到达的危险地域的探测,这时就需要机器人为我们获取一些数据及情报。
这就需要机器人可以自动定位探测目标向探测目标自动行进并能通过传感器了解周围环境以及自身状态。
在复杂的地形中,机器人的自动避障与自动导航是必须要求的,所以自动避障技术以及自动导航就由此发展起来了。
我的智能小车就是基于这一技术设计出来的。
智能小车是一个集环境感知、规划决策、自动行驶等功能于一体的综合系统, 它集中地运用了计算机、传感、信息、通信、导航、人工智能及自动控制等技术,是典型的高新技术综合体[1]。
智能小车算是简单的机器人,它们经常被用在那些人类无法适应的工作环境中,因此它们在人类生活中得到了广泛的应用。
在很多工作领域中它们可以超越人类工作的质量与效率。
生活中有很多这样的例子如焊接、医疗、喷漆、探测等。
在相对恶劣的工作环境中,机器人不会受到任何影响,并能继续保持良好的工作效率,而人类则不行,时间久了不但会疲惫而且对身体有害。
我此次的设计主要实现自动避障及自动导航功能。
此次设计对于未来智能系统、自动化等方面的发展都有非常重要的作用,所以本设计与实际具有紧密联系,具有重要的现实意义。
基于51单片机的红外避障+超声波避障程序
基于51单⽚机的红外避障+超声波避障程序最近在学习关于51单⽚机控制智能⼩车,学习了很多⼤佬优秀的代码和思路受到了⼀些启发,决定按⾃⼰的逻辑尝试⼀下关于红外避障+超声波避障的程序经过实际测试,当PWM在50%左右,效果还⾏,但当全速前进时效果不是很理想代码还有待改进,有些地⽅逻辑⽐较混乱,单纯只是为了能跑通,有待优化先记录⼀下,毕竟也花了不少时间来写和调试#include<reg52.H>#include "test2.h"#include <stdlib.h>sbit P22 = P2^2;sbit P23 = P2^3;sbit P24 = P2^4;sbit TRIG = P2^1;sbit ECHO = P2^0;sbit left_zhangai = P3^4;sbit right_zhangai = P3^5;unsigned char flag = 0;unsigned char i;unsigned int out_TH0, out_TL0, distance;void left_bizhang(){for (i = 0; i < 30; i++) //90 = 90{car_left_backward();}}void right_bizhang(){for (i = 0; i < 30; i++) //90 = 90{car_right_backward();}}void all_bizhang(){for (i = 0; i < 30; i++) //90 = 90{car_right_backward();}}void back_bizhang(){for (i = 0; i < 10; i++)car_straight_backward();for (i = 0; i < 10; i++)car_left_backward();}void init_time(){TMOD = 0x11; //启动0 1两个定时器TH0 = 0;TL0 = 0;TR0 = 0;TR1 = 0;TH1 = 238;TL1 = 0;TF0 = 0; //中断溢出标志位TF1 = 1;ET0 = 1;ET1 = 1;EA = 1;}void run(){P22 = 1;P24 = 1;left_zhangai = 1;right_zhangai = 1;TRIG = 0; // 先给控制端初始化为0car_straight_forward_per50();distance = 100;while(1){/////////////////////////////label:if (left_zhangai == 1&&right_zhangai == 1){car_straight_forward_per50();}else{if (left_zhangai == 0&&right_zhangai == 0) {all_bizhang();}if (right_zhangai == 0&&left_zhangai == 1) {right_bizhang();}if (left_zhangai == 0&&right_zhangai == 1) {left_bizhang();}}init_time(); //初始化定时器flag = 0; //置溢出标志位为0//控制⼝发⼀个10US 以上的⾼电平TRIG = 1;TR1 = 1; //启动定时器1delay_10um(2);TRIG = 0;//等待接收端出现⾼电平while(!ECHO){if (TH1 == 0){distance = 200;goto label;}};TR0 = 1; //启动计时器开始计时while(ECHO){if (TH1 == 0){distance = 200;goto label;}}; //等待⾼电平结束TR0 = 0; //关闭低电平out_TH0 = TH0; //取定时器的值out_TL0 = TL0;distance = (TH0*256 + TL0)*1.7/100;if (flag == 1){flag = 0;}else if (distance >= 200){car_straight_forward_per50();}else if (distance <= 10){back_bizhang();}else if (distance <= 20){all_bizhang();}///////////////////////////////////////// }}void timer0() interrupt 1//中断函数{flag=1; //溢出标志位置1}。
基于51单片机的避障小车程序
基于51单片机的避障小车程序程序中有我写的注释,看不懂程序的话,可以参考。
#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit IN1=P2^1;//左电机输入端1sbit IN2=P2^2;//左电机输入端2sbit IN3=P2^3;//右电机输入端1sbit IN4=P2^4;//右电机输入端2sbit ENA=P2^0;//右电机使能控制端sbit ENB=P2^5;//左电机使能控制端sbit TX=P1^0;//超声波发送控制端sbit RX=P1^1;//超声波接收控制端uint time=0,ERROR;//用于存放定时器时间值uint PWM1,PWM2,num1=0,num2=0;uint s=0;//用于存放距离的值uchar tt=0;void Delay20us()//@11.0592MHz 延时20us{unsigned char i;_nop_();_nop_();_nop_();i = 52;while (--i);}void forwardg()//前进函数{IN1=1;IN2=0;IN3=1;IN4=0;PWM1=15;PWM2=18;}void stopg()//停止函数{IN1=1;IN2=1;IN3=1;IN4=1;PWM1=0;PWM2=0;}void count()//测距函数{tt=200;if(tt==200)//20ms超声波发送一次{tt=0;TX=1;//超声波发送端Delay20us();//延时20usTX=0;//超声波发送端ERROR=50000;//while(RX==0&&ERROR>0)//判断是否有接收&&等待时常{ERROR--;//等待时长}if(RX==1)//超声波有接收RX=1{TR0=1;//开始计时while(RX&&!TF0);//接收完毕(RX=0)或者超出量程结束语句TR0=0;//停止计时if(TF0==1)//如果溢出(超出量程){TF0=0;//置溢出标志位为0s=999;//直行控制}else{time=TH0*256+TL0;TH0=0;TL0=0;s=(time*1.7)/100;//距离计算公式}}else{s=999;}}}void time0init()//定时器0初始化{TMOD|=0x01;//设置定时器0为工作方式1TH0=0;TL0=0;//定时器赋初值}void time1init()//定时器1初始化{ET1=1;//开定时器中断TR1=1;//开定时器1中断TH1=0xFF;//定时器赋初值TL1=0xA3;TMOD|=0x10;//设置定时器1为工作方式1}void time1() interrupt 3//定时计数器1中断{TH1=0xFF;TL1=0xA3;//赋初值tt++;num1++;num2++;if(num1>=100) //PWM的周期为100*0.1=10ms num1=0;if(num2>=100)num2=0;if(num1<PWM1)ENA=1;//打开右电机使能控制端if(num2<PWM2)ENB=1;if(num1>=PWM1)ENA=0;//关闭右电机使能控制端if(num2>=PWM2)ENB=0;}void main(){time0init();time1init();EA=1;//开总中断while(1){count();//调用距离计算函数if(s>=6)//大于等于6厘米前进{forwardg();}else{stopg();}}}。
学习型红外线遥控程序——C51
学习型红外线遥控程序——C51学习型红外线遥控程序——C51/*************晶体为11.0592M,波特率9600bps***************学习型红外线遥控程序*******/#include <AT89X51.H>void Ewen(void);void Ewds(void);void Delay(void);void Irda(void);void Study(void);void Output(unsigned int h);void Comput(unsigned char outdata);void Erase(unsigned char Address);unsigned int Read(unsigned char Address);unsigned char Display(unsigned char inAddress);void Write(unsigned char Address,unsigned int InData);unsigned int Both(unsigned char data1,unsigned char data2);unsigned char data e1 _at_ 0x1A; //分别存放红外线译码后的数据unsigned char data w1 _at_ 0x1B;unsigned char data e2 _at_ 0x1C;unsigned char data w2 _at_ 0x1D;sbit IrInput=P3^2; //红外线输入引脚,可自定义sbit Study1=P3^6; //学习按键,可自定义sbit Led2=P2^5; //接收成功、学习成功指示sbit Led1=P2^6; //空闲指示sbit Dout=P2^3; //at93c16--DOsbit Din=P2^2; //at93c16--DIsbit sk=P2^1; //at93c16--SKsbit cs=P2^0; //at93c16--CS/*********************主程序***************************/ void main(void){unsigned int i;SCON = 0x50; //串口方式1,允许接收TMOD = 0x20; //定时器1定时方式2TH1 = 0xFD; //波特率9600TL1 = 0xFD;IT0 = 1; //INT0下降沿有效EX0 = 1; //开INT0中断;TR1 = 1; //启动定时器P2_7=0; //初始化引脚P1=0xff;EA = 1; //允许CPU中断while(1){for (i=0; i<20000; i++){ Led1=1;if(!Study1) Study();}for (i=0; i<20000; i++){ Led1=0;if(!Study1) Study();}}}/***********************串口输出**********************/ void Comput(unsigned char outdata){SBUF = outdata;while(!TI);TI = 0;}/*******************红外线查询子程序*******************/ void Irda(void){#pragma asmMOV R6,#10SB:MOV R4,#19 ;延时880微秒D1:MOV R5,#19DJNZ R5,$DJNZ R4,D1JB P3.2,EXIT ;延时882微秒后判断P3.2脚是为1DJNZ R6, SB ;在8820微秒内如P3.2为1就退出JNB P3.2, $ ;等待高电平避开9毫秒低电平引导脉冲MOV R4,#10 ;延时4740微秒D2: MOV R5,#218DJNZ R5,$DJNZ R4,D2;延时4.74毫秒避开4.5毫秒的结果码MOV R1,#1AH ;设定1AH为起始RAM区MOV R2,#4 ;接收从1AH到1DH,用于存放操作码和操作反码PP:MOV R3,#8 ;每组数据为8位SS:JNB P3.2,$ ;等待地址码第一位的高电平信号MOV R4,#19 ;延时880微秒D5:MOV R5,#19DJNZ R5,$DJNZ R4,D5;高电平开始后882微秒判断信号的高低电平MOV C,P3.2 ;将P3.2引脚此时的电平状态0或1存入C中JNC TT ;如果为0就跳转到TTMOV R4,#2 ;延时1000微秒D6:MOV R5,#248DJNZ R5,$DJNZ R4,D6;检测到高电平1的话延时1毫秒等待脉冲高电平结束TT:MOV A,@R1 ;将R1中地址的给ARRC A ;将C中的值0或1移入A中的最低位MOV @R1,A ;DJNZ R3,SS ;接收满8位换一个内存INC R1 ;对R1中的值加1,换下一个RAMDJNZ R2,PP ;接收完所有数据EXIT:#pragma endasm}。
51单片机小车循迹避障原理
51单片机小车循迹避障原理
51单片机小车循迹避障的原理主要包括以下步骤:
1. 传感器检测:小车通过安装的传感器检测路径和障碍物。
寻迹传感器利用黑色对光线的反射率小这个特点,当检测到黑线时,传感器上的开关指示灯会熄灭,输出的是高电平。
如果没有经过黑线,一直保持低电平。
红外传感器在有障碍物时灯会亮,所以有障碍物代表低电平,没有障碍物高电平。
2. 信息处理:51单片机接收并处理传感器的信号。
根据传感器的信号,单片机判断出小车是否偏离了预定路径,或者前方是否有障碍物。
3. 电机控制:根据信息处理的结果,单片机控制电机转动。
例如,如果检测到小车偏离了预定路径,单片机将发送信号使电机转动,使小车回到正确的路径上。
如果检测到前方有障碍物,单片机将发送信号使电机停止转动,避免小车撞到障碍物。
4. 循环检测:小车在行进过程中不断重复上述步骤,确保能够持续地沿着预定路径行进并避开障碍物。
这就是51单片机小车循迹避障的基本原理。
实际的实现可能会更复杂,可能需要更多的传感器和控制逻辑来确保小车的稳定和安全运行。
寻迹避障小车51程序(绝版模块化程序)
M a i n.c #include "common.h"#include "motor.h"#include "timer.h"uchar speed_l;uchar speed_r;sbit out = P3^7;void main(){P1 = 0xff;flag_l = 0;flag_r = 0;sensor_ldata = 0;sensor_rdata = 0;avoid_keyfunc = 0;findline_keyfunc = 0;motor_stop();timerinit();while(1){/*********************************************************循迹功能*********************************************************/while(findline_keyfunc){/**************************************************************** 正常情况下前进****************************************************************/ if(sensor == 0x27){motor_go();speed_l = 50;speed_r = 47;}/****************************************************************如果小车偏左****************************************************************/if((sensor == 0x37) || (sensor == 0x17) || (sensor == 0x0f) || (sensor == 0x1f) || (sensor == 0x3f)){motor_r();speed_l = 45;speed_r--;if(speed_r == 30){speed_r = 31;}}/**************************************************************** 如果小车偏右****************************************************************/if((sensor == 0x67) || (sensor == 0x47) || (sensor == 0x87) || (sensor == 0xc7) ||(sensor == 0xe7)){motor_l();speed_r = 45;speed_l--;if(speed_l == 30){speed_l = 31;}}}/////////////////////////////////////////////////////////////////// /////****************************************************************** * 避障功能******************************************************************* / while(avoid_keyfunc){/*********************************************************** 如果没有检测到有障碍物***********************************************************/ if((sensor_ldata == 1) && (sensor_rdata == 1)){motor_go();speed_l = 48;speed_r = 50;}/*********************************************************** 如果检测到右边有障碍物***********************************************************/ if((sensor_ldata == 1) && (sensor_rdata == 0)){motor_go();speed_l--;speed_r = 100;if(speed_l == 10){speed_l = 11;}}/****************************************************** 如果左边检测到有障碍物******************************************************/ if((sensor_ldata == 0) && (sensor_rdata == 1)){motor_go();speed_r--;speed_l = 100;if(speed_r == 10){speed_r = 11;}}/****************************************************** 如果都检测到有障碍物******************************************************/ if((sensor_ldata == 0) && (sensor_rdata == 0)){motor_go();speed_r = 100;speed_l = 10;}//////////////////////////////////////}/////////////////////////////////////motor_stop();}}MAIN.H#ifndef MAIN_H#define MAIN_Hextern uchar speed_l;extern uchar speed_r;#endifMotor.c#include "common.h"#include "timer.h"sbit in1 = P2^0;sbit in2 = P2^1; //左电机sbit in3 = P2^2;sbit in4 = P2^3;//右电机sbit ENA = P2^4; //只有当ENA=1时左电机才能转sbit ENB = P2^5; // 只有。
红外避障小车c语言程序
LeftStop ; RightStop ; }
} //******************************************************** // 跟随程序 //******************************************************** void Follow(void) { if(RightSenser && LeftSenser&&PWM) { LeftStop ; RightStop; } if((!RightSenser) && LeftSenser&&PWM) { TurnRight_1() ; } if(RightSenser && (!LeftSenser)&&PWM) { TurnLeft_1() ; } if(!(RightSenser || LeftSenser)) { FCar() ; } } //********************************************************
基于51单片机的红外遥控小车设计和制作
基于51单片机的红外遥控小车设计和制作本文介绍一款红外线遥控小车,以AT89S51单片机为核心控制器,用L289驱动直流电机工作,控制小车的运行。
本款小车具有红外线遥控手动驾驶、自动驾驶、寻迹前进等功能。
本系统采用模块化设计,软件用C语言编写。
一、设计任务和要求以AT98C51单片机为核心,制作一款红外遥控小车,小车具有自动驾驶,手动驾驶和循迹前进等功能。
自动驾驶时,前进过程中可以避障。
手动驾驶时,遥控控制小车前进、后退、左转、右转、加速等操作。
寻迹前进时小车还可以按照预先设计好的轨迹前进。
二、系统组成及工作原理本系统由硬件和软件两部分组成。
硬件部分主要完成红外编码信号的发射和接受、障碍物检测、轨迹检测、直流电机运行的发生等功能。
软件主要完成信号的检测和处理、设备的驱动及控制等功能。
AT89S51单片机查询红外信号并解码,查询各个检测部分输入的信号,并进行相应处理,包括电机的正反转,判断是否遇到障碍物,判断是否小车其那金中有出轨等。
系统结构框图如图1所示。
图1 系统结构框图三、主要硬件电路1、遥控发射器电路该电路的主要控制器件为遥控器芯片HT6221,如图2所示。
HT6221将红外码调制成38KHZ的脉冲信号通过红外发射二极管发出红外编码。
图2中D1是红外发射二极管,D2是按键指示灯,当有按键按下时D2点亮。
HT6221的编码规则是:当一个键按下超过36ms,振荡器使芯片激活,如果这个按键按下且延迟大约108ms,这108ms发射代码由一个起始码(9ms),一个结果码(4.5ms),低8位地址码(9ms~18ms),高8位地址码(9~18ms),8位数据码(9~18ms)和这8位数据码的反码(9~18ms)组成,如果按键按下超过108ms仍未松开,接下来发射的代码将仅由起始码(9ms)和结束码(2.5ms)组成。
按照上图的接法,K1~K8的数据码分别为:0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07。
单片机红外遥控小车源程序
单片机红外遥控小车源程序The document was finally revised on 202151单片机红外遥控小车源程序单片机源程序如下:1./*******************************************************************************2.--------------------------------------------------------------------------------3.* 实验名 : 红外线试验4.* 实验说明 : 数码管显示红外线发送过来的键值。
5.* 连接方式 : 见连接图6.* 注意 :7.*******************************************************************************/8.9.//#include<>10.#include<>11.//--定义使用的IO--//12.13.14.sbit IRIN = P3^2;15.sbit PWM1?= P0^1;16.sbit PWM2?= P0^2;17.18.//--定义一个全局变量--//19.unsigned char timer1;20.unsigned char IrValue[6]; //用来存放读取到的红外值21.unsigned char Time;22.23.//--声明全局函数--//24.void IrInit();25.void DelayMs(unsigned int );26.void Time1Config();27.void speedup();28.void Slowdown();29.void go();30.void left();31.void right();32.void pwm_left(int x);33.void pwm_right(int x);34./*******************************************************************************35.* 函数名 : main36.* 函数功能 : 主函数37.* 输入 : 无38.* 输出 : 无39.*******************************************************************************/40.41.void main()42.{43. PWM1=0;44. PWM2=0;45. IrInit();46. Time1Config();47. while(1)48. {49.50. IrValue[4]=IrValue[2]>>4; //高位51. IrValue[5]=IrValue[2]&0x0f; //低位52. if(IrValue[4]==0x0e&&IrValue[5]==0x08)53. {54.55. pwm_left(37);56. pwm_right(40);57.58. }59.60.61. if(IrValue[4]==0x0d&&IrValue[5]==0x04)62. {63.64. pwm_left(0);65. pwm_right(0);66.67. }68.69.//70. if(IrValue[4]==0x0e&&IrValue[5]==0x02)71. {72.73. pwm_left(35);74. pwm_right(22);75.76.77. }78.79. if(IrValue[4]==0x0e&&IrValue[5]==0x00)80. {81.82. pwm_left(22);83. pwm_right(35);84.85.86. }87.88. }89.90.}91.92.93.94.95.96.void pwm_left(int x)97.{98. if(timer1>100)//PWM周期为100*99. {100.101. timer1=0;102. }103.104. if(timer1 < x) //改变30这个值可以改变直流电机的速度105. {106.107. PWM1=1;108. }109.110. else111. {112.113. PWM1=0;114. }115.116.}117.118.void pwm_right(int y)119.{120. if(timer1>100)//PWM周期为100*121. {122.123. timer1=0;124. }125.126. if(timer1 < y) //改变30这个值可以改变直流电机的速度127. {128.129. PWM2=1;130. }131.132. else133. {134.135. PWM2=0;136. }137.138.}139./***************************************************************** **************140.* 函数名 : DelayMs()141.* 函数功能 : 延时142.* 输入 : x143.* 输出 : 无144.****************************************************************** *************/145.146.void DelayMs(unsigned int x) //误差 0us147.{148. unsigned char i;149. while(x--)150. {151.152. for (i = 0; i<13; i++)153. {}154. }155.156.}157./***************************************************************** **************158.* 函数名 : IrInit()159.* 函数功能 : 初始化红外线接收160.* 输入 : 无161.* 输出 : 无162.****************************************************************** *************/163.164.void IrInit()165.{166. IT0=1;//下降沿触发167. EX0=1;//打开中断0允许168. EA=1; //打开总中断169.170. IRIN=1;//初始化端口171. PWM1=0;172.173. PWM2=0;174.}175./***************************************************************** **************176.* 函数名 : ReadIr()177.* 函数功能 : 读取红外数值的中断函数178.* 输入 : 无179.* 输出 : 无180.****************************************************************** *************/181.182.void ReadIr() interrupt 0183.{184. unsigned char j,k;185. unsigned int err;186. Time=0;187. DelayMs(70);188.189. if(IRIN==0) //确认是否真的接收到正确的信号190. {191.192.193. err=1000; //1000*10us=10ms,超过说明接收到错误的信号194. /*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时195.侯,程序死在这里*/196. while((IRIN==0)&&(err>0)) //等待前面9ms的低电平过去197. {198.199. DelayMs(1);200. err--;201. }202.203. if(IRIN==1) //如果正确等到9ms低电平204. {205.206. err=500;207. while((IRIN==1)&&(err>0)) //等待的起始高电平过去208. {209.210. DelayMs(1);211. err--;212. }213.214. for(k=0;k<4;k++) //共有4组数据215. {216.217. for(j=0;j<8;j++) //接收一组数据218. {219.220.221. err=60;222. while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去223. {224.225. DelayMs(1);226. err--;227. }228.229. err=500;230. while((IRIN==1)&&(err>0)) //计算高电平的时间长度。
