基于STM32F407的测距模块HY-SRF05轮询开发
基于STM32F407的测距模块HY-SRF05轮询开发
HY-SRF05作为基础测距模块,在开发与学习中经常会用到,且成本低廉,开发简单,但是由于单个测距模块并不能很好的测量全面的距离,所以,多个模块的操作就显得十分重要。
代码如下:
u8 timeget=0;
char meter=0;
u16 SRF=0;
float UltrasonicWave_Distance=0;
u32 Time=0;
int temp;
//
/*
作者:Z.J. 01190949
代码说明:HY_SRF05超声波测距模块反馈
硬件连线说明:
//HY-SRF05模块1占用:
TRIG------PG2:触发
ECHO------PD12:接收:TIM4通道1,APB1
OUT-------PE4:输出(不用)
(单个测试)//
*/
/*
3个模块轮询
占用如下:
TRIG1------PG11
TRIG2------PG12
TRIG3------PG13ECHO1-------PD12
ECHO2-------PD13
ECHO3-------PD14
*////void TIM4_ICap_Init(u16 arr,u16 psc)
{TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_ICInitTypeDef TIM_ICInitStructure;NVIC_InitTypeDef NVIC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitTypeDef GPIO_InitStructures;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);//使能GPIO时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); //TIM4时钟//Trig 采用IO口TRIG触发测距,给至少10us的高电平信号PG2GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHzGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOG,&GPIO_InitStructure);//Echo 通过IO口Echo输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2;PE5GPIO_InitStructures.GPIO_Mode =GPIO_Mode_AF; //复用GPIO_InitStructures.GPIO_OType =GPIO_OType_PP;GPIO_InitStructures.GPIO_Pin =GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14; // PD12GPIO_InitStructures.GPIO_PuPd =GPIO_PuPd_DOWN; //下拉GPIO_InitStructures.GPIO_Speed =GPIO_Speed_50MHz;GPIO_Init(GPIOD,&GPIO_InitStructures);GPIO_PinAFConfig(GPIOD,GPIO_PinSource12,GPIO_AF_TIM4); //GPIOD12 映射TIM4GPIO_PinAFConfig(GPIOD,GPIO_PinSource13,GPIO_AF_TIM4);GPIO_PinAFConfig(GPIOD,GPIO_PinSource14,GPIO_AF_TIM4);TIM_TimeBaseInitStructure.TIM_Period=arr; //自动重装载值TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //预分频TIM_TimeBaseInitStructure.TIM_CounterMode =TIM_CounterMode_Up; //向上计数TIM_TimeBaseInitStructure.TIM_ClockDivision =TIM_CKD_DIV1;TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure); //TIM3初始化TIM_ICInitStructure.TIM_Channel =TIM_Channel_1;//通道1TIM_ICInitStructure.TIM_ICFilter =0X00;//不滤波TIM_ICInitStructure.TIM_ICPolarity =TIM_ICPolarity_Rising;//向上捕获TIM_ICInitStructure.TIM_ICSelection =TIM_ICSelection_DirectTI;//映射到TI1TIM_ICInitStructure.TIM_ICPrescaler =TIM_ICPSC_DIV1;//不分频TIM_ICInit(TIM4,&TIM_ICInitStructure);TIM_ICInitStructure.TIM_Channel =TIM_Channel_2;//通道2TIM_ICInitStructure.TIM_ICFilter =0X00;//不滤波TIM_ICInitStructure.TIM_ICPolarity =TIM_ICPolarity_Rising;//向上捕获TIM_ICInitStructure.TIM_ICSelection =TIM_ICSelection_DirectTI;//映射到TI2TIM_ICInitStructure.TIM_ICPrescaler =TIM_ICPSC_DIV1;//不分频TIM_ICInit(TIM4,&TIM_ICInitStructure);TIM_ICInitStructure.TIM_Channel =TIM_Channel_3;//通道3TIM_ICInitStructure.TIM_ICFilter =0X00;//不滤波TIM_ICInitStructure.TIM_ICPolarity =TIM_ICPolarity_Rising;//向上捕获TIM_ICInitStructure.TIM_ICSelection =TIM_ICSelection_DirectTI;//映射到TI3TIM_ICInitStructure.TIM_ICPrescaler =TIM_ICPSC_DIV1;//不分频TIM_ICInit(TIM4,&TIM_ICInitStructure);//TIM_ClearFlag(TIM4,TIM_FLAG_Update);TIM_ITConfig(TIM4,TIM_IT_CC1|TIM_IT_CC2|TIM_IT_CC3,ENABLE);//TIM_CCxCmd(TIM4, TIM_Channel_1|TIM_Channel_2|TIM_Channel_3, TIM_CCx_Enable);NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;NVIC_Init(&NVIC_InitStructure);TIM_Cmd(TIM4,ENABLE);printf("aa");}u8 CAPTURE_STA_TIM4CH[3] = {0};u16 CAPTURE_VAL_TIM4CH[3];u16 CAPTURE_UP_TIM4CH[3], CAPTURE_DOWN_TIM4CH[3];u8 TIM4_ICapture_OFProtocol=0; //OF→overflow溢出 定义一个溢出标记协议u16 TIM4_ICapture_val; //定义一个变量来存放 定时器4的值void TIM4_IRQHandler(void) //TIM4中断服务函数
{if((CAPTURE_STA_TIM4CH[0]&0x80) == 0) { //还未捕获成功printf("kk1");if(TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET) { //捕获1发生捕获事件if(CAPTURE_STA_TIM4CH[0]&0x40) { //捕获到一个下降沿CAPTURE_STA_TIM4CH[0] |= 0x80; //标记成功捕获到一次高电平脉宽CAPTURE_DOWN_TIM4CH[0] = TIM_GetCapture1(TIM4);if(CAPTURE_DOWN_TIM4CH[0] >= CAPTURE_UP_TIM4CH[0]){CAPTURE_VAL_TIM4CH[0] = CAPTURE_DOWN_TIM4CH[0] - CAPTURE_UP_TIM4CH[0];}else CAPTURE_VAL_TIM4CH[0] = 0xffff + CAPTURE_DOWN_TIM4CH[0] - CAPTURE_UP_TIM4CH[0];TIM_OC1PolarityConfig(TIM4, TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获} else { //还未开始,第一次捕获上升沿CAPTURE_STA_TIM4CH[0] = 0; //清空CAPTURE_VAL_TIM4CH[0] = 0;CAPTURE_UP_TIM4CH[0] = TIM_GetCapture1(TIM4);CAPTURE_STA_TIM4CH[0] |= 0x40; //标记捕获到了上升沿TIM_OC1PolarityConfig(TIM4, TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获} TIM_ClearFlag(TIM4, TIM_FLAG_CC1); //清除状态标志}} if((CAPTURE_STA_TIM4CH[1]&0x80) == 0) { //还未捕获成功//printf("kk1");if(TIM_GetITStatus(TIM4, TIM_IT_CC2) != RESET) { //捕获2发生捕获事件if(CAPTURE_STA_TIM4CH[1]&0x40) { //捕获到一个下降沿CAPTURE_STA_TIM4CH[1] |= 0x80; //标记成功捕获到一次高电平脉宽CAPTURE_DOWN_TIM4CH[1] = TIM_GetCapture2(TIM4); //获取捕获2计数if(CAPTURE_DOWN_TIM4CH[1] >= CAPTURE_UP_TIM4CH[1]){CAPTURE_VAL_TIM4CH[1] = CAPTURE_DOWN_TIM4CH[1] - CAPTURE_UP_TIM4CH[1]; }elseCAPTURE_VAL_TIM4CH[1] = 0xffff + CAPTURE_DOWN_TIM4CH[1] - CAPTURE_UP_TIM4CH[1];TIM_OC2PolarityConfig(TIM4, TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获} else { //还未开始,第一次捕获上升沿CAPTURE_STA_TIM4CH[1] = 0; //清空CAPTURE_VAL_TIM4CH[1] = 0;CAPTURE_UP_TIM4CH[1] = TIM_GetCapture2(TIM4);CAPTURE_STA_TIM4CH[1] |= 0x40; //标记捕获到了上升沿TIM_OC2PolarityConfig(TIM4, TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获}TIM_ClearFlag(TIM4, TIM_FLAG_CC2); //清除状态标志 }}if((CAPTURE_STA_TIM4CH[2]&0x80) == 0) { //还未捕获成功//printf("kk1");if(TIM_GetITStatus(TIM4, TIM_IT_CC3) != RESET) { //捕获2发生捕获事件if(CAPTURE_STA_TIM4CH[2]&0x40) { //捕获到一个下降沿CAPTURE_STA_TIM4CH[2] |= 0x80; //标记成功捕获到一次高电平脉宽CAPTURE_DOWN_TIM4CH[2] = TIM_GetCapture3(TIM4); //获取捕获2计数if(CAPTURE_DOWN_TIM4CH[2] >= CAPTURE_UP_TIM4CH[2]){CAPTURE_VAL_TIM4CH[2] = CAPTURE_DOWN_TIM4CH[2] - CAPTURE_UP_TIM4CH[2]; }elseCAPTURE_VAL_TIM4CH[2] = 0xffff + CAPTURE_DOWN_TIM4CH[2] - CAPTURE_UP_TIM4CH[2];TIM_OC3PolarityConfig(TIM4, TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获} else { //还未开始,第一次捕获上升沿CAPTURE_STA_TIM4CH[2] = 0; //清空CAPTURE_VAL_TIM4CH[2] = 0;CAPTURE_UP_TIM4CH[2] = TIM_GetCapture3(TIM4);CAPTURE_STA_TIM4CH[2] |= 0x40; //标记捕获到了上升沿TIM_OC3PolarityConfig(TIM4, TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获}TIM_ClearFlag(TIM4, TIM_FLAG_CC3); //清除状态标志 }} if(CAPTURE_STA_TIM4CH[0]&0x80) { //成功捕获到了一次上升沿 //溢出时间总和printf(" CAPTURE_VAL_TIM4CH[0]=%d",CAPTURE_VAL_TIM4CH[0]);UltrasonicWave_Distance=(double)CAPTURE_VAL_TIM4CH[0]*170*100/10000;printf("Distance%d:%f cm\r\n",SRF,UltrasonicWave_Distance);//USART打印总的高点平时间CAPTURE_STA_TIM4CH[0] = 0;} if(CAPTURE_STA_TIM4CH[1]&0x80) { //成功捕获到了一次上升沿 //溢出时间总和printf(" CAPTURE_VAL_TIM4CH[1]=%d",CAPTURE_VAL_TIM4CH[1]);UltrasonicWave_Distance=(double)CAPTURE_VAL_TIM4CH[1]*170*100/10000;printf("Distance%d:%f cm\r\n",SRF,UltrasonicWave_Distance);//USART打印总的高点平时间CAPTURE_STA_TIM4CH[1] = 0;} if(CAPTURE_STA_TIM4CH[2]&0x80) { //成功捕获到了一次上升沿 //溢出时间总和printf(" CAPTURE_VAL_TIM4CH[2]=%d",CAPTURE_VAL_TIM4CH[2]);UltrasonicWave_Distance=(double)CAPTURE_VAL_TIM4CH[2]*170*100/10000;printf("Distance%d:%f cm\r\n",SRF,UltrasonicWave_Distance);//USART打印总的高点平时间CAPTURE_STA_TIM4CH[2] = 0;}
}// if((TIM4_ICapture_OFProtocol&0X80)==0)//还未成功捕获 8*16 = 128 =2的7次方 第八位
// {
// //printf("kk1");
// if(TIM_GetITStatus(TIM4,TIM_IT_CC1)==1)
// {
// //printf("kk2");
// if(TIM4_ICapture_OFProtocol&0X40) //捕获到一个下降沿 //其实是判断前一次是否捕捉到了上升沿 如果是 0x40 第七位为高 如果捕捉过 那么这次一定是下降沿
// {
// printf("aa");
// TIM4_ICapture_OFProtocol|=0X80; //标记成功捕获到一次高电平脉宽
// TIM4_ICapture_val=TIM_GetCapture1(TIM4);//获取当前的捕获值.
// printf("TIM4_ICapture_val%d=%u\r\n",SRF,TIM4_ICapture_val);
// TIM_Cmd(TIM4,ENABLE); //关闭定时器4
// TIM_OC1PolarityConfig(TIM4,TIM_OCPolarity_High); //CC1P=0 设置为上升沿捕获
// TIM_Cmd(TIM4,ENABLE);
// }else //还未开始,第一次捕获上升沿
// {
// printf("bb");
// TIM4_ICapture_OFProtocol=0; //清空
// TIM4_ICapture_val=0;
// TIM4_ICapture_OFProtocol|=0X40; //标记捕获到了上升沿
// TIM_Cmd(TIM4,DISABLE); //关闭定时器4
// TIM_SetCounter(TIM4,0);
// TIM_OC1PolarityConfig(TIM4,TIM_OCPolarity_Low); //CC1P=1 设置为下降沿捕获
// TIM_Cmd(TIM4,ENABLE); //使能定时器4
// }
// }
// }
// TIM_ClearITPendingBit(TIM4, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位void Ultrasonic_StartMeasure() //开启超声波 向给 trig 发送至少10 us的高电平脉冲(模块自动向外发送8个40K的方波)
{//printf("what%d",SRF);GPIO_WriteBit(GPIOG,GPIO_Pin_11,1);delay_ms(10); //延时GPIO_WriteBit(GPIOG,GPIO_Pin_11,0);printf("02\t"); GPIO_WriteBit(GPIOG,GPIO_Pin_12,1);delay_ms(10); //延时GPIO_WriteBit(GPIOG,GPIO_Pin_12,0);printf("03\t");GPIO_WriteBit(GPIOG,GPIO_Pin_13,1);delay_ms(10); //延时GPIO_WriteBit(GPIOG,GPIO_Pin_13,0);printf("04\t");;
}
.h文件如下
#ifndef _HY_SRF05_H
#define _HY_SRF05_H
#include "sys.h"
#define Trig PGout(2)
//void sci(void);//串口通信
extern u16 SRF;
//void ranging(void);//测距
void TIM4_ICap_Init(u16 arr,u16 psc);
void Ultrasonic_Init(void);
void Ultrasonic_StartMeasure(void);
//void Ultrasonic_Judge(void);
#endif
我这里使用的是TIM4的通道1,2,3,在原本的开发中本来只想使用通道1接收3个信号来源,但是后来发现没有办法完成,因此修改了3个触发与3个接收。且因为未知原因,GPIO_SetBits在使用时,没有办法输出高电平,所以改用了GPIO_WriteBit,当然如果你的环境下可以使用GPIO_SetBits的话,我还是建议用的,毕竟GPIO_WriteBit会提示警告。
顺带一提,我已经把他们封装成了一个方法,在使用的时候只需要调用就可以了,不需要在写其他的东西了。.h的一些方法可能有点多余,不影响使用,看不惯可以删除或者注释。如有疑问,欢迎私信~
基于STM32F407的测距模块HY-SRF05轮询开发相关推荐
- CP340/CP341基于ASCII驱动协议的多站点轮询
西门子SIMATIC S7系列串行通信模块,包括CP340.CP341.CP440-1.CP441-1/2.CPU313C/314C-2PtP以及ET200S的1SI 3964/ASCII等,都支持A ...
- Comet 反Ajax: 基于jQuery与PHP实现Ajax长轮询(LongPoll)
传统的AJAX轮询方式,客服端以用户定义的时间间隔去服务器上查询最新的数据.种这种拉取数据的方式需要很短的时间间隔才能保证数据的精确度,但太短的时间间隔客服端会对服务器在短时间内发送出多个请求. 反转 ...
- (原创)Linux设备轮询机制分析
一. 设备轮询机制的基本思想 所谓的设备轮询机制实际上就是利用网卡驱动程序提供的NAPI机制加快网卡处理数据包的速度,因为在大流量的网络环境当中,标准的网卡中断加上逐层的数据拷贝和系统调用会占用大量的 ...
- WEB消息提醒实现之二 实现方式-Jquery Ajax长轮询
#Jquery Ajax长轮询 ##原理 Jquery Ajax长轮询的原理主要是,前台客户端发送ajax请求到服务器,服务器接收到请求之后会保持住连接,直到有新消息才返回响应信息并关闭连接,客户端处 ...
- 【详解】Ribbon 负载均衡服务调用原理及默认轮询负载均衡算法源码解析、手写
Ribbon 负载均衡服务调用 一.什么是 Ribbon 二.LB负载均衡(Load Balancer)是什么 1.Ribbon 本地负载均衡客户端 VS Nginx 服务端负载均衡的区别 2.LB负 ...
- 51单片机 普中V2 超声波测距 报警 显示 基于MCS51单片机的超声波测距模块的开发
基于MCS51单片机的超声波测距模块的开发 采用C51程序设计语言,完成下列功能要求. l 必选功能: (1) 超声波模块和单片机的接口设计,画出完整的电路原理图.(15分) (2) 开发板上电时,显 ...
- STM32单片机基于HAL库开发HC-SR04 超声波测距模块(终极版)
参考: 某宝HC-SR04 超声波测距模块商品详情页 STM32L051C8T6 HAL库 输入捕获进行超声波测距 案例 STM32CubeMX学习笔记3--TIM2输入捕获(SR-04测距) cub ...
- 51单片机项目设计:基于超声波的 车库停车系统、车位检测系统设计(8个超声波测距模块)keil+protues仿真
基于51单片机的车库停车系统 代码仿真资料链接https://download.csdn.net/download/mbs520/12742296 一.设计要求: 毕业设计原题: 本设计主要用于室内停 ...
- 超声波测距模块HC-SR04详解(基于51单片机)
本篇文章是个人整理的包含超声波测距模块HC-SR04的基本介绍与基本工作原理以及分别通过LCD1602.数码管和串口显示距离的实例讲解与代码的笔记,部分内容来自<HC-SR04超声波测距模块说明 ...
- 基于Kinetis 60、HC-SR04超声测距模块的简易水情测量装置
单片机:Kinetis 60 龙邱开发板 开发环境:IAR Embedded Workbench IDE 文章目录 一.HC-SR04超声测距模块介绍 1.1 超声波测距模块简介 1.2 超声波测距模 ...
最新文章
- 可能是全网写特征工程最通透的...
- Systick 延时函数详解
- MySQL自增字段并发插入导致死锁
- C# 连接SQLServer数据库及登录验证知识
- 突发!HashiCorp禁止在中国使用企业版VAULT软件
- 蘑菇街2015校招 Java研发笔试题 详解,2015java
- Error detection in Knowledge Graphs: Path Ranking, Embeddings or both?-学习笔记
- 转答寒冬的面试题(1)
- 计算机组成与结构r形式,计算机组成复习(自己整理的)
- ajax上送src,使用script的src实现跨域和类似ajax效果
- 四周年了,谈谈一个程序员的职场心得
- java库存审核表_JAVA库存案例
- android.view.VelocityTracker
- java 判断5张牌的组成
- 字体编辑用中日韩汉字Unicode编码表
- 软件测试用例朋友圈发表功能,微信发朋友圈测试用例
- CentOS 6.5 安装Redis并设置开机自启动
- 日拱一卒,“功不唐捐
- 摄影口诀--针对不同情景
- 《Python自然语言处理-雅兰·萨纳卡(Jalaj Thanaki)》学习笔记:07 规则式自然语言处理系统