#define uchar unsigned ch">

红外避障电动小车C51程序

红外避障电动小车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);//延时}}。

合集下载

基于单片机的智能避障小车设计(C51语言编程)【开题报告】

基于单片机的智能避障小车设计(C51语言编程)【开题报告】

开题报告电气工程及其自动化基于单片机的智能避障小车设计(C51语言编程)一、课题研究意义及现状随着电子技术的飞速发展,电子产品也越来越智能化和微型化。

世界玩具市场也因此越来越向电子化发展。

根据美国玩具协会调查统计,近年来全球的玩具市场越来越大,但是全球玩具市场的结构却发生了比较巨大的变换。

传统玩具的市场份额也在逐年的减少,智能电子玩具的市场份额则越来越多。

美国电子玩具工业的发展在21世纪出现了一个最大的变革,那就是科技(尤其是互联网)在玩具中的应用。

这种改变给玩具工业带来了无限机遇和挑战,美国的玩具市场由1996年的227亿美元到2005年的230亿美元。

并且在这些玩具中75%是装有电子设备的高科技玩具,电子玩具的兴起代表着玩具发展的“新时代”的开始。

因此,传统玩具中的益智玩具销售将领先。

给传统的洋娃娃、毛绒玩具安装上IC,将成一种潮流,机器人玩具过去由于生产成本高,外表缺吸引力,导致发展缓慢,随着生产成本的降低,外形的改进,教育性机器人玩具可能放异彩。

我们已经有理由相信:电子玩具的兴起代表着玩具发展的“新时代”的开始,电子玩具多彩的艺术表现形式是吸引孩子们到百货店挑选玩具的兴趣所在。

这些数据的表明,高新电子玩具已经成为玩具市场的主流。

在这些电子玩具中,智能小车是一个非常热门的玩具产品,智能小车,也称轮式机器人,是一种以汽车电子为背景,涵盖控制、模式识别、传感技术、电子、电气、计算机、机械等多学科的科技创意性设计,一般主要由路径识别、速度采集、角度控制及车速控制等模块组成。

我国是世界最大的玩具制造国和出口国,但是我国的玩具大部分都是以低廉的劳动力以及传统玩具来取得的,在高新技术以及玩具的附加值上不能与其他国家相比,随着当今智能玩具的发展,国内的玩具结构必须要做出改变,我们必须利用科技创新来提高玩具的附加值。

因此,高科技含量的电子互动式玩具必须是中国未来发展的趋势。

本次课题准备设计一种能够实时采集传感器信号、智能分析外部环境以及自动实现方向控制等功能的智能小车。

基于51单片机的红外避障+超声波避障程序

基于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语言)

基于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程序

自动避障红外电动小车C51程序
#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"};
****************************/
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单片机的避障小车程序

基于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学习型红外线遥控程序——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)) //计算高电平的时间长度。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档