首页 > 其他分享 >【IoT】红外避障小车

【IoT】红外避障小车

时间:2023-02-01 10:31:08浏览次数:44  
标签:delay 避障 小车 void IoT char sbit LCM nop


言​

随着生产自动化的发展需要,机器人已经越来越广泛地应用到生产自动化上,随着科学技术的发展,机器人的传感器种类也越来越多,其中红外传感器已经成为自动行走和驾驶的重要部件。

红外的典型应用领域为自主式智能导航系统,机器人要实现自动避障功能就必须要感知障碍物,感知障碍物相当给机器人一个视觉功能。智能避障是基于红外传感系统,采用红外传感器实现前方障碍物检测,并判断障碍物远近。而利用红外对不同颜色物体反射强弱差别又可以实现循迹功能。​

由于时间和水平有限,我们暂选最基本的避障,循迹功能作为此次设计的目标。​

本设计通过小车这个载体再结合由STC89C52为核心的控制板可以达到其基本功能,再辅加由漫反射式光电开关组成的避障电路,基于PWM技术的转速控制、电源电路、电机驱动电路就可以完善整个设计。​

1.【摘 要】:本文提出一种智能避障,循迹小车的设计方法,利用红外技术检测障碍物,轨迹信息,采用STC89C52单片机进行实时控制,实现智能避障,智能小车采用前轮驱动,两轮各用一个直流电机控制,避障,循迹用的传感器采用红外漫反射式传感器。​

【关键词】: 避障 循迹 光电开关 差分控制​

PWM LCD 测速​


2. 功能概述

智能小车采用前轮驱动,前轮左右两边各用一个电机驱动,分别控制两个轮子的转动从而达到转向的目的,后轮是万向轮,起支撑的作用。避障部分,将3个红外线光电传感器分别装在车体的左中右,当车的左边的传感器检测到障碍物时,主控芯片控制右轮电机停止左轮转动,车向右方转向,当车的右边传感器检测到障碍物时,主控芯片控制左轮电机停止转动,车向左方转向,当前面有障碍物时规定车右转。而当小车同时有两个传感器接收到信号时,采用倒退方式转弯以避免碰到障碍物,于此同时测定速度并显示,在避障小车前进的同时从LCD点阵液晶显示器上显示小车当时速度和行驶的路程。​

循迹部分,采用七个红外传感器置于车身前下方,中间五个主要用于循迹普通道路,外边两个略比中间的靠前,主要用来检测直角弯道。车向左偏时右拐,右偏时左拐,左右拐又分为校正和转弯两档。遇到直角时极易冲出跑道,故给车施加一个反向脉冲。行驶过程中显示屏显示车速及路程。​

3.硬件设计

如下图所示,是本次设计智能小车的电路框图。以STC89C52为电路的中央处理器,来处理传感器采集来的数据,处理完毕之后以便去控制电机驱动电路来驱动电机。电源部分是为整个电路模块提供电源,以便能正常工作。​



【IoT】红外避障小车_单片机

【IoT】红外避障小车_红外_02



4. 避障电路

(1) 障碍物探测方案的选择

方案一:脉冲调制的反射式红外线发射接受器。由于采用该有交流分量的调制信号,则可大幅度减少外界干扰;另外红外线接受官的最大工作电流取决于平均电流。如果采用占空比小的调制信号,再品均电流不变的情况下,顺势电流很大(50—100mA),则大大提高了信噪比。并且其反应灵敏,外围电路也很简单。它的优点是消除了外界光线的干扰提高了灵敏度。​

方案二:采用超声波传感器,如果传感器接收到反射的超声波,则通知单片机前方有障碍物,如则通知单片机可以向前行驶。市场上很多红外光电探头也都是基于这个原理。这样不但能准确完成测量,而且能避免电路的复杂性​

由以上两种方案比较可知。方案一要比方案二优势大,市场上很多红外观点探头也都基于这个原理。其电路简单,工作可靠,性能比较稳定。从而避免了电路的复杂性,因此我先用方案二作为小车的监测系统。​

避障电路采用漫反射式光电开关进行避障。光电开关是集发射头和接收头于一体的检测开关,其工作原理是根据发射头发出的光束,被障碍物反射,接收头据此做出判断是否有障碍物。当有光线反射回来时,输出低电平;当没有光线反射回来时,输出高电平。单片机根据接收头电平的高低做出相应控制,避免小车碰到障碍物,由于接收管输出TTL电平,有利于单片机对信号的处理。​

光电开关工作原理:

光电开关是通过把光强度的变化转换成电信号的变化来实现控制的。
光电开关在一般情况下,有三部分构成,它们分为:发送器、接收器和检测电路。​



【IoT】红外避障小车_红外_03





【IoT】红外避障小车_智能车_04



避障电路功能表:​

传感器​

避障电路输出(上升沿动作)​

待执行命令​

左​

中​

右​

左转信号(P2.1)​

右转信号(P2.0)​

0​

0​

0​


√​

后右转​

0​

0​

1​


√​

右转​

0​

1​

0​


√​

右转​

0​

1​

1​


√​

右转​

1​

0​

0​

√​


左转​

1​

0​

1​


√​

右转​

1​

1​

0​

√​


左转​

1​

1​

1​



前进​

注解(“0”表示有障碍物; “1”表示无障碍物)​

【IoT】红外避障小车_单片机_05


(2)信号检测模块

小车循迹原理是小车在画有黑线的白纸

红外探测法,即利用红外线在不同颜色的物理表面具有不同的反射性质的特点。在小车行驶过程中不断地向地面发射红外光,当红外光遇到白色地面时发生漫发射,反射光被装在小车上的接收管接收;如果遇到黑线则红外光被吸收,则小车上的接收管接收不到信号,再通过LM324作比较器来采集高低电平,从而实现信号的检测。避障亦是此原理。电路图如图3.4。​

市面上有很多红外传感器,在这里我选用TCRT5000型光电对管。​

【IoT】红外避障小车_智能车_06


图3.4循迹原理图​


4. 单片机电路

本设计的主控芯片选择STC89C52,负责检测传感器的状态并向电机驱动电路发出动作命令。复位电路采用手动复位。​


【IoT】红外避障小车_智能车_07

单片机电路如下:​




5. 电机转速控制电路

转速控制采用基于PWM技术的脉冲调制技术,通过单片机输出两列PWM信号,经过l298N对电机进行速度调控。

6. 电源电路

本系统所有芯片都需要+5V的工作电压,而干电池只能提供的电压为1.5V的倍数的电压,并且随着使用时间的延长,其电压会逐渐下降,故采用了一个12v蓄电池,再用LM7805稳压芯片。L7805能提供最大1A的电流,足以满足芯片供电的要求。虽然微处理器和微控制器不需要支持电路,功耗也很低,但必须要加以考虑。 ​


电源电路拟定为:​

【IoT】红外避障小车_单片机_08


7.电机驱动电路

市场上用很多种类的小电压直流电动机,很方便的选择到。主要有普通电动机、和步进电动机。​

方案一:采用步进电机,步进电动机的一个显著的特点就是具有快速启动和停止能力,能够达到我们所要求的标准。如果负荷不超过步进电机所能提供的动态转矩值,就能够立即是步进电机启动或反转。其转换灵敏度比较高。正转、反转控制灵活。但是步进电机的价格比较昂贵,对于我们的现状相差太远。​

方案二:采用普通的直流电机。直流电机具有优良的调速特性,调速平滑、方便。调整范围广;过载能力强,能承受频繁的冲击负载,可实现频繁的无极快速启动、制动和反转。能满足各种不容的特殊运行要求。​

由于普通直流电机价格适宜,更易于购买,并且电路相对简单,因此采用直流电机作为动力源


本设计采用L298N驱动使电机正反转从而做到前进,左转右转。​

【IoT】红外避障小车_智能车_09


驱动电路(参考文献[4])

电机驱动一般采用H桥式驱动电路,L298N内部集成了H桥式驱动电路,从而可以采用L298N电路来驱动电机。通过单片机给予L298N电路PWM信号来控制小车的速度,起停。其引脚图如3.2,驱动原理图如图3.3。​



【IoT】红外避障小车_红外_10


图3.2 L298N引脚图​



【IoT】红外避障小车_智能车_11


图3.3 电机驱动电路​



【IoT】红外避障小车_红外_12




源程序:

#include<reg52.h>​

#include <intrins.h>​

#include <string.h>​

#define Busy 0x80 //用于检测LCM状态字中的Busy标识​

#define LCM_Data P0​

#define uchar unsigned char​

sbit LCM_RS=P2^2; //1602寄存器选择​

sbit LCM_RW=P2^1; //读/写控制​

sbit LCM_E=P2^0;​


sbit LLT=P1^7;//避障口​

sbit RLT=P2^7;​

sbit MLT=P3^4;​


sbit S1=P1^0; 传感器信号输入端口​

sbit S2=P1^1;​

sbit S3=P1^3;//INT​

sbit S4=P1^5;//LLT​

sbit S5=P1^6;//RLT​

sbit S6=P1^2;​

sbit S7=P1^4;//OUT​


sbit LH=P2^3; 电机1 左轮​

sbit LL=P2^4;​


sbit RH=P2^5; 电机2 右轮​

sbit RL=P2^6;​


sbit ENA=P3^6;//电机左轮使能​

sbit ENB=P3^7;//电机右轮使能​



sbit key1=P3^0;​

sbit key2=P3^1; ​

sbit key3=P3^2;​

sbit key4=P3^3;​

/******************************************************​

* 名 称:引脚定义​

* 功 能:引脚定义​

* 入口参数:无​

* 出口参数:无​

*******************************************************/​




unsigned char ​

character1[][8]={{0x2,0x02,0x2,0x02,0x1F,0x02,0x06,0x7},{0x00,0x0F,0x8,0x08,0xF,0x08,0x08,0x0F},​

{0x00,0x1C,0x4,0x4,0x1C,0x4,0x4,0x1C},{0xA,0xA,0x2,0x02,0x02,0x02,0x02,0x2},{0x19,0x09,0x8,0x08,0x8,0x0A,0x0C,0x08},​

{0x2,0x4,0x18,0x10,0x8,0x4,0x2,0x03}};​



int C1=0,C2=0,C3;//计数单位​

static int SU0=0,SU1=0,SU2=0,SU=0;​

static int SU3=0,V=0,V0=0,V1=0;​




int tmp1=0,tmp2=0;//左右占空比调整tmp/T​

int SPEED1,SPEED2;​


uchar count=0; //初始化计数变量​

uchar T=90; //pwm信号周期T*100us​

/***********************************************************************​

测距模块儿​

***********************************************************************/​


void delay10us() //延时,>10us​

{​

_nop_( ); ​

_nop_( ); ​

_nop_( ); ​

_nop_( ); ​

_nop_( ); ​

_nop_( ); ​

_nop_( ); ​

_nop_( ); ​

}​


int mainceju()​

{​


char T;​

int START,END,longth;​

S3=0;S4=0;//初始化接口值​

S4=1; //开始发射脉冲​

delay10us(); //延时​

while(!S3); //等待返回信号​

START=(TH2*256+TL2);//开始计时​

while(S3); //等待返回信号结束​

END=(TH2*256+TL2);//关闭计时器​


T=(TH0*256+TL0); //计算返回脉冲时间​

lnotallow=340*T/20000;//计算测距结果厘米​




return(longth);​




}​




/*****************************************************************************************************​

循迹模块儿​

****************************************************************************************************/​

/******************************************************​

*名 称elay(long int Delay_time)​

*功 能:延时​

*入口参数:Delay_time​

*出口参数:无、​

*说 明: 延时​

******************************************************/​


void delay(long int Delay_time)//延时函数​

{​

int i;​

while(Delay_time)​


{​

for(i=0; i<150;i++)​

{​

_nop_(); ​

_nop_();​

_nop_();​

_nop_();​

}​

Delay_time--;​

}​

}​


//-----------------------------------------------​

void correct_left()//向左校正,赋值​

{​

tmp1=T-30;​

tmp2=T-15;​

LH=1;​

LL=0;​

RH=1;​

RL=0;​

}​

//------------------------------------------------​

向右校正,赋值​

{​

tmp1=T-15;​

tmp2=T-30;​

LH=1;​

LL=0;​

RH=1;​

RL=0;​

}​

//--------------------------------------------------​

void turn_left()//左转,赋值​

{​

tmp1=0;​

tmp2=T-25;​

LH=0; 转弯时一个正转,一个反转,​

LL=0;​

RH=1;​

RL=0; ​

}​

//---------------------------------------------------​

void turn_right()//右转,赋值​

{​

tmp1=T-25;​

tmp2=0;​

LH=1; 转弯时一个正转,一个反转,​

LL=0; ​

RH=0; ​

RL=0; ​

}​

//-----------------------------------------------------​

void straightL() //慢直走,赋值​

{​

tmp1=T-40; //左右电机占空比初始化,调节直线运动速度​

tmp2=T-40; ​

LH=1;​

LL=0;​

RH=1;​

RL=0; ​

}​


//-----------------------------------------------------​

void straight() //直走,赋值​

{​

tmp1=T-10; //左右电机占空比初始化,调节直线运动速度​

tmp2=T-10; ​

LH=1;​

LL=0;​

RH=1;​

RL=0; ​

}​

//-----------------------------------------------------​

void back() //后退​

{​

tmp1=T-20; //左右电机占空比初始化,调节直线运动速度​

tmp2=T-20; //鉴于左右轮电机内部阻力不同,故占空比取不同值,这组值需要单独写程序取值​

LH=0;​

LL=1;​

RH=0;​

RL=1; ​

}​


//-----------------------------------------------------​

void stop() //停车​

{​

tmp1=0;​

tmp2=0;​

LH=0;​

LL=0;​

RH=0;​

RL=0;​

ENA=0;​

ENB=0;​



}​





/******************************************************​

* 名 称:void turn()​

* 功 能:路径控制​

* 入口参数:int Position​

* 出口参数:无​

******************************************************/​


void turn ()​

{​





if(!(S1|S2|S3|S4|S5|S6|S7))​

{​

_nop_();​

_nop_();​

back();​

delay(20);​

if((!S1)&(!S2)&S4&(!S6)&(!S7))​

{​

if(S4&S5&S6);​

else ​

back();​


}​



}//后退寻线​




//全白后退寻线​




if(S1&S2&S3&S4&S5&S6&S7)​

{​

delay(1); ​

stop();​

back();​

delay(1);​



}//全黑,停止​



if( (S1&S3&(!S7))||(S1&S4&(!S7))||(S2&S4&(!S7)) )//遇到左直角​

{​

back();​

delay(5);​


turn_left();​

delay(5);​

while( (S1&S3&(!S7))||(S1&S4&(!S7))||(S2&S4&(!S7)) )​

turn_left();​

//delay(50);​

}​


if( (S5&S7&(!S1))||(S4&S7&(!S1))||(S4&S6&(!S1)) )//遇到右直角​

{​

back();​

delay(5);​

turn_right();​

delay(5);​

while( (S5&S7&(!S1))||(S4&S7&(!S1))||(S4&S6&(!S1)) )​

turn_right();​

//delay(50);​


}​





if((!S1)&(!S2)&S4&(!S6)&(!S7))​

{​


_nop_();​

_nop_();​

_nop_();​

_nop_();​





if(S3&S4&S5)//避免死循环​

{​

back();​

delay(20);​

if(S3&S4)​

{​

turn_left();​

delay(5);​

}​

if(S4&S5)​

{​

turn_right();​

delay(5);​

}​



}​


else​

straight();​


}//全速速前行​




if(!(S4|S5|S6|S7))​

{​


_nop_();​

_nop_();​

_nop_();​


if((!S1)&S3)​

correct_left(); //校正​


if( ((!S3)&S2)||(S1&(!S3)) )​

turn_left(); //左拐​


if(S1&S2&S3)//遇到左直角​

{​

back();​

delay(5);​

while(S1&S2&S3)​

turn_left();​

delay(5);​



}​



} ​






if( !(S1|S2|S3|S4))​

{​




_nop_();​

_nop_(); ​

_nop_();​

_nop_(); ​


if(S5&(!S7))​

correct_right();//校正​



if( ( (!S5)&S6 )||((!S5)&S7) )​

turn_right(); //右拐​


if(S5&S6&S7)//遇到右直角​

{​

back();​

delay(5);​

while(S5&S6&S7)​

turn_right();​

delay(5);​



}​




} ​

}​


/****************************************************************************************************​

避障模块儿​

*****************************************************************************************************/​


void Rback()​

{​


RH=0;​

RL=1;​

LH=0;​

LL=0;​

}​

void Lback()​

{​


RH=0;​

RL=0;​

LH=0;​

LL=1;​

}​

void mainbizhang()​

{​



if((!LLT)&MLT&(!RLT))//010​

{​

Rback();​

delay(20);​

}​

if((LLT)&(!MLT)&(!RLT))//100​

turn_left();​


if((!LLT)&(!MLT)&(RLT))//001​

turn_right();​


if((!LLT)&(!MLT)&(!RLT))//000​

{​

Rback();​

delay(15);​

}​




if((!LLT)&(MLT)&(RLT))//011​

turn_right();​


if((LLT)&(!MLT)&(RLT))//101​

turn_left();​


if((LLT)&(MLT)&(!RLT))//110​

turn_left();​


if((LLT)&(MLT)&(RLT))//111​

straight();​




}​


/*****************************************************************************************************​

测速显示子程序​

*****************************************************************************************************/​

//=====================================================================================​

//延时程序​

//=====================================================================================​

void Delay5Ms()​

{​

unsigned long int TempCyc = 5000;​

while(TempCyc--);​

}​





uchar ReadStatusLCM()​


{​


char i;​

uchar busy;​

LCM_RS = 0;​

LCM_RW = 1;​

LCM_E = 1;​

for(i=0;i<100;i++);​

busy=(P0&0x80);​

LCM_E = 0;​

return(busy);​

}​



//=====================================================================================​

//读写子程序​

//=====================================================================================​


//读数据​

unsigned char ReadDataLCM()​

{​

while (ReadStatusLCM());​


LCM_RS = 1; ​

LCM_RW = 1;​

LCM_E = 1;​

return(LCM_Data);​

}​


//读状态​


//写数据​

void WriteDataLCM(unsigned char WDLCM)​

{char i;​

while (ReadStatusLCM());​


LCM_Data = WDLCM;​

LCM_RS = 1;​

LCM_RW = 0;​

LCM_E=0;​

LCM_E = 1; ​

若晶振速度太高可以在这后加小的延时​

for(i=0;i<100;i++);//延时​

LCM_E =0;​

}​


//写指令​

void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测​

{​

char i;​

while(ReadStatusLCM());​

LCM_Data = WCLCM;​

LCM_RS = 0;​

LCM_RW = 0;​

LCM_E = 0;​

LCM_E = 1;​

for(i=0;i<100;i++);​

LCM_E = 0;​


}​


//=====================================================================================​

//初始化子程序​

//=====================================================================================​


void LCMInit(void) //LCM初始化​

{​


LCM_Data = 0;​

WriteCommandLCM(0x38,0); // 三次显示模式设置,不检测忙信号​

Delay5Ms(); ​

WriteCommandLCM(0x38,0);​

Delay5Ms(); ​

WriteCommandLCM(0x38,0);​

Delay5Ms(); ​

WriteCommandLCM(0x38,1); // 显示模式设置,开始要求每次检测忙信号​

Delay5Ms();​

WriteCommandLCM(0x08,1); // 关闭显示​

Delay5Ms();​

WriteCommandLCM(0x01,1); // 清屏​

Delay5Ms();​

WriteCommandLCM(0x06,1); // 显示光标移动设置​

Delay5Ms();​

WriteCommandLCM(0x0c,1); // 显示开及光标设置​

Delay5Ms();​

}​



//=====================================================================================​

//按指定位置显示一个字符​

//=====================================================================================​


void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)​

{​

Y &= 0x1;​

X &= 0xF; //限制X不能大于15,Y不能大于1​

if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;​

X |= 0x80; ​

算出指令码​

WriteCommandLCM(X, Y); //这里不检测忙信号,发送地址码​

WriteDataLCM(DData);​

}​


//=====================================================================================​

//按指定位置显示一串字符​

//void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)​

//说明: x(0-15):x参数 y(0-1):y参数 DData(字符串):要显示的内容(英文、数字、符号)​

//=====================================================================================​


void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)​

{​

unsigned char ListLength,j;​

ListLength = strlen(DData);​

Y &= 0x1;​

限制X不能大于15,Y不能大于1​

坐标应小于0xF​

{ ​

for(j=0;j<ListLength;j++)​

{​

显示单个字符​

X++;​

}​

}​

}​


//=====================================================================================​

//显示自定义字符​

//void mychar(char xx,char yy,unsigned char *character,unsigned char saveto)​

//说明:xx(0-15):为x参数.yy(0-1):y参数.character:要显示的字符的列表地址,在程序前面有定义​

//saveto(1-7)为字符保存的RAM,每屏最多显示7个自定义字符​

//(0x00-0x0h是自定义字符)​

//=====================================================================================​



//=====================================================================================​

//主函数​

//=====================================================================================​

void mychar(char xx,char yy,unsigned char *character,unsigned char saveto)​

{​

unsigned char add = (saveto<<3) | 0x40;​

临时变量,每一行的值​

for(o=0;o<8;o++)​


{​

t=*(character+o);​

WriteCommandLCM(add+o, 0); ​

WriteDataLCM(t);​

}​


显示字符​

}//====​




void main1602()​

{​


char m,n;​

char k=0,l=1;​


LCMInit();//1602初始化​

delay(400);​

for(m=0;m<2;m++)​

for(n=0;n<3;n++,k++,l++)​

{​


mychar(n+13,m, character1[k],l);​


} ​


// WriteCommandLCM(0x01,1); //清屏*/​


DisplayListChar(0,0,"V=00.0m/s");​

DisplayListChar(0,1,"S=000.0m");​


}​


/////////////////////////////////////////////////////////////////////////////​


void refresh()//刷新屏幕​

{​




//SU=(TH1*256+TL1)/1000;​

SU=(TH1*256+TL1)/100;​


if(SU!=0) ​

V=(TH1*256+TL1)/10-SU3;​

//if()​

//V=SU*10/C3;​

SU3=(TH1*256+TL1)/10;​

SU0=SU%10;​

SU1=(SU%100)/10;​

SU2=SU/100;​

V0=(V)%10;​

V1=(V)/10;​

SU0=SU0|0x30;;​

SU1=SU1|0x30;​

SU2=SU2|0x30;​

V0=V0|0x30;​

V1=V1|0x30;​






DisplayOneChar(2,0,V1);​

DisplayOneChar(3,0,V0);​

DisplayOneChar(3,1,SU2);​

DisplayOneChar(4,1,SU1);​

DisplayOneChar(6,1,SU0);​


}​

void averrage()​

{​


V=SU/C3;​

V0=(V)%10;​

V1=(V)/10;​

V0=V0|0x30;​

V1=V1|0x30;​

DisplayOneChar(2,0,V1);​

DisplayOneChar(3,0,V0);​




}​



/*********************************************************************************************​

1602测速模块儿子程序​

***************************************************************************************************/​



/******************************************************​

*名 称:void begin()​

*功 能:初始化​

*入口参数:无​

*出口参数:无​

*说 明: 初始化各个参数​

*******************************************************/​



void begin()​

{ ​


key1=1;key2=1;​

key3=1;key4=1;​

TMOD=0X52; ​


TH1=0; /* 装入定时器的初值,计数100次溢出 */ ​

TL1=0;​

TH0=0x9B; /* 装入定时器的初值,计数100次溢出 */ ​

TL0=0x9B; /*装入时间常数*/​


EA=1; /* 开中断 */ ​

ET1=1;​

ET0=1;/* 定时器1允许中断 */ ​

ET2=1;​

TR2=1;​

TR1=1; /* 启动定时器1 */​


/* 定时器0允许中断 */ ​

TR0=1;​

RCAP2H=(65536-10000)/256;​

RCAP2L=(65536-10000)%256; ​


LH=0;​

LL=0;​

RH=0;​

RL=0;​

ENA=0;​

ENB=0;​



}​

/******void scan()​

{​

if(!key1)​

{​

delay(15);​

if(!key1)​

// while(1)​

// {​

//begin();//初始化​

//main1602();​


do{turn();​

} while(key1&key2&key3&key4);​


// } ​


}​



if(!key2)​

{​

delay(15);​

if(!key2)​

//while(1)​

//{​

//begin();//初始化​

//main1602(); ​


do{mainbizhang();​

}while(key1&key2&key3&key4);​

//}​

}​


if(!key3)​

{​

delay(15);​

if(!key3)​


//{​

// ET0=0;​

// ET1=0;​

do{averrage();​

}while(key1&key2&key3&key4);​

// }​


}​

if(!key4)​

{​

delay(15);​

if(!key4)​

// {​

do{stop();​

}while(key1&key2&key3&key4);​


// ET0=0;​

// ET1=0;​

//}​

}​

}*/​


/******************************************************​

* 名 称:void timer0() interrupt 1​

* 功 能: T0中断服务程序​

* 入口参数:无​

* 出口参数:无​

*******************************************************/​





void timer1() interrupt 5​

{​

TF2=0;​

C2++;​

if((C2%100)==0)​

{​

C3++;//每秒刷新一次​

refresh();​

}​

//scan();​


}​



void timer0() interrupt 1 /* T0中断服务程序 */ ​


{ ​




if(count==0)​

{​

SPEED1=tmp1;​

SPEED2=tmp2;​

}​

if(count<SPEED1) ENA=1;​

else ENA=0; /* 产生电机1的PWM信号 */​


if(count<SPEED2) ENB=1;​


else ENB=0; /* 产生电机2的PWM信号 */​


count++; ​

if(count>=T) count=0; /* 1个PWM信号由100次中断产生 */ ​

}​


void count0() interrupt 3 ​

{​

TH1=0/256; /* 装入定时器的初值,计数100次溢出 */ ​

TL1=0%256; /*装入时间常数*/​


C1++;​

//s=x96000/48/4*3*13/2​


}​




void main()​

{ ​


begin();//初始化​

main1602();//显示模块儿初始化​

while(1)​

{​

if(key1==0)​

{delay(1);​

if(key1==0)​


do turn();while(key1&key2&key3&key4);}​

if(key2==0)​

{​

delay(1);​

if(key2==0)​


do mainbizhang();​

while(key1&key2&key3&key4);​

}​

if(key3==0)​

{​

delay(1);​

if(key3==0)​


do averrage();while(key1&key2&key3&key4);​

}​

if(key4==0)​

{​

delay(1);​

if(key3==0)​



do stop();​

while(key1&key2&key3&key4);​

}​



}​


}​

标签:delay,避障,小车,void,IoT,char,sbit,LCM,nop
From: https://blog.51cto.com/u_15284384/6030935

相关文章

  • 【KAWAKO】audiotsm-使用python对音频进行变速不变调处理
    目录安装库导入相关库定义reader定义writer定义WSLOA算法,并运行官方手册源码安装库pipinstallaudiotsm导入相关库importaudiotsmimportaudiotsm.io.wavimpo......
  • 将IoTDB注册为Windows服务
    昨天写的文章《​​WindowsServer上部署IoTDB集群​​》,Windows下的IoTDB是控制台程序,打开窗口后,很容易被别人给关掉,因此考虑做成Windows服务,nssm正是解决该问题的利器。1.......
  • Apache IoTDB C# SDK 介绍
    最近今天写了IoTDB的三篇相关文章,完成了安装部署和客户端连接:​​WindowsServer上部署IoTDB集群​​​​DBeaver连接IoTDBDriver​​​​将IoTDB注册为Windows服务​​Ts......
  • Apache IoTDB C# SDK 介绍
    最近今天写了IoTDB的三篇相关文章,完成了安装部署和客户端连接:​​WindowsServer上部署IoTDB集群​​​​DBeaver连接IoTDBDriver​​​​将IoTDB注册为Windows服务​​Ts......
  • DBeaver 连接IoTDBDriver
    DBeaver是一个SQL客户端和数据库管理工具。DBeaver可以使用IoTDB的JDBC驱动与IoTDB进行交互。IoTDB官网是有说明的,官网的方法是从源码编译​​https://iotdb.ap......
  • Windows Server上部署IoTDB 集群
    本文是参考官方的IoTDB集群版(1.0.0)的安装及启动教程:​​https://iotdb.apache.org/zh/UserGuide/V1.0.x/Cluster/Cluster-Setup.html​​,在WindowsServer2019上部署集......
  • Apache IoTDB C# SDK Apache-IoTDB-Client-CSharp
    最近今天写了IoTDB的三篇相关文章,完成了安装部署和客户端连接:WindowsServer上部署IoTDB集群DBeaver连接IoTDBDriver将IoTDB注册为Windows服务TsFile是IoTDB的底层数......
  • m基于蚁群优化模糊控制的机器人路线规划和避障算法
    1.算法描述蚁群算法是受到对真实蚂蚁群觅食行为研究的启发而提出。生物学研究表明:一群相互协作的蚂蚁能够找到食物和巢穴之间的最短路径,而单只蚂蚁则不能。生物学家经过大......
  • m基于蚁群优化模糊控制的机器人路线规划和避障算法matlab仿真
    1.算法描述       蚁群算法是受到对真实蚂蚁群觅食行为研究的启发而提出。生物学研究表明:一群相互协作的蚂蚁能够找到食物和巢穴之间的最短路径,而单只蚂蚁则不能......
  • 郭总云IOT Studio 1.0 演示视频拍摄方案
    标题:自建云平台,”潮“玩ESP8266标签:物联网IOTESP8266微信小程序云平台视频大纲上实物照片和和代码花絮;设备照:(面包板和裸板设备的合照;裸板设备各个角度的微距;给交......