基于STM32的超声波避障小车

超声波避障小车原理就是通过给超声波模块超过10us的高电平信号,自动发送8个40KHZ的方波,来检测是不是有信号的返回,如果有信号的返回,那么就判断为前方有障碍物,并且通过舵机云台,来实现180度的旋转,检测左右两边是否的有障碍物,从而进行避障的功能。

说完原理,接下来就是根据各部件的原理来进行编程,我的超声波避障小车主要涉及了超声波HC-SR04模块,L298N电机驱动模块,舵机sg90模块。
首先是最基本的电机驱动模块的相关代码:

#include "bsp_motor.h"
#include "delay.h"
#include 

void TIM4_PWM_Motor(unsigned int arr,unsigned int psc)
{	
	GPIO_InitTypeDef					GPIO_InitStuct;
	TIM_TimeBaseInitTypeDef		TIM_TimeBaseInitStuct;
	TIM_OCInitTypeDef					TIM_OCInitStuct;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);
	
	
	GPIO_InitStuct.GPIO_Pin=GPIO_Pin_7;						//左电机控制
	GPIO_InitStuct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStuct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStuct);
	
	GPIO_InitStuct.GPIO_Pin=GPIO_Pin_8;						//左电机PWM
	GPIO_InitStuct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStuct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStuct);
	
	GPIO_InitStuct.GPIO_Pin=GPIO_Pin_9;						//右电机PWM
	GPIO_InitStuct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStuct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStuct);
		
	GPIO_InitStuct.GPIO_Pin=GPIO_Pin_4;						//右电机方向控制
	GPIO_InitStuct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStuct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStuct);
	
	TIM_TimeBaseInitStuct.TIM_ClockDivision=0;
	TIM_TimeBaseInitStuct.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInitStuct.TIM_Period=arr;
	TIM_TimeBaseInitStuct.TIM_Prescaler=psc;
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStuct);
	
	TIM_OCInitStuct.TIM_OCMode = TIM_OCMode_PWM2; 
	TIM_OCInitStuct.TIM_OutputState = TIM_OutputState_Enable; 
	TIM_OCInitStuct.TIM_Pulse = 0; 
	TIM_OCInitStuct.TIM_OCPolarity = TIM_OCPolarity_High; 
	TIM_OC3Init(TIM4, &TIM_OCInitStuct);  
	TIM_OC4Init(TIM4, &TIM_OCInitStuct);  
	
	TIM_CtrlPWMOutputs(TIM4,ENABLE);	
  
	TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);  
	TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); 
	
 	TIM_Cmd(TIM4, ENABLE);
}

void car_run(unsigned char ucChannel,signed char cSpeed)
{
		short PWM;	
   	PWM = 7201 - fabs(cSpeed)*72;
	switch(ucChannel)
	{
		case 0://右轮
			TIM_SetCompare3(TIM4,PWM);
			if (cSpeed>0) 
				GPIO_ResetBits(GPIOA,GPIO_Pin_4);
			else if(cSpeed<0) 
				GPIO_SetBits(GPIOA,GPIO_Pin_4);		
			break;
		case 1://左轮
		  TIM_SetCompare4(TIM4,PWM); 
			if (cSpeed>0) 
				GPIO_SetBits(GPIOB,GPIO_Pin_7);
			else if (cSpeed<0)
				 GPIO_ResetBits(GPIOB,GPIO_Pin_7);
			break;			
	}
}


void Run_Go(signed char speed,int time)  //前进函数
{
		  signed char f_speed = - speed;
	    car_run(1,f_speed);
			car_run(0,speed);
			delay_ms(time);                
}

void Run_stop(int time) //刹车函数
{
	  car_run(1,0);
	  car_run(0,0);
	  GPIO_ResetBits(GPIOA,GPIO_Pin_4);;
	  GPIO_ResetBits(GPIOB,GPIO_Pin_7);;
		delay_ms(time);           
}

void Run_left(signed char speed,int time) //左转
{
	  car_run(1,0);     
	  car_run(0,speed);    
		delay_ms(time);                 
}
void Run_Spin_left(signed char speed,int time) //左旋转
{
	  signed char u_speed = 100 - speed; 
 	  car_run(1,speed);  
	  car_run(0,u_speed);          
		delay_ms(time);                 

}
void Run_right(signed char speed,int time)  //右转
{
	  signed char f_speed = - speed;
	  car_run(1,f_speed);   
	  car_run(0,0);                
		delay_ms(time);                  
}
void Run_Spin_right(signed char speed,int time) //右旋转
{
	  signed char u_speed = 100 - speed;
	  signed char f_speed = - speed;
	  car_run(1,-u_speed);   
	  car_run(0,f_speed);           
		delay_ms(time);                   
}
void Run_back(signed char speed,int time) //后退
{
	  signed char u_speed = 100- speed;
	  signed char f_speed = - u_speed;
	  car_run(1,u_speed);
	  car_run(0,f_speed);
		delay_ms(time);                 
}

超声波检测距离的相关代码:

#include "bsp_hc.h"
#include "delay.h"
#define	TRIG_PORT      GPIOC		
#define	ECHO_PORT      GPIOC		
#define	TRIG_PIN       GPIO_Pin_0   
#define	ECHO_PIN       GPIO_Pin_1

float UltrasonicWave_Distance;     
void UltrasonicWave_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;	
	EXTI_InitTypeDef EXTI_InitStructure;
 	NVIC_InitTypeDef NVIC_InitStructure;
	
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);
    
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;					  
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	         
  GPIO_Init(GPIOC, &GPIO_InitStructure);	      

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;				   
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;		 
  GPIO_Init(GPIOC,&GPIO_InitStructure);				
	

 	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource1);

 	EXTI_InitStructure.EXTI_Line = EXTI_Line1;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);		                        
		
			
	NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;			     
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;	 
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;			  
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;						
  NVIC_Init(&NVIC_InitStructure);  	                       
}

void EXTI1_IRQHandler(void)
{
	delay_us(10);		                     
  if(EXTI_GetITStatus(EXTI_Line1) != RESET)
	{
			TIM_SetCounter(TIM2,0);
			TIM_Cmd(TIM2, ENABLE);                                      
		
			while(GPIO_ReadInputDataBit(GPIOC,ECHO_PIN));	         

			TIM_Cmd(TIM2, DISABLE);			                                
			UltrasonicWave_Distance=TIM_GetCounter(TIM2)*5*34/200.0;			
			EXTI_ClearITPendingBit(EXTI_Line1); 
	}
}
void Timerx_Init(uint16_t arr,uint16_t psc)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

	TIM_TimeBaseStructure.TIM_Period = 5000;
	TIM_TimeBaseStructure.TIM_Prescaler =(7200-1); 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; 
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); 
 
	TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_Trigger,ENABLE);
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
	NVIC_Init(&NVIC_InitStructure);  
							 
}

void TIM2_IRQHandler(void)   
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) 
		{
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update  ); 
		}
}

int UltrasonicWave_StartMeasure(void)
{
  int temp;
	GPIO_SetBits(TRIG_PORT,TRIG_PIN); 		  
  delay_us(20);		                    
  GPIO_ResetBits(TRIG_PORT,TRIG_PIN);
	temp = UltrasonicWave_Distance*10;
	return temp;
}

舵机云台的相关代码:

#include "bsp_duoji.h"

void TIM5_PWM_Init(u16 arr,u16 psc)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_OCInitTypeDef TIM_OCInitStructure;
	
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	

	 TIM_TimeBaseStructure.TIM_Period = arr;
	 TIM_TimeBaseStructure.TIM_Prescaler =psc;
	 TIM_TimeBaseStructure.TIM_ClockDivision = 0;
	 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	 TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); 
	
	 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	 TIM_OCInitStructure.TIM_Pulse = 0;
	 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	 TIM_OC1Init(TIM5, &TIM_OCInitStructure);
	 
	 TIM_CtrlPWMOutputs(TIM5,ENABLE);	
	 TIM_OC1PreloadConfig(TIM5, TIM_OCPreload_Enable); 
   TIM_OC2Init(TIM5, &TIM_OCInitStructure);
	 
	 TIM_ARRPreloadConfig(TIM5, ENABLE); 
   TIM_Cmd(TIM5, ENABLE); 
}

最后是主函数:

#include "stm32f10x.h"
#include "bsp_motor.h"
#include "bsp_duoji.h"
#include "bsp_hc.h"
#include "delay.h"

void duojizhuantou(float angle)
{
	angle=(u16)(50.0*angle/9.0+249.0);
	TIM_SetCompare1(TIM5,angle);
}

int front_detection()
{
	duojizhuantou(90);
	delay_ms(100);
	return UltrasonicWave_StartMeasure();
}
int left_detection()
{
	duojizhuantou(175);
	delay_ms(300);
	return UltrasonicWave_StartMeasure();
}
int right_detection()
{
	duojizhuantou(5);
	delay_ms(300);
	return UltrasonicWave_StartMeasure();
}

int main(void)
{
  Timerx_Init(4999,7199);   
	HC_GPIO();              
	TIM4_PWM_Motor(7199,0);
	TIM5_PWM_Init(9999,143); 
	
	while(1)
	{  		
		if(front_detection()<60 && front_detection()>0) 
		{
			Run_stop(500);		
			Run_back(60,500);	
			Run_stop(1000);			
			left_detection();
			delay_ms(500);
			right_detection();
			delay_ms(500);
			if((left_detection() < 60 ) &&( right_detection() < 60 ))
			{
				Run_Spin_left(60,1000);
			}				
      else if(left_detection() > right_detection())
			{
				Run_left(60,1000);
				Run_stop(500);
			}	
      else
			{
				Run_right(60,1000);
				Run_stop(500);					
			}							
		}	
		else
		{
			Run_Go(60,10);
		}
	}
 }

你可能感兴趣的