超声波避障小车
发表于更新于
字数总计:1k阅读时长:4分钟 中国
超声波避障小车
Zehua摘要:介绍了使用一路超声波测距和两路红外测障的自动避障小车
##功能实现:
材料:51单片机,L298N模块,超声波模块HC-SR04,Sg90舵机,红外传感器,18650电池
###硬件连接:
###代码编写:
####马达运动:
调节L298N的IN接口,控制电机正反转,通过变量PWMA和PWMB调节占空比从而调节小车左右轮的速度。
#include <REGX51.H> sbit IN1 = P2^4; sbit IN2 = P2^3; sbit IN3 = P2^2; sbit IN4 = P2^1; extern unsigned char PWMA,PWMB; void straight() { IN1 = 1; IN2 = 0; PWMA = 25; IN3 = 0; IN4 = 1; PWMB = 25; } void turnleft() { IN1 = 1; IN2 = 0; PWMA = 34; IN3 = 1; IN4 = 0; PWMB = 21; } void turnright() { IN1 = 0; IN2 = 1; PWMA = 21; IN3 = 0; IN4 = 1; PWMB = 35; } void back() { IN1 = 0; IN2 = 1; PWMA = 30; IN3 = 1; IN4 = 0; PWMB = 30; } void stop() { IN1 = 1; IN2 = 1; PWMA = 0; IN3 = 1; IN4 = 1; PWMB = 0; }
|
####马达速度的调节:
分别为左,右两侧马达提供pwm调节,通过调节PWMA与PWMB,可以调整输出的占空比从而控制速度。
void main() { TMOD|=0x11; TH0=0; TL0=0; TH1=0xFE; TL1=0x33; ET0=1; ET1=1; TR1=1; EA=1; } void Tmr1_isr() interrupt 3 { TH1=0xFE; TL1=0x33; i++; j++; if(i < PWMA) { ENA = 1; } else { ENA = 0; if(i >= 100) { i = 0; } } if(j < PWMB) { ENB = 1; } else { ENB = 0; if(j >= 100) { j = 0; } } }
|
####舵机的控制:
每500微秒执行一次中断,每执行一次通过counter计数,执行40次清零,输出周期为20ms的波形,通过调节angle改变占空比,从而控制舵机的角度。angle为1,2,3,4时,角度分别为0,45,90,135度。
void Tmr1_isr() interrupt 3 { TH1=0xFE; TL1=0x33; counter++; if(counter <= angle) sg90 = 1; if(counter > angle && counter <= 40) sg90 = 0; if(counter > 40) counter = 0; }
|
####超声波测距:
先给Tirg大于10us的高电平作为触发信号,通过检测echo口输出高电平的时间,得到从发射到返回所用的时间。
#include <REGX51.H> #include <intrins.h> void delayms(unsigned int ms); sbit Echo = P1^5; sbit Trig = P1^6; sbit sg90 = P1^7; extern unsigned int time; extern unsigned int S; void hcsr04() { Trig=1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); Trig=0; while(!Echo); TR0=1; while(Echo); TR0=0; } void count(void) { time=(TH0*256+TL0)*1.085; TH0=0; TL0=0; S=time*0.017; delayms(2); }
|
####小车的运行:

默认直行,若前方有障碍物,则优先右转,若右方也有障碍物,则向左转,若两侧都有障碍物,则后退并且优先向右转,若右侧有障碍物,再向左转。
若小车左侧或右侧被墙角卡住,则红外传感器发出低电平,小车后退并优先向右转。
#include <REGX51.H> #include "motor.h" void count(); void hcsr04(); void delayms(unsigned int ms); void run(); extern unsigned int S; extern unsigned char angle; sbit left_d=P3^7; sbit right_d=P3^6; void run() { if(right_d==0) { back(); delayms(500); angle=2; delayms(200); hcsr04(); count(); } if(left_d==0) { back(); delayms(500); angle=2; delayms(200); hcsr04(); count(); if(angle ==3 && S >= 20) { straight(); hcsr04(); count(); } else if(angle ==3 && S < 20) { stop(); angle = 2; delayms(200); hcsr04(); count(); } if(angle == 2 && S >=20) { turnright(); delayms(500); angle =3; delayms(200); hcsr04(); count(); } else if(angle == 2 && S < 20) { angle = 4; delayms(200); hcsr04(); count(); } if(angle == 4 && S >=20) { turnleft(); delayms(500); angle =3; delayms(200); hcsr04(); count(); } else if(angle == 4 && S <20) { back(); delayms(500); angle =3; delayms(200); hcsr04(); count(); } }
|