STM32 学习笔记4-智能小车-超声波避障
目录
老规矩:Model X 特斯拉镇楼 (图文相关,Model X 鹰翼门 侧门防止磕碰,装了超声波传感器)
什么是超声波?超声波测距原理?
超声波(ultrasonic (waves) )是一种机械波,其具有指向性强、能量消耗缓慢、传播距离相对较远等特点
波长:人类耳朵能听到的声波频率为为20HZ~20KHz,超声波一般为大于20KHz23 kHz到40 kHz
超声波测距原理:超声波常用的测距方法为回声探测法,s=340t/2,其他还相位检测法、声波幅值检测法。
误差影响因素:超声波是一种声波,声速V与温度关系很大,V = 331.4 + 0.607T式中,T为实际温度单位为℃,v为超声波在介质中的传播速度单位为m/s。一般要提高精度,需要做相应的温度补偿程序。
硬件:
超声波传感器:
型号: HC-SR04
ultrasonic sensor 包括四个引脚分别是 Vcc Input(trig 控制端) output ( echo 接收端) Gnd
超声波内部原理图
车身结构件及其附件:
如底板,车轮等 ,提供支撑与安装
驱动:2*直流电机
控制模块:单片机 STM32 F10系列 超声波控制模块相关芯片
电路图:
软件:
逻辑控制策略:
初始化→检测障碍物→检测范围内无障碍物→前进
→检测范围外有障碍物→后退→右(左)转→检测障碍物
比如在检测到障碍物的时候,蜂鸣器会响等。
代码实现:
main.c 主函数
#include "stm32f10x.h"
#include "delay.h"
#include "motor.h"
#include "keysacn.h"
#include "IRSEARCH.h"
#include "IRAvoid.h" //红外避障头文件
#include "usart.h"
#include "UltrasonicWave.h" //超声波头文件
#include "timer.h" //计时器 计时头文件
int main(void)
{
delay_init(); //初始化
KEY_Init();
IRSearchInit();
IRAvoidInit();
Timerx_Init(5000,7199); //定时器设置用来开启定时器计时,记录Echo变为低电平的时间。
UltrasonicWave_Configuration(); //超声波模块初始化
uart_init(115200); // 串口初始化为115200
TIM4_PWM_Init(7199,0); //初始化PWM
STM32_brake(500); //刹车函数0.5s
keysacn();
while(1)
{
//printf("测到的距离值为:%d\n",UltrasonicWave_StartMeasure());
if(UltrasonicWave_StartMeasure()<40) //当距离小于40cm时,判断为有障碍物
{
ZYSTM32_back(50,500); //后退
STM32_Right(50,500); //右转
BEEP_SET; //蜂鸣器响
}
else
{
STM32_run(50,1); //无障碍物 直行
BEEP_RESET; //蜂鸣器不响
}
}
}
Timerx_Init函数
#include "timer.h"
//通用定时器3中断初始化
//APB1
//arr :
//psc
void Timerx_Init(u16 arr,u16 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; // :TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //TIM_TimeBaseInitStruct
TIM_ITConfig( //
TIM2, //TIM2
TIM_IT_Update | //TIM
TIM_IT_Trigger, //TIM
ENABLE //
);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM3
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// TIM_Cmd(TIM2, ENABLE); // TIMx
}
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update ); //
}
}
UltrasonicWave.c 主函数:
#include "UltrasonicWave.h"
#include "usart.h"
#include "timer.h"
#include "delay.h"
/***超声波四个引脚定义******************/
#define TRIG_PORT GPIOC //TRIG
#define ECHO_PORT GPIOC //ECHO
#define TRIG_PIN GPIO_Pin_0 //TRIG PC0 - TRIG
#define ECHO_PIN GPIO_Pin_1 //ECHO PC1 - ECHO
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 = TRIG_PIN; //PC0接 TRIG
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设为推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(TRIG_PORT, &GPIO_InitStructure); // 初始化外设 GPIO
GPIO_InitStructure.GPIO_Pin = ECHO_PIN; //PC7接ECH0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //设为输入
GPIO_Init(ECHO_PORT,&GPIO_InitStructure); //初始化GPIOA
//GPIOC.1 中断线以及中断初始化配置
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); //根据EXTI_InitStruct中指定的参数初始化外设 EXTI寄存器
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; //
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStructure中指定的参数初始化外设 NVIC寄存器
}
//-----------------------通道1中断函数---------------------------------------------
void EXTI1_IRQHandler(void)
{
delay_us(10); //延时10us
if(EXTI_GetITStatus(EXTI_Line1) != RESET)
{
TIM_SetCounter(TIM2,0);
TIM_Cmd(TIM2, ENABLE); //开启时钟
while(GPIO_ReadInputDataBit(ECHO_PORT,ECHO_PIN)); //等待低电平
TIM_Cmd(TIM2, DISABLE); //定时器2失能
UltrasonicWave_Distance=TIM_GetCounter(TIM2)*5*34/200.0; //计算距离UltrasonicWave_Distance<150
// U_temp = UltrasonicWave_Distance*10;
// if(UltrasonicWave_Distance>0)
// {
// printf("distance:%f mm",UltrasonicWave_Distance*10);
// }
EXTI_ClearITPendingBit(EXTI_Line1); //清除EXTI线路挂起位
}
}
/* 开始测距,发送一个大于10微秒的脉冲,然后测量返回的高电平的时间 */
int UltrasonicWave_StartMeasure(void)
{
int u_temp;
GPIO_SetBits(TRIG_PORT,TRIG_PIN); //送10微秒的高电平
delay_us(20); //
GPIO_ResetBits(TRIG_PORT,TRIG_PIN);
u_temp = UltrasonicWave_Distance*10;
return u_temp;
}
uart_init ()主函数
void uart_init(u32 bound){
//GPIO
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //
//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);// GPIOA.9
//USART1_RX GPIOA.10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//USART
USART_InitStructure.USART_BaudRate = bound;//
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Cmd(USART1, ENABLE);
}
backup:超声波测距工作原理
参考链接: