红外避障电动小车C51程序
基于单片机的智能避障小车设计(C51语言编程)【开题报告】
开题报告电气工程及其自动化基于单片机的智能避障小车设计(C51语言编程)一、课题研究意义及现状随着电子技术的飞速发展,电子产品也越来越智能化和微型化。
世界玩具市场也因此越来越向电子化发展。
根据美国玩具协会调查统计,近年来全球的玩具市场越来越大,但是全球玩具市场的结构却发生了比较巨大的变换。
传统玩具的市场份额也在逐年的减少,智能电子玩具的市场份额则越来越多。
美国电子玩具工业的发展在21世纪出现了一个最大的变革,那就是科技(尤其是互联网)在玩具中的应用。
这种改变给玩具工业带来了无限机遇和挑战,美国的玩具市场由1996年的227亿美元到2005年的230亿美元。
并且在这些玩具中75%是装有电子设备的高科技玩具,电子玩具的兴起代表着玩具发展的“新时代”的开始。
因此,传统玩具中的益智玩具销售将领先。
给传统的洋娃娃、毛绒玩具安装上IC,将成一种潮流,机器人玩具过去由于生产成本高,外表缺吸引力,导致发展缓慢,随着生产成本的降低,外形的改进,教育性机器人玩具可能放异彩。
我们已经有理由相信:电子玩具的兴起代表着玩具发展的“新时代”的开始,电子玩具多彩的艺术表现形式是吸引孩子们到百货店挑选玩具的兴趣所在。
这些数据的表明,高新电子玩具已经成为玩具市场的主流。
在这些电子玩具中,智能小车是一个非常热门的玩具产品,智能小车,也称轮式机器人,是一种以汽车电子为背景,涵盖控制、模式识别、传感技术、电子、电气、计算机、机械等多学科的科技创意性设计,一般主要由路径识别、速度采集、角度控制及车速控制等模块组成。
我国是世界最大的玩具制造国和出口国,但是我国的玩具大部分都是以低廉的劳动力以及传统玩具来取得的,在高新技术以及玩具的附加值上不能与其他国家相比,随着当今智能玩具的发展,国内的玩具结构必须要做出改变,我们必须利用科技创新来提高玩具的附加值。
因此,高科技含量的电子互动式玩具必须是中国未来发展的趋势。
本次课题准备设计一种能够实时采集传感器信号、智能分析外部环境以及自动实现方向控制等功能的智能小车。
基于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单片机的红外遥控智能小车源程序(C语言)
/*预处理命令*/#include<reg52.h> //包含单片机寄存器的头文件#include<intrins.h> //包含_nop_()函数定义的头文件#define uchar unsigned char#define uint unsigned int#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};sbit IRIN=P3^2; //红外接收器数据线sbit LCD_RS = P0^7;sbit LCD_RW = P0^6;sbit LCD_EN = P0^5;uchar begin[]={"My car!"};uchar cdis1[]={"jiansu!"};uchar cdis2[]={"qianjin!"};uchar cdis3[]={"jiasu!"};uchar cdis4[]={"zuozhuang!"};uchar cdis5[]={"STOP!"};uchar cdis6[]={"youzhuan!"};uchar cdis8[]={"daoche!"};sbit M1 = P1^0;sbit M2 = P1^1;sbit M3 = P1^2;sbit M4 = P1^3;sbit EN12 = P1^4;sbit EN34 = P1^5;uchar IRCOM[7];uchar m,n;uchar t=2;uchar g;uchar code digit[]={"0123456789"};uint v;uchar count;bit flag;void delayxms(uchar t);void delay(unsigned char x) ;void delay1(int ms);void motor();void lcd_display();/*检查LCD忙状态lcd_busy为1时,忙,等待。
自动避障红外电动小车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 );
基于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}。
电视遥控器的C51解码程序及其控制的电动遥控玩具车举例
电视遥控器的C51解码程序及其控制的电动遥控玩具车举例彩色电视红外线遥控器小巧方便,抗干扰能力强,遥控距离远,得到广泛应用。
其基本原理是通过键盘产生编码,对38K 载波调制,经放大,形成一串串脉冲由红外线发射管发射出去,现以M50462AP 集成电路的遥控器为例,介绍其编码及其用C 语言实现的解码程序。
彩电遥控器由键盘、M50462AP 和红外发射管等组成,电原理图如图1:图1脉冲宽度0.25MS ,编码为“1”时,脉冲间隔为1MS ,编码为“0”时,脉冲间隔为2MS ,如图3: 编码“0” 编码“1”图3指令前8位为引导码,后8位为功能码,M50462AP 中的引导码C0~C7由1110XX10组成,C4、C5由外引脚C4、C5控制,当C4、C5悬空或为“1”时,C4、C5为0,反之为1,如以熊猫牌遥控器为例,其引导码为“11100010”即十六进制“E2H ”,按键时间必须大于18MS 才能被确认,具有自动消抖功能,按键22MS 后开始发送指令,指令周期为44MS ,如此循环发送,直到按键被释放。
其编码及其对应的功能按键如表一:表一电视遥控器的解码由一片目前广泛使用、体积小而功能极强的AT89C2051单片机作解码芯片,该单片机内含128B RAM,2K Flash ROM,15根I/O口线,5个中断源,一个全双工串口,2个定时器/计数器,2个外部中断,时钟频率最高可达24M HZ,而外部引脚仅为20个。
遥控接收头直接接89C2051的INT0端,解码利用了定时器T0的门控位GA TE位功能捕捉脉冲间隔宽度,即定时器工作不仅要允许位TR0置位,还要INT0引脚为高电平才能开始定时,定时器T0工作在十六位定时器方式,解码如图4:图4至于定时数值的判定,初值为0,以逻辑“1”为例,晶振f=6M HZ,脉宽T=1.75MS,由计算知:count:=T/(1/f)=875=36BH 由于本文为实验,故仅判定TH0的值,而又因有误差,认为只要TH0大于等于3即为“1”,否则为“0”,详细见中断流程图。
寻迹避障小车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; // 只有。
基于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)) //计算高电平的时间长度。
基于51单片机的红外遥控-自动避障-贴墙行走-人体感应智能小车机器人
基于51单片机的红外遥控-自动避障-贴墙行走-人体感应智能小车机器人队员1姓名:周葛学院:仪器科学与电器工程学院专业:测控技术与仪器年级:大一教学号:65130109邮箱:zhouge94@队员2姓名:成妍学院:药学院专业:生物医学工程(再生医学)年级:大一教学号:73130430邮箱:lianyungangcheng@作品类别:基本电子技术应用类目录一、引言 (1)二、总体设计 (1)三、单元电路设计 (2)1)单片机最小驱动模块 (2)2)红外接收模块 (3)方案选择 (3)方案确定 (3)理论分析与方案论证 (3)3)电机驱动模块 (4)4)避障循迹贴墙模块 (5)方案选择 (5)方案确定 (5)理论分析与方案论证 (6)5)电源模块 (7)6)人体感应模块 (7)四、软件设计 (8)五、整体测试 (8)六、结论 (9)【参考文献】 (9)【附录】 (10)源程序 (10)一、引言以STC89C52单片机为核心,制作一款红外线遥控小车,小车具有自动驾驶、手动驾驶和循迹前进等功能。
自动驾驶时,小车在前进过程中可以自动躲避障碍物。
手动驾驶时,可以手动遥控小车前进、后退、左转、右转、加速等操作。
寻迹时小车可以按轨迹前进。
红外遥控的特点是利用红外线进行点对点通信的技术,不影响周边环境,不干扰其他电器设备。
室内近距离(小于10米),信号无干扰、传输准确度高、体积小、功率低的特点,遥控中得到了广泛的应用。
本系统采用成品红外发射遥控器,具有21个按键,采用NEC红外传输协议。
接收端使用1838一体化接受头,通过单片机中断程序处理红外信号。
二、总体设计本系统由硬件和软件两部分组成。
硬件部分由红外线接受电路,控制电路,直流电机驱动,障碍物检测电路,人体感应电路五部分组成,完成红外编码信号的接受,直流电机的驱动,障碍物检测、墙体检测、地面检测,人体感应检测等功能。
软件部分主要完成信号的检测和处理、直流电机的控制,障碍物的规避等功能。
基于51单片机的智能循迹避障小车C源程序
项目名称:智能小车系别:信息工程系专业:11电气工程及其自动化姓名:刘亮、崔占闯、韩康指导教师:王蕾崔占闯联系邮箱:目录摘要: ...............................................................................................3关键词: (3)绪论: (3)一、系统设计 (4)1.一、任务及要求 (4)1.2车体方案认证与选择 (4)二、硬件设计及说明 (5)2.1循迹+避障模块 (5)2.2主控模块 (6)2.3电机驱动模块 (6)2.4机械模块 (7)2.5 电源模块 (7)三、自动循迹避障小车整体设计 (7)四、软件设计及说明 (8)4.1系统软件流程图 (9)4.2系统程序 (9)五、系统测试进程 (12)六、总结 (13)七、附录:系统元器件 (13)摘要本设计要紧有三个模块包括信号检测模块、主控模块、电机驱动模块。
信号检测模块采纳红外光对管,用以对有无障碍与黑线进行检测。
主控电路采纳宏晶公司的8051核心的STC89C52单片机为操纵芯片。
电机驱动模块采纳意法半导体的L298N专用电机驱动芯片,单片操纵与传统分立元件电路相较,使整个系统有专门好的稳固性。
信号检测模块将搜集到的路况信号传入STC89C52单片机,经单片机处置事后对L298N发出指令进行相应的调整。
通过有无光线接收来操纵电动小车的转向,从而实现自动循迹避障的功能。
关键词:智能循迹避障小车,STC89C52单片机,L298N驱动芯片,信号检测模块,循迹避障绪论(一)智能小车的作用和意义自第一台工业机械人诞生以来,机械人的进展已经遍及机械、电子、冶金、交通、宇航、国防等领域。
最近几年来机械人的智能水平不断提高,而且迅速地改变着人们的生活方式。
人们在不断探讨、改造、熟悉自然的进程中,制造能替代人劳动的机械一直是人类的妄图。
随着科学技术的进展,机械人的感系统,关于视觉的各类技术而言图像处置技术已相当发达,而基于图像的明白得技术还很掉队,机械视觉需要通过大量的运算也只能识别一些结构化环境简单的目标。
《基于51单片机的红外避障自动车的实现》技术报告
《基于51单片机的红外避障自动车的实现》技术报告技术报告:基于51单片机的红外避障自动车的实现引言红外避障技术在自动车领域中具有重要的应用潜力。
本报告旨在介绍一种基于51单片机的红外避障自动车的实现方法。
该自动车能够通过红外遥感技术检测周围环境并避开障碍物,实现自主导航功能。
一、系统硬件设计1.硬件平台选择本系统主要采用51单片机作为主控制器,因其资源丰富、易于编程和低成本等特点。
另外,还需要模块包括红外传感器模块和马达驱动模块。
2.红外传感器模块设计红外传感器模块通过红外发射管和接收管组成。
发射管发出红外光,在遇到障碍物时,被障碍物反射回的红外光通过接收管被接收到。
根据接收到的光线强度和反射时间,可以确定是否有障碍物存在。
3.马达驱动模块设计马达驱动模块通过电路连接到51单片机输出口,用于控制电机的转动。
当检测到有障碍物存在时,系统会发送信号给马达驱动模块,从而控制车辆停止或改变方向。
二、系统软件设计1.硬件初始化在程序的开始部分,需要对51单片机和各个硬件模块进行初始化,包括设置引脚的输入输出方式、红外传感器和马达的初始化等。
2.红外传感器数据采集与处理通过相关的接口和程序代码,可以实现对红外传感器的数据采集和处理。
利用红外传感器模块发射红外光,并通过接收模块接收到反射的光线信号。
通过采集到的信号强度和反射时间,可以判断是否有障碍物存在。
3.障碍物检测与避障根据红外传感器采集到的数据,判断是否有障碍物存在。
如果有障碍物,则需要控制车辆停止或改变方向来避开障碍物。
通过控制马达驱动模块,可以实时改变车辆的行驶方向。
4.车辆导航控制车辆导航控制部分主要是根据红外传感器采集到的数据和障碍物检测结果,实时控制车辆的行驶方向。
通过对数据的处理和逻辑判断,可以决定车辆的下一步行动,例如前进、后退、左转或右转等。
三、实验结果与讨论在实验中,我们成功实现了基于51单片机的红外避障自动车的功能。
通过红外传感器模块,我们可以有效地检测到周围的障碍物,并及时避开,实现了自主导航。
51自动避障小车整体程序
#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit Trig=P3^0;sbit Echo=P3^3;sbit control=P3^5;uint dis,flag=0,timeH,timeL,succeed_flag,time;void tran_ret();void delay_nus(uint n);void delay_ms(long int m);void delay_n100us(uint n);void run();//void backrun();//void freestop();void turnleft();void turnright ();void Sturnround();void Nturnround();void servo_turn(int gao);//********************************************************************** //主函数void main(){TMOD=0x01;EA=1;ET0=1;IT1=0;Trig=0;servo_turn(0);delay_ms(5000);while(1){tran_ret();if(dis>30){run();}else{P1=0XFF;servo_turn(-90);delay_ms(5000);tran_ret();if (dis>30){turnleft();P1=0XFF;servo_turn(0);delay_ms(5000);run();}else{P1=0XFF;servo_turn(90);delay_ms(5000);tran_ret();if (dis>30){turnright();servo_turn(0);delay_ms(5000);run();}else{Nturnround ();servo_turn(0);delay_ms(5000);run();}}}}}//***************************************************************************** ********//子函数//***************************************************************************** *********//全速前进void run(){P1=0xaa;//delay_ms(60);//P1=0xff;}/*//全速后退void backrun() { P1=0x55;delay_ms(19);P1=0x00;delay_ms(1); } *///自由停止/*void freestop () {P1=0x00;delay_ms(20); } *///左转void turnleft() {P1=0x0a;delay_ms(100);//P1=0xff;}//右转void turnright() {P1=0xa0;delay_ms(100); // P1=0xff;}/*//原地顺时针打转void Sturnround() {P1=0xa0;delay_ms(40);P1=0x00;delay_ms(1); } *///原地逆时针打转void Nturnround () {P1=0x0a;delay_ms(100);// P1=0x00;}//发射void tran_ret(){EA=0; //关总中断Trig=1; //超声波输入端delay_nus(20);//延时20usTrig=0; //产生一个20us的脉冲while(Echo==0); //等待Echo回波引脚变高电平succeed_flag=0; //清测量成功标志EA=1;EX1=1; //打开外部中断0TH0=0;//定时器1清零TL0=0; //定时器1清零TF0=0; //计数溢出标志ET0=1;TR0=1; //启动定时器1delay_ms(20); //等待测量的结果TR0=0; //关闭定时器1EX1=0; //关闭外部中断0if(succeed_flag==1){time=timeH*256+timeL;dis=time*0.0182; //cm/////12MHZ疑问之处us//////////////////////////////////////// display(distance);}if(succeed_flag==0){dis=200; ////////////// test = !test; //测试灯变化}}//延时函数1void delay_ms(long int n){uint i,j;for(i=n;i>0;i--)for(j=110;j>0;j--);}//延时函数2void delay_nus(uint n){uint i;for(i=n;i>0;i--);}//延时函数3void delay_n100us(uint n){uint i;while(n--){for(i=7;i>0;i--);}}//中断函数void exter1() interrupt 2 // 外部中断1 {timeH =TH0; //取出定时器的值timeL =TL0; //取出定时器的值succeed_flag=1;//至成功测量的标志EX1=0; //关闭外部中断TR0=0;}void servo_turn(int offset){int servo,gao;control=0;servo=14;offset/=9;gao=servo-offset;control=1;delay_n100us(gao);control=0;delay_n100us(200-gao);}。
红外循迹c51程序
#inclu de<re g52.h>#de fineuintunsig ned i nt#defin e uch ar un signe d cha ruin t i,t;lon g cou nter;//编码器脉冲数值u charfinis h=0;//停车标志//--------传感器变量------------s bit r i1=P0^0; //*左边传感器*//sbit ri2=P0^1;sbit ri3=P0^2;sbit mid=P0^3;//*中间传感器*//sbi t le3=P0^4;sbi t le2=P0^5;sbi t le1=P0^6;//*右边传感器*//sb it bz=P2^7;//蔽障管//-------电机舵机控制变量-----------sbit ENA=P1^0; //驱动电机pwm//sb it mo to1=P1^1;//电机控制//s bit m oto2=P1^2;sbit PWM=P1^4; //舵机pwm////---------转角变量---------uint angl e;ui nt ab solut e(int);//--------速度变量----------ui nt pr o; //驱动电机调速uin t car_driv er; //驱动力参数ui nt pu lse_s peed; //电机当前速度uintideal_spee d; //理想状态下的速度i nt sp eed_e rror; //理想速度与当前速度的差值intpre_e rror=0; //PID控制的速度差值intpre_d_erro r=0;//PID控制的速度上一次的差值int pk=0,erro r=0;//速度的PID值int s peedm ax;//----------表格值----------uintcodespeed_tabl e[]={50,40,40};uint code angl e_tab le[]={110,75,110};#defin e kp213#defin e ki7#de finekd 15//-----------函数定义-------void init();v oid d elay(uint);voi d qct yp();void duoj i();voidcarpo sitio n();voidspeed();v oid p id();//=============主函数==========voidmain(){init();while(1){q ctyp();carp ositi on();sp eed();}}//===========子函数============//-----------初始化-----------voi d ini t(){TMO D=0x11;//设定双定时器EA=1;//EX0=1;//开外部中断0// T CON=0x01;TR0=1;T R1=1;TH0=(65536-20000)/256;TL0=(65536-20000)%256;//设定定时初始值,可去下载个定时器计算软件,20m sTH1=(65536-1000)/256;TL1=(65536-1000)%256;E T0=1;ET1=1;ENA=1;pu lse_s peed=0;s peedm ax=0;}//---------延时函数----------v oid d elay(uintn){ucha r a,b,c;for(c=1;c>0;c--)f or(b=n;b>0;b--)f or(a=2;a>0;a--);}//-------光电管全无状态时(脱离轨道),读取前次状态---------voidqctyp(){ri1=P0^0;r i2=P0^1;ri3=P0^2;mid=P0^3;le3=P0^4;l e2=P0^5;le1=P0^6;}//-------循迹函数,读取光电管状态------------vo id ca rposi tion(){if(!le1&&!le2&&!le3&&mid&&!ri3&&!r i2&&!ri1){angle=0;}el se if(le3&&!mid&&!ri3&&!r i2&&!ri1){angle=1;}el se if(le2&&!mid&&!ri3&&!r i2&&!ri1){angle=1;}el se if(le1&&!mid&&!ri3&&!r i2&&!ri1){angle=1;}el se if(ri1&&!mid&&!le3&&!l e2&&!le1){angle=2;}el se if(ri2&&!mid&&!le3&&!l e2&&!le1){angle=2;}el se if(ri3&&!mid&&!le3&&!l e2&&!le1){angle=2;}}//-----------舵机控制-------------void duoj i() //舵机控制{P WM=1;del ay(an gle_t able[angle]); //可改变舵机转向角度PW M=0;}//-----------------计算车的速度-----------------voi d spe ed(){ /*if(speed max<=pulse_spee d) speed max=p ulse_speed;if(sp eedma x>=40) s peedm ax=40;pi d();pro=car_d river;//变量y是改变小车速度这里范围是0--39*/p ro=sp eed_t able[angle];m oto1=1;m oto2=0; }//------------PID控制----------------/*void pid(){signe d int d_e rror, dd_e rror; //e rror=speed_erro rid eal_s peed=speed_tabl e[ang le];erro r=ide al_sp eed-p ulse_speed;d_error=erro r-pre_erro r; //d_er ror 当前速度差与上一次速度差之差dd_er ror=d_erro r-pre_d_er ror;pre_error=erro r; //存储当前偏差pre_d_err or=d_error;pk+=kp*d_err or+ki*erro r+kd*dd_er ror;if(p k<=0)p k=0;else if(p k>=40) pk=40;car_drive r=pk;}//-----------中断---------------voi d ext er0() inte rrupt 0{coun ter++;}*/vo id ti mer0() int errup t 1//产生pwm信号控制舵机,周期20ms{TH0=(65536-20000)/256;//1011 0001 即TH O=(65536-20000)/256TL0=(65536-20000)%256; //1110 0000即TLO=(65536-20000)%256duoji();}void time r1()inter rupt3//产生pwm信号控制驱动电机速度{TH1=(65536-1000)/256;TL1=(65536-1000)%256;i++;i f(i<=pro){ ENA=1;}el se{EN A=0;}i f(i==50){E NA=~E NA;i=0;}/* t++;if(t==1000){t=0;pul se_sp eed=4*coun ter/500; //速度=编码器主动轮周长(M)*脉冲/分辨率coun ter=0;} */}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
红外避障电动小车C51程序时间:2009-05-13 来源: 作者: 点击:1400 字体大小:【大中小】#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 //前进#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#define right_light 0XaF //右转向灯0xaf,两个是0xbf#define back_light 0XcF //刹车灯即后灯#define front_light 0x3f //前灯#define light_on 0xff //开所有灯#define true 1#define false 0#define LCD_Data P0#define Busy 0x80 //用于检测LCD状态字中的Busy标识sbit c=P1^2; //转向灯使能端uchar code talk1[]={"backward"};uchar code talk2[]={"forward"};uchar code talk3[]={"Turnleft"};uchar code talk4[]={"Turn right"};uchar flage =0x00;sbit ledcs=P1^2; //74H573的片选信号//sbit left_led=P0^2; //左红外发射管//sbit right_led=P0^3; //右红外发射管sbit LCD_RS = P1^5; //LCD定义引脚sbit LCD_RW = P1^6; //sbit LCD_E = P1^7 ;void Delay5Ms(void){uint TempCyc = 5552;while(TempCyc--);}//400ms延时void Delay400Ms(void){uchar TempCycA = 5;uint TempCycB;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;LCD_E = 1;while (LCD_Data & Busy); //检测忙信号return(LCD_Data);}//LCD写数据void WriteDataLCD(unsigned char WDLCD ){ReadStatusLCD(); //检测忙LCD_Data = WDLCD;LCD_RS=1;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时忽略忙检测 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); //三次显示模式设置,不检测忙信号Delay5Ms();WriteCommandLCD(0x38,0);Delay5Ms();WriteCommandLCD(0x38,0);Delay5Ms();WriteCommandLCD(0x38,1); //显示模式设置,开始要求每次检测忙信号WriteCommandLCD(0x08,1); //关闭显示WriteCommandLCD(0x01,1); //显示清屏WriteCommandLCD(0x06,1); // 显示光标移动设置WriteCommandLCD(0x0C,1); // 显示开及光标设置}//按指定位置显示一个字符void DisplayOneChar(uchar X, uchar Y, uchar DData){Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1if (Y)X |= 0x40; //当要显示第二行时地址码+0x40;X |= 0x80; // 算出LCD的指令码WriteCommandLCD(X, 0); //这里不检测忙信号,发送地址码WriteDataLCD(DData);}//按指定位置显示一串字符(只能写一行);void DisplayListChar(uchar X, uchar Y,uchar ListLength, uchar *DData,uchar n) { uchar i;Y &= 0x01;X &= 0x0F; //限制X不能大于15,Y不能大于1for(i=0;i<ListLength;i++){ if (X <= 0x0F) //X坐标应小于0xF{ DisplayOneChar(X, Y, DData[i]); //显示单个字符if(n==true)Delay400Ms();X++;}}}/****************************红外线接收子程序,利用了中断的下降沿触发方式****************************/void infrared_ray()interrupt 0 using 3{ uchar i=90;flage=0x01; //接受标志位while(i--); //减小灵敏度EX0=0; //关掉中断,等到发射方波后才开启,处于别动}// 延时子程序void delay(uint n){while(--n);}//中断初始化void Init0(void){ EA=1;IT0=1;}/***************************************/*原理是把中断打开并发射方波,当有中断时就转到中断产生中断位为下一步转向做准备,当没有是关闭中断****************************************/void seng_wave(uchar timer,bit n)//timer通过载波发射信号的时间,n->左右发射管的选择{ uchar i;P1 |= 0X04; //ledcs=1为74ls573为11脚为高电平时数据直接输出,为低时把数据锁存住,即保持IE |= 0X01;P0 |=0x0c; //04for(i=timer;i>0;i--){ if(n)P0^=0x08; // 右发射管通过载波发射信号//00else P0^=0x04; // 左发射管通过载波发射信号//0cdelay(100); //这里控制着灵敏度(控制38khz的方波的多少)和距离} //timer*delay(x)即为发射管得到的平均电流P1 &= 0Xfb;IE &= 0Xfe;}//led转向灯指示子程序void light_control(uchar deng){ ledcs=1;P0 =deng;ledcs=0; //11111011}//电机和灯光的控制部分void control(uchar n,uchar dj_state,uchar light){ 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;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--){delay(2000);}P2=dj_state5; //停车light_control(light_off); //led关闭WriteCommandLCD(0x01,1); //LCD显示清屏P2=dj_state1; //前进if(dj_state1){ P1|=0X04; //ledcs=1;P0=0x0f;P1&=0XFB;delay(100);DisplayListChar(0,0,7,talk2,false);}}/****************************************避障主要控制部分*****************************************/void move_car(void){uchar temp =0x00;//左边红外管发射seng_wave(1,left_infrare); //向下为中断开启有关闭后,要执行的语句if(flage==0x01){temp|=0x01;flage=0x00;}//右边红外管发射delay(30);seng_wave(1,right_infrare); //向下为中断开启有关闭后,要执行的语句if(flage==0x01){temp|=0x02;flage=0x00;}//左边有障碍物,右转if(temp==0x01){control(2,dj_state2,left_light); temp =0x00;}//右边有障碍物,左转else if(temp==0x02) {control(2,dj_state3,right_light ); temp =0x00;}//两个方向都有障碍物,后退,右转else if(temp==0x03) {control(10,dj_state4,back_light );control(5,dj_state2,right_light ); temp =0x00;}}void main(void){ Init0(); //中断初始化P1 |= 0X04; //开锁存器的控制位P0 = 0xFf; //数据口的清零P1&=0XFB; //关锁存器的控制位LCDInit(); //LCD初始化WriteCommandLCD(0x01,1); //显示清屏delay(100);P2=dj_state1;DisplayListChar(0,0,8,talk2,false);while(1){ move_car(); //主要控制部分delay(200000);//延时}}。