一.所需材料:
1任何一种型号的stm32f10x的微控制器
2.HC-SR04模块
3.安装串口驱动与串口助手(这里用的火哥的串口调试助手)
4.ST-link或者串口等下载方式都可以
二。超声波原理
网上一大堆,这里我就大体说一下:单片机先给TRIG一个大于10us的高电平,然后模块ECHO引脚会发出一个高电平,检测高电平的时间乘声速便可算出距离。这里ECHO发出也接收,所以检测的时间,假设按秒算,然后乘170便是以m为单位的距离。
三.源代码分析
1.接口定义:
//由于只是用的定时器的基本计时功能,所以IO口随便找两个便可以
#define HCSR04_PORT GPIOB
#define HCSR04_PORTC_CLK_FUN RCC_APB2PeriphClockCmd
#define HCSR04_CLK RCC_APB2Periph_GPIOB
#define HCSR04_TRIG GPIO_Pin_11
#define HCSR04_ECHO GPIO_Pin_10
2.驱动函数分析
//超声波计数,记录有几个更新中断,由于在.c文件中定义,中断函数中测试其值,故加个extern
extern u16 msHcCount = 0;
//IO口初始化 TRIG为普通推挽输出,ECHO为浮空输入,
//配置时基结构体
void Hcsr04Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
GPIO_InitTypeDef GPIO_InitStructure;
HCSR04_PORTC_CLK_FUN(HCSR04_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin =HCSR04_TRIG;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);
GPIO_InitStructure.GPIO_Pin = HCSR04_ECHO;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
TIM_DeInit(TIM2);
TIM_TimeBaseStructure.TIM_Period = (1000-1); //定时器时钟1MHZ,自动重装载寄存器的值为1000, 也就是说满一次为1MS
TIM_TimeBaseStructure.TIM_Prescaler =(72-1);
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
TIM_ClearFlag(TIM4, TIM_FLAG_Update);
TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
hcsr04_NVIC();
TIM_Cmd(TIM4,DISABLE);
}
//中断配置,这里只用了一个中断,不用考虑中断嵌套等等,所以中断优先级以及次优先级可以随便配置,只用到了定时器update中断
void hcsr04_NVIC(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//关闭定时器4
static void CloseTimerForHc(void)
{
TIM_Cmd(TIM4, DISABLE);
}
//打开定时器4
static void OpenTimerForHc(void)
{
TIM_SetCounter(TIM4,0);
msHcCount = 0;
TIM_Cmd(TIM4, ENABLE);
}
//获取定时器4计数器值,此值为更新中断的次数*1000+计数器的值
u32 GetEchoTimer(void)
{
u32 t = 0;
t = msHcCount*1000;
t += TIM_GetCounter(TIM4);
TIM4->CNT = 0;
Systick_DelayMs(50);
return t;
}
//通过定时器4计数器值推算距离,单位厘米,假设测试值为x,距离y=x/1M*17000
//这里每测出5此求个平均值输出
float Hcsr04GetLength(void )
{
u32 t = 0;
int i = 0;
float lengthTemp = 0;
float sum = 0;
while(i!=5)
{
GPIO_SetBits(HCSR04_PORT,HCSR04_TRIG);
Systick_DelayUs(20);
GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);
while(GPIO_ReadInputDataBit(HCSR04_PORT,HCSR04_ECHO)==RESET);
OpenTimerForHc();
i = i + 1;
while(GPIO_ReadInputDataBit(HCSR04_PORT,HCSR04_ECHO)==SET);
CloseTimerForHc();
t = GetEchoTimer();
lengthTemp = ((float)t*0.017);//cm
sum = lengthTemp + sum ;
}
lengthTemp = sum/5.0;
return lengthTemp;
}
3.主函数测试程序:
float length;
//延时函数初始化
Systick_DelayMs(10); //这里用的系统滴答定时器延时
hcsr04_NVIC(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
USART_Config();//串口服务程序,这里我用的火哥的串口一
Hcsr04Init();
while(1)
{
length = Hcsr04GetLength();
printf("距离为:%.3fcmn",length);
Systick_DelayMs(1000);
}
四.效果图
上一篇:基于STM32F103C8T6的超声波测距示例
下一篇:记STM32之PWM学习笔记 ---PWM原理
推荐阅读最新更新时间:2024-11-03 19:13
设计资源 培训 开发板 精华推荐
- 基于STM32G474VE的电力电子实验控制核心板
- GPIO_Control_SSR
- STEVAL-ISA076V1,基于 L6924D 的锂离子/锂聚合物电池集成电源开关的电池充电器演示板
- 使用 IXYS 的 IXDN430YI 的参考设计
- PCA9635 16位LED驱动器典型应用电路
- IP6805U QI充电板
- 用于 Intel 486TM DX4TM Overdrive 微处理器的 LT1584CT 7A 低压差稳压器的典型应用
- 【训练营】【实战训练营】万能遥控器 699520A
- 使用 NXP Semiconductors 的 TDA3681 的参考设计
- LT1171HVIQ、-28/2.5A 负升压稳压器的典型应用
- TE 官微人工客服功能上线,可以与 TE 技术专家直接微信沟通了!
- 直播|基于英特尔® Agilex™ FPGA的PCIe Gen5和CXL解决方案
- Microchip最新SAM 以及 PIC32单片机软件开发平台-- MPLAB® Harmony V3介绍 ”
- 免费申请恩智浦Cortex开发板
- EEWorld下载中心大批技术资料等你来领,还有好礼相助
- 【有奖直播】 聚焦语音识别核心技术,走进Microchip Timberwolf™音频处理器研讨会
- 来翻牌吧!解锁示波器的N种玩法
- EEWorld邀你来拆解(第15期)拆起来!
- 秋风送爽,你来答题我送礼!看Maxim 深入浅出低功耗处理器视频精彩为您呈现!