小车用的是52单片机的四驱wifi,两侧电机串联,超声波模块是便宜实用的HC-SR04
单片机源程序:
- /****************************************************************************
- 硬件连接
- ****************************************************************************/
- #include<reg52.h>
- #include <intrins.h>
- #define ECHO1 P1_0 //超声波接口定义
- #define TX1 P1_1 //超声波接口定义
- #define ECHO2 P1_2 //超声波接口定义
- #define TX2 P1_3 //超声波接口定义
- #define ECHO3 P1_4 //超声波接口定义
- #define TX3 P1_5 //超声波接口定义
- #define ECHO4 P1_6 //超声波接口定义
- #define TX4 P1_7 //超声波接口定义
- #define ECHO5 P0_0 //超声波接口定义
- #define TX5 P0_1 //超声波接口定义
- #define Left_moto_pwm P2_2 //PWM信号端
- #define Right_moto_pwm P2_3 //PWM信号端
- sbit IN1=P2^0;
- sbit IN2=P2^1;
- sbit IN3=P2^4;
- sbit IN4=P2^5;
- sbit EN1=P2^2;
- sbit EN2=P2^3;
- bit Right_moto_stop=1;
- bit Left_moto_stop =1;
- #define Left_moto_go {IN1=0,IN2=1,EN1=1;} //左电机向前走
- #define Left_moto_back {IN1=1,IN2=0,EN1=1;} //左边电机向后走
- #define Left_moto_Stop {EN1=0;} //左边电机停转
- #define Right_moto_go {IN3=1,IN4=0,EN2=1;} //右边电机向前走
- #define Right_moto_back {IN3=0,IN4=1,EN2=1;} //右边电机向后走
- #define Right_moto_Stop {EN2=0;} //右边电机停转
- unsigned char pwm_val_left =0;//变量定义
- unsigned char push_val_left =0;// 左电机占空比N/20
- unsigned char pwm_val_right =0;
- unsigned char push_val_right=0;// 右电机占空比N/20
-
- unsigned int time=0;
- unsigned int timer=0;
- unsigned long S1=0;
- unsigned long S2=0;
- unsigned long S3=0;
- unsigned long S4=0;
- unsigned long S5=0;
- unsigned char timer1=0; //扫描时间变量
- /************************************************************************/
- void delay(unsigned char x) //1ms延时函数,100ms以内可用
- {
- unsigned char i;
- while(x--)
- for(i=124;i>0;i--);
- }
- void Conut1(void) //计算距离
- {
- while(!ECHO1); //当RX为零时等待
- TR0=1; //开启计数
- while(ECHO1); //当RX为1计数并等待
- TR0=0; //关闭计数
- time=TH0*256+TL0; //读取脉宽长度
- TH0=0;
- TL0=0;
- S1=(time*1.7)/100; //算出来是CM
- }
- void Conut2(void) //计算距离
- {
- while(!ECHO2); //当RX为零时等待
- TR0=1; //开启计数
- while(ECHO2); //当RX为1计数并等待
- TR0=0; //关闭计数
- time=TH0*256+TL0; //读取脉宽长度
- TH0=0;
- TL0=0;
- S2=(time*1.7)/100; //算出来是CM
- }
- void Conut3(void) //计算距离
- {
- while(!ECHO3); //当RX为零时等待
- TR0=1; //开启计数
- while(ECHO3); //当RX为1计数并等待
- TR0=0; //关闭计数
- time=TH0*256+TL0; //读取脉宽长度
- TH0=0;
- TL0=0;
- S3=(time*1.7)/100; //算出来是CM
- }
- void Conut4(void) //计算距离
- {
- while(!ECHO4); //当RX为零时等待
- TR0=1; //开启计数
- while(ECHO4); //当RX为1计数并等待
- TR0=0; //关闭计数
- time=TH0*256+TL0; //读取脉宽长度
- TH0=0;
- TL0=0;
- S4=(time*1.7)/100; //算出来是CM
- }
- void Conut5(void) //计算距离
- {
- while(!ECHO5); //当RX为零时等待
- TR0=1; //开启计数
- while(ECHO5); //当RX为1计数并等待
- TR0=0; //关闭计数
- time=TH0*256+TL0; //读取脉宽长度
- TH0=0;
- TL0=0;
- S5=(time*1.7)/100; //算出来是CM
- }
- //全速前进
- void run(void)
- {
- push_val_left=20; //左电机调速,速度调节变量 0-20。。。0最小,20最大,四驱大轮>6
- push_val_right=18; //右电机调速
- Left_moto_go ; //左电机往前走
- Right_moto_go ; //右电机往前走
-
- }
- /************************************************************************/
- //全速后退
- void backrun(void)
- {
- push_val_left=20;
- push_val_right=18 ;
- Left_moto_back ; //左电机往前走
- Right_moto_back ; //右电机往前走
- }
- /************************************************************************/
- //左转
- void leftrun(void)
- {
- push_val_left=13;
- push_val_right=10;
- Left_moto_back ; //左电机往后走
- Right_moto_go ; //右电机往前走
- }
- /************************************************************************/
- //右转
- void rightrun(void)
- {
- push_val_left=13;
- push_val_right=10;
- Left_moto_go ; //左电机往前走
- Right_moto_back ; //右电机往后走
- }
- /************************************************************************/
- //STOP
- void stoprun(void)
- {
- Left_moto_Stop ; //左电机停
- Right_moto_Stop ; //右电机停
- }
- /************************************************************************/
- void COMM( void )
- {
-
- TX1=1;
- delay(1);
- TX1=0; //启动超声波测距
- Conut1(); //计算距离
-
- TX2=1;
- delay(1);
- TX2=0; //启动超声波测距
- Conut2(); //计算距离
-
- TX3=1;
- delay(1);
- TX3=0; //启动超声波测距
- Conut3(); //计算距离
- TX4=1;
- delay(1);
- TX4=0; //启动超声波测距
- Conut4(); //计算距离
- TX5=1;
- delay(1);
- TX5=0; //启动超声波测距
- Conut5(); //计算距离
-
- if(S1<20 && S3<30 && S5<20) //进入狭窄通道
- {
- backrun(); //倒车
- }
- if(S2<20 && S3<30 && S4<20) //进入狭窄通道
- {
- backrun(); //倒车
- if(S2>30 && S3>30)
- leftrun();
- if(S4>30 && S3>30)
- rightrun();
- }
- else
- if(S1<20)
- {
- rightrun(); //车与障碍物呈45度角时,车的左边比车的右边距离小,右转
- }
- else
- if(S2<20)
- {
- rightrun(); //车与障碍物呈45度角时,车的左边比车的右边距离小,右转
- }
- else
- if(S3<30 ) //车子与障碍物90度垂直,右边距离小左转
- {
- backrun();
- if(S2>20&&S4<20)
- {
- leftrun(); //车与障碍物呈45度角时,车的左边比车的右边距离小,右转
- if(S2<20&&S4>20)
- { backrun(); //车与障碍物呈45度角时,车的左边比车的右边距离小,右转
- delay(90);
- delay(90);
- }
- }
- }
- else
- if(S4<20)
- {
- leftrun(); //车与障碍物呈45度角时,车的右边比车的左边距离小,左转
- }
- else
- if(S5<20)
- {
- leftrun(); //车与障碍物呈45度角时,车的右边比车的左边距离小,左转
- }
- else
- if(S3<30 && S1<S5 ) //车子与障碍物90度垂直,左边距离小右转
- {
- rightrun();
- }
- else
- if(S3<30 && S1>S5 ) //车子与障碍物90度垂直,右边距离小左转
- {
- leftrun();
- }
- else
- if(S1<20&&S5<20)
- {
- backrun();
- }
- else
- if(S3<30&&S2<20)
- {
- rightrun(); //车与障碍物呈45度角时,车的左边比车的右边距离小,右转
- }
- else
- if(S3<30&&S4<20)
- {
- leftrun(); //车与障碍物呈45度角时,车的右边比车的左边距离小,左转
- }
- else
- if(S3>30&&S4<20)
- {
- leftrun(); //车与障碍物呈45度角时,车的右边比车的左边距离小,左转
- }
- else
- if(S3>30&&S2<20)
- {
- rightrun(); //车与障碍物呈45度角时,车的左边比车的右边距离小,右转
- }
-
- else
- if(S2>20&&S4<20)
- {
- leftrun(); //车与障碍物呈45度角时,车的左边比车的右边距离小,右转
- if(S2<20&&S4>20)
- { backrun(); //车与障碍物呈45度角时,车的左边比车的右边距离小,右转
- delay(90);
- delay(90);
- }
- }
- else
- {
- run();
- }
- }
- /************************************************************************/
- /* PWM调制电机转速 */
- /************************************************************************/
- /* 左电机调速 */
- /*调节push_val_left的值改变电机转速,占空比 */
- void pwm_out_left_moto(void)
- {
- if(Left_moto_stop)
- {
- if(pwm_val_left<=push_val_left)
- {
- Left_moto_pwm=1;
- }
- else
- {
- Left_moto_pwm=0;
- }
- if(pwm_val_left>=20)
- pwm_val_left=0;
- }
- else
- {
- Left_moto_pwm=0;
- }
- }
- /******************************************************************/
- /* 右电机调速 */
- void pwm_out_right_moto(void)
- {
- if(Right_moto_stop)
- {
- if(pwm_val_right<=push_val_right)
- {
- Right_moto_pwm=1;
- }
- else
- {
- Right_moto_pwm=0;
- }
- if(pwm_val_right>=20)
- pwm_val_right=0;
- }
- else
- {
- Right_moto_pwm=0;
- }
- }
- ///*TIMER1中断服务子函数产生PWM信号*/
- void time1()interrupt 3 using 2
- {
- TH1=(65536-100)/256; //100US定时
- TL1=(65536-100)%256;
- timer++;
- pwm_val_left++;
- pwm_val_right++;
- pwm_out_left_moto();
- pwm_out_right_moto(); //定时器100US为准。在这个基础上延时
- }
- /***************************************************/
- ///*TIMER0中断服务子函数产生PWM信号*/
- void timer0()interrupt 1
- {
- }
- /***************************************************/
- void main(void)
- {
- TMOD=0X11;
- TH1=(65536-100)/256; //100US定时
- TL1=(65536-100)%256;
- TH0=0;
- TL0=0;
- TR1= 1;
- ET1= 1;
- ET0= 1;
- EA = 1;
- delay(100);
- while(1) /*无限循环*/
- {
- COMM();
- }
- }
复制代码 |