赞
踩
项目简介:
项目是实现模拟雷达倒车,随着超声波模块检测到的车距大小,有源蜂鸣器发出不同频率警报声同时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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。