STM32超声波模块测距

2023-10-30

特别注意!

单独t-link只能提供3.3v电压!模块接5v电压只能收到3.3V。供电的时候请接上micro口!

模块介绍
HC-SR04超声波模块可提供2cm~400cm的距离感测功能,测量精度可以达到3mm。
通过声音340m/s * t / 2可以算出距离.在这里插入图片描述

接线图
A9、A10串口可以选择ttl转usb淘宝十几块一个。B8、B9、5V、GND接在HC-SR04超声波模块
在这里插入图片描述

结合时序图
我们按照时序图从上到下从左到右进行查看,主要分成3块,按照我们的代码,第一块PB8默认低电平随后PB8发起高电平,接着模块内部会工作发送脉冲,同时检测PB9返回的高电平时间。

在这里插入图片描述
主要代码
这里有用到SYSTICK作为全局延时功能,USART1串口通信模块.

#include "stm32f10x.h"
#include "GPIOLIKE51.h"
#include "stdio.h"

static u8  fac_us=0;                                    //us延时倍乘数                           
static u16 fac_ms=0;                                    //ms延时倍乘数

int fputc( int ch, FILE *f ){
		USART_SendData(USART1,(u8) ch );
		while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
		return ch;
}

//初始化延迟函数
//当使用OS的时候,此函数会初始化OS的时钟节拍
//SYSTICK的时钟固定为HCLK时钟的1/8
//SYSCLK:系统时钟
void delay_init(){
        SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);       	  //选择外部时钟  HCLK/8
        fac_us=SystemCoreClock/8000000;                               	  //为系统时钟的1/8  
        fac_ms=(u16)fac_us*1000;                                      	  //非OS下,代表每个ms需要的systick时钟数   
} 

//SysTick 微秒计时器
void delay_us(uint32_t nus){
	u32 temp;                     
	SysTick->LOAD=nus*fac_us;                             //时间加载                           
	SysTick->VAL=0x00;                                    //清空计数器
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;        	  //开始倒数         
	do{
		temp=SysTick->CTRL;
    }while((temp&0x01)&&!(temp&(1<<16)));                 //等待时间到达   
	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;        	  //关闭计数器
	SysTick->VAL =0X00;                                   //清空计数器  
}

//SysTick 毫秒计时器
void delay_ms(uint32_t nms){
	u32 temp;                  
	SysTick->LOAD=(u32)nms*fac_ms;                        //时间加载(SysTick->LOAD为24bit)
	SysTick->VAL =0x00;                                   //清空计数器
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;      		  //开始倒数  
	do{
		temp=SysTick->CTRL; 
	}while((temp&0x01)&&!(temp&(1<<16)));                 //等待时间到达   
	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;       		  //关闭计数器
	SysTick->VAL =0X00;    
}

void USART1_init(){
	
	GPIO_InitTypeDef GPIO_InitStructure;
	//配置串口结构体
	USART_InitTypeDef USART_InitStructure;
	//NVIC结构体
	NVIC_InitTypeDef NVIC_InitStructure;
	// 打开功能复用IO时钟,用于串口通信
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);	
	//使能GPIO硬件时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	//使能串口1硬件时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	
	/* 配置PA9和PA10为复用功能模式 */

	//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);					//初始化GPIOA.10  
	
	USART_InitStructure.USART_BaudRate = 9600;
	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); //初始化串口1
	
	/* Configure the NVIC Preemption Priority Bits */  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
	
	/* Enable the USARTy Interrupt */
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	
	NVIC_Init(&NVIC_InitStructure);
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);		    //配置为接收中断
	USART_Cmd(USART1, ENABLE);  						  	//使能串口1

}


/**
*	配置Gpio PB8为发送 PB9为返回
*/
void GPIOB_init(void){
	GPIO_InitTypeDef GPIO_InitStruct;
	/* GPIOB时钟初始化 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8;  			//发送电平引脚
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; 	//GPIO_Mode_Out_PP 推挽输出
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;  			//返回电平引脚
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_Init(GPIOB, &GPIO_InitStruct);
	
}

int32_t sr04_get_destace(){
	int32_t t = 0; //时间 us微秒
	int32_t d = 0; //距离 mm毫米
	PBout(8)=0;

	//向PB8发送高电平
	PBout(8) = 1; 
	//持续运行至少大于10_us
	delay_us(20);
	//向PB8发送低电平
	PBout(8) = 0; 
	//循环等待PB9返回的高电平
	while(PBin(9) == 0){
		t++; //累计1微秒
		delay_us(1);
		if(t >= 1000000){
			//超时返回-1
			return -1;
		}
	}
	//测量高电平时长
	while(PBin(9)){
		t++; //累计9微秒 
		delay_us(9); //声音速度340m/s 9us == 3mm
		if(t >= 1000000){
			//未检测高电平超时返回-2
			return -2;
		}
	}
	//计算距离 距离3mm乘以时间us除以2得出距离
	d=3*t/2;
	return d;
}

int main(void){
	//距离mm
    int32_t d = 0;
	delay_init();
	//串口初始化 TXD->PA9,RXD->PA10 接在ttl转usb记得反接
	USART1_init();
	//HC-SR04传感器相关初始化,使用的基础IO->输出PB8,接收PB9
	GPIOB_init();
	printf("distance:%dmm\r\n", d);
	while(1)
    {
		d = sr04_get_destace();
		if(d > 0){
			//距离大于20mm且小于等于4m才会打印输出
			if(d>=20 && d<=4000){
				printf("distance:%dmm\r\n", d);
			}

		}
		//延迟一秒
		delay_ms(1000);
    }

}
//  "GPIOLIKE51.h"
#ifndef __GPIOLIKE51_H
#define __GPIOLIKE51_H	 

///#include <stm32f10x_lib.h>

//位带操作,实现51类似的GPIO控制功能
//具体实现思想,参考<<CM3权威指南>>第五章(87页~92页).
//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) 
//IO口地址映射
#define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C 
#define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C 
#define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C 
#define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C 
#define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C 
#define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C    
#define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C    

#define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808 
#define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08 
#define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008 
#define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408 
#define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808 
#define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08 
#define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08 
 
//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出 
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入 

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出 
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入 

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出 
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入 

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出 
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入 

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出 
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入

#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出 
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入

#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //输出 
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //输入

#endif

在这里插入图片描述

串口打印配置: STM32重写fputc.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32超声波模块测距 的相关文章

随机推荐

  • C语言编程获取PE文件DOS头

    include
  • seata 1.4.2 无法注册到 nacos2.1.1

    问题 使用docker 部署seata 一直出现数据库连接异常 异常 com mysql cj jdbc exceptions CommunicationsException Communications link failure nett
  • 电机速度曲线规划_S曲线

    导读 电机驱动是很常见的应用 在很多系统中都会碰到需要改变电机的速度以实现相应的控制功能 这就涉及到电机速度曲线规划的问题 本文仅代表记录自己的学习理解 如有错误 欢迎指正 想要S型速度曲线规划的仿真模块的学友请关注公众号 浅谈电机控制 留
  • 一个成熟期货交易系统需要解决哪些问题?

    一个成熟期货交易系统需要解决哪些问题 交易系统绝对不仅仅是时机选择 资金管理 情绪控制这么简单 他是一个系统性的思维 交易系统是一组包含了入场信号 风险控制 资金管理 加减仓机制 可以没有 离场方式等等基本元素的的规则组合 成熟的交易系统是
  • AngularJS概述&指令

    AngularJS 指令 AngularJS 应用组成如下 View 视图 即 HTML Model 模型 当前视图中可用的数据 Controller 控制器 即 JavaScript 函数 可以添加或修改属性 指令 描述 ng app 定
  • android studio cmake 编译找不到ninja解决方案

    https forum cocos com t android studio cmake ninja 77324
  • 偶数斐波那契数列

    斐波那契数列中的每一项都是前两项的和 由和开始生成的斐波那契数列的前项为 1 2 3 5 8 13 21 34 55 89 考虑该斐波那契数列中不超过四百万的项 求其中为偶数的项之和 解题思路 这里我们要是用for循环肯定会超过范围 所以我
  • 警告:隐式声明函数‘xxx’ [-Wimplicit-function-declaration]

    在c编译中 出现此类警告的原因 没有声明原始函数 一般的解决方式 在程序前面增加函数头说明即可 否则是用默认说明 隐式说明 来解释函数调用规则 比如返回值默认是int就是在你不说明时起作用的 以下是摘录的比较好的一篇说明 点击打开链接 1
  • HTML空格占位符 空行,整理,待以后查看

    32 普通的英文半角空格 160 nbsp xA0 no break space 普通的英文半角空格但不换行 12288 中文全角空格 一个中文宽度 8194 ensp en空格 半个中文宽度 8195 emsp em空格 一个中文宽度 8
  • java跨库分页_微服务架构跨库分页解决的四种方案

    引言 微服务架构是一项在云中部署应用和服务的新技术 大部分围绕微服务的争论都集中在容器或其他技术是否能很好的实施微服务 而红帽说API应该是重点 微服务可以在 自己的程序 中运行 并通过 轻量级设备与HTTP型API进行沟通 关键在于该服务
  • JS代码延时执行

    延时执行代码使用window对象的setTimeout函数 第一个参数为要延时执行的代码 第二个参数为延时时间 毫秒单位 例子
  • css置灰属性 模糊属性 滤镜遮罩属性 (一行代码实现)

    网站一行代码置灰 原因都知道 是为了纪念一位伟人 这种把整个页面都变成灰色 下面是css便捷属性 置灰实现方式 filter grayscale 1 效果 模糊度实现方式 filter blur 5px 效果 最后一种是 backdrop
  • 程序员必会的git语法及gitlab、github应用

    文章目录 3分钟掌握git语法及gitlab github应用 关于作者 作者介绍 前言 一 控制版本 1 1 什么是版本 1 2 什么是控制版本 1 3 版本管理工具 二 git 版本管理 2 1 git 介绍 2 2 git 安装 2
  • VSCode下使用markdown导出pdf,导出图片或插入LaTeX公式等使用记录(1)

    记录一下自己觉得比较好用的markdown插件 以及在VSCode下编辑并将markdown的渲染结果导出pdf为或png等格式 1 Markdown All in One VSCode下的markdown插件 目前这个用起来比较丝滑 而且
  • 微服务架构下的移动架构实践

    转载本文需注明出处 EAII企业架构创新研究院 违者必究 如需加入微信群参与微课堂 架构设计与讨论直播请直接回复此公众号 加群 姓名 公司 职位 微信号 大家好 我是普元信息移动产品的负责人 郝振明 很高兴又与大家见面了 今天和大家分享的主
  • 怎么使用51单片机实现人脸识别?

    使用 51 单片机实现人脸识别可以通过以下步骤来实现 准备必要的硬件设备 包括 51 单片机 摄像头和相应的连接线 安装并配置相应的开发环境 如 Keil IAR 等 准备人脸识别所需的人脸数据库 这可以通过手动收集人脸图像并进行标记来实现
  • linux内核态和用户态(通俗易懂)

    一 内核态 用户态概念 内核态 也叫内核空间 是内核进程 线程所在的区域 主要负责运行系统 硬件交互 用户态 也叫用户空间 是用户进程 线程所在的区域 主要用于执行用户程序 二 内核态和用户态的区别 内核态 运行的代码不受任何限制 CPU可
  • 在为水质担忧吗?——水质检测大屏展示系统启动(inscode直观运行)

    前言 作者主页 雪碧有白泡泡 个人网站 雪碧的个人网站 推荐专栏 java一站式服务 React从入门到精通 前端炫酷代码分享 从0到英雄 vue成神之路 uniapp 从构建到提升 从0到英雄 vue成神之路 解决算法 一个专栏就够了 架
  • 动态规划法求解编辑距离问题

    问题描述 设A和B是两个字符串 现在要用最少的字符操作次数 将字符串A转换为字符串B 这里所说的字符操作共有3种 1 删除一个字符 2 插入一个字符 3 将一个字符替换另一个字符 例如 A sfdqxbw B gfdgw 结果为4 问题求解
  • STM32超声波模块测距

    特别注意 单独t link只能提供3 3v电压 模块接5v电压只能收到3 3V 供电的时候请接上micro口 模块介绍 HC SR04超声波模块可提供2cm 400cm的距离感测功能 测量精度可以达到3mm 通过声音340m s t 2可以