STM32简单小项目——模拟超声波雷达倒车

项目简介:

         项目是实现模拟雷达倒车,随着超声波模块检测到的车距大小,有源蜂鸣器发出不同频率警报声同时OLED上显示测得距离。

        项目硬件部分:主芯片STM32F103C8T6、0.96寸OLED显示屏、有源蜂鸣器模块、HC-SR04超声波模块、ST-LINK烧录器、杜邦线若干、跳线若干。

        项目软件部分:用到了STM32的内部定时器TIM2以及GPIO口。

模块介绍:

        有源蜂鸣器:工作原理是当输入低电平时,蜂鸣器内部的震荡源被激活,从而发出声音,无需额外的驱动信号,我们通过控制主芯片给蜂鸣器低电平的时间可以发出不同频率声响。

        

        HC-SR04超声波模块:一款常用于测距的非接触式传感器,其测距范围在2cm至400cm之间,测距精度高达3mm,宽电压3V-5.5V。其工作原理是给模块接入电源和地线;通过Trig引脚(控制端)输入一个持续10微秒以上的高电平脉冲信号(最佳时间是40-50微秒),触发模块发射超声波;当超声波遇到障碍物并返回时,Echo引脚(接收端)的电平会发生变化,从0变为1,此时可以启动定时器开始计时;当模块接收到返回的超声波信号时,Echo引脚的电平再次变化,从1变为0,此时停止定时器计数;最后,根据定时器记录的时间以及声音在空气中的速度340m/s,就可以通过公式s=(vt)/2计算出所测的距离。

代码(采用STM32标准库开发):

        超声波模块初始化配置: 模块配置需要用到TIM2定时器中断和GPIO口,具体的配置方法可以看我另一篇文章(STM32F103C8T6内部定时器中断控制LED和USART串口通信代码-CSDN博客)这里超声波模块的TIM2预分频器值配置为0,自动重载值配置为720,使定时器每10微秒进一次中断;Trig和Echo引脚接在STM32任意GPIO口,Trig配置为推挽输出模式,Echo配置为下拉模式(因为Echo在没有电平变化时默认为低电平),本项目Trig接PA0,Echo接PA1。

        自定义发送超声波函数:给Trig引脚45微秒的高电平唤醒超声波模块发送超声波,然后再至低电平;用一个while循环等待Echo引脚变高电平,随后开启定时器开始计时;每次启动定时器前要将计数变量清零,确保下次计数准确。

        自定义接收超声波有返回值函数:while循环等待Echo引脚变低电平,结束计时,通过公式计算返回距离,这里需要注意单位的换算,本项目最后在OLED显示的是cm/s的单位。

void Chaosb_Init()
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;//推挽输出
	GPIO_InitStructure.GPIO_Pin= GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPD;//下拉输入
	GPIO_InitStructure.GPIO_Pin= GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	TIM_InternalClockConfig(TIM2);//开启内部时钟
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision= TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode= TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period= 720;//自动重载  10微秒
	TIM_TimeBaseInitStructure.TIM_Prescaler= 0;//预分频
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter= 0;
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM2,TIM_FLAG_Update);//更新标志位
	
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//开启中断源
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel= TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority= 1;
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_Cmd(TIM2,DISABLE);//关闭定时器
}

//发送超声波
void Trig_Init()
{
	GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_SET);
	Delay_us(45);
	GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET);
	while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)==RESET);//等待Echo变高电平
	Distance=0;
	TIM_Cmd(TIM2,ENABLE);//开启定时器
}

//接收开始计时
uint16_t Echo_Init()
{
		while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)==SET);//等待Echo变低电平
		TIM_Cmd(TIM2,DISABLE);//关闭定时器
		return sdu=((Distance * 0.00001) * 34000) / 2;
}

        蜂鸣器模块初始化配置: 蜂鸣器模块I/O引脚可以选择接在STM32任意GPIO口配置为推挽输出模式,本项目I/O引脚接PB10。

        自定义不同发声频率函数:通过switch来选择在不同距离区间内的不同警报声,可以通过调节Delay的延迟值来发出自己想要的警报声。

void Buzzer_Init()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin= GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
}

void Buzzer_dangw(int i)//不同发声频率选择
{
	switch(i)
	{
		break;
		case 1:
		GPIO_ResetBits(GPIOB,GPIO_Pin_10);
		Delay_ms(350);
		GPIO_SetBits(GPIOB,GPIO_Pin_10);
		Delay_ms(350);
		break;
		case 2:
		GPIO_ResetBits(GPIOB,GPIO_Pin_10);
		Delay_ms(250);
		GPIO_SetBits(GPIOB,GPIO_Pin_10);
		Delay_ms(250);
		break;
	    case 3:
		GPIO_ResetBits(GPIOB,GPIO_Pin_10);
		Delay_ms(150);
		GPIO_SetBits(GPIOB,GPIO_Pin_10);
		Delay_ms(150);
		break;
	    case 4:
		GPIO_ResetBits(GPIOB,GPIO_Pin_10);
		Delay_ms(50);
		GPIO_SetBits(GPIOB,GPIO_Pin_10);
		Delay_ms(50);
		break;
}
	}

        主函数:对各模块初始化,自定义shift()函数用(>=大于或等于&&<=小于或等于)配置不同距离区间响应对应想要的警报声,这里的OLED配置借鉴了江协科技代码配置,文章下面链接有本项目源码,有需要的小伙伴可以自取。

#include "stm32f10x.h"                  // Device header
#include "OLED.h" 
#include "Delay.h"
#include "chaosb.h"
#include "Buzzer.h"

uint16_t T,Distance;

void shift()
{
	GPIO_SetBits(GPIOB,GPIO_Pin_10);
		if(T >= 30 && T <= 50)
		{
			Buzzer_dangw(1);
		}
		
		if(T >= 10 && T <= 30)
		{
			Buzzer_dangw(2);
		}
		if( T <= 10)
		{
			Buzzer_dangw(4);
		}
}

int main(void)
{
	Chaosb_Init();
	OLED_Init();
	Buzzer_Init();
	OLED_ShowString(1,1,"Distance:   cm");
	while(1)
	{
		Trig_Init();
		Echo_Init();
		T=Echo_Init();
		OLED_ShowNum(1,10,T,2);
		Delay_ms(100);
		shift();
	}
}

void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
	{
		Distance++;
	}
	TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}

        实物图:

 

以上内容都是自己自学和理解,如有理解不正确的地方,可在评论区指出或者私信我进行更改,大家共同进步,希望这篇文章对大家有帮助。

链接:https://pan.baidu.com/s/1MDg97XEr52u4GPAf6ZvH5g?pwd=444a 
提取码:444a 

  • 24
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值