基于STM32的超声波避障小车

    科技2022-08-17  143

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

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

    #include "bsp_motor.h" #include "delay.h" #include <math.h> 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); } } }
    Processed: 0.030, SQL: 9