基于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轮询开发相关推荐

  1. CP340/CP341基于ASCII驱动协议的多站点轮询

    西门子SIMATIC S7系列串行通信模块,包括CP340.CP341.CP440-1.CP441-1/2.CPU313C/314C-2PtP以及ET200S的1SI 3964/ASCII等,都支持A ...

  2. Comet 反Ajax: 基于jQuery与PHP实现Ajax长轮询(LongPoll)

    传统的AJAX轮询方式,客服端以用户定义的时间间隔去服务器上查询最新的数据.种这种拉取数据的方式需要很短的时间间隔才能保证数据的精确度,但太短的时间间隔客服端会对服务器在短时间内发送出多个请求. 反转 ...

  3. (原创)Linux设备轮询机制分析

    一. 设备轮询机制的基本思想 所谓的设备轮询机制实际上就是利用网卡驱动程序提供的NAPI机制加快网卡处理数据包的速度,因为在大流量的网络环境当中,标准的网卡中断加上逐层的数据拷贝和系统调用会占用大量的 ...

  4. WEB消息提醒实现之二 实现方式-Jquery Ajax长轮询

    #Jquery Ajax长轮询 ##原理 Jquery Ajax长轮询的原理主要是,前台客户端发送ajax请求到服务器,服务器接收到请求之后会保持住连接,直到有新消息才返回响应信息并关闭连接,客户端处 ...

  5. 【详解】Ribbon 负载均衡服务调用原理及默认轮询负载均衡算法源码解析、手写

    Ribbon 负载均衡服务调用 一.什么是 Ribbon 二.LB负载均衡(Load Balancer)是什么 1.Ribbon 本地负载均衡客户端 VS Nginx 服务端负载均衡的区别 2.LB负 ...

  6. 51单片机 普中V2 超声波测距 报警 显示 基于MCS51单片机的超声波测距模块的开发

    基于MCS51单片机的超声波测距模块的开发 采用C51程序设计语言,完成下列功能要求. l 必选功能: (1) 超声波模块和单片机的接口设计,画出完整的电路原理图.(15分) (2) 开发板上电时,显 ...

  7. STM32单片机基于HAL库开发HC-SR04 超声波测距模块(终极版)

    参考: 某宝HC-SR04 超声波测距模块商品详情页 STM32L051C8T6 HAL库 输入捕获进行超声波测距 案例 STM32CubeMX学习笔记3--TIM2输入捕获(SR-04测距) cub ...

  8. 51单片机项目设计:基于超声波的 车库停车系统、车位检测系统设计(8个超声波测距模块)keil+protues仿真

    基于51单片机的车库停车系统 代码仿真资料链接https://download.csdn.net/download/mbs520/12742296 一.设计要求: 毕业设计原题: 本设计主要用于室内停 ...

  9. 超声波测距模块HC-SR04详解(基于51单片机)

    本篇文章是个人整理的包含超声波测距模块HC-SR04的基本介绍与基本工作原理以及分别通过LCD1602.数码管和串口显示距离的实例讲解与代码的笔记,部分内容来自<HC-SR04超声波测距模块说明 ...

  10. 基于Kinetis 60、HC-SR04超声测距模块的简易水情测量装置

    单片机:Kinetis 60 龙邱开发板 开发环境:IAR Embedded Workbench IDE 文章目录 一.HC-SR04超声测距模块介绍 1.1 超声波测距模块简介 1.2 超声波测距模 ...

最新文章

  1. 可能是全网写特征工程最通透的...
  2. Systick 延时函数详解
  3. MySQL自增字段并发插入导致死锁
  4. C# 连接SQLServer数据库及登录验证知识
  5. 突发!HashiCorp禁止在中国使用企业版VAULT软件
  6. 蘑菇街2015校招 Java研发笔试题 详解,2015java
  7. Error detection in Knowledge Graphs: Path Ranking, Embeddings or both?-学习笔记
  8. 转答寒冬的面试题(1)
  9. 计算机组成与结构r形式,计算机组成复习(自己整理的)
  10. ajax上送src,使用script的src实现跨域和类似ajax效果
  11. 四周年了,谈谈一个程序员的职场心得
  12. java库存审核表_JAVA库存案例
  13. android.view.VelocityTracker
  14. java 判断5张牌的组成
  15. 字体编辑用中日韩汉字Unicode编码表
  16. 软件测试用例朋友圈发表功能,微信发朋友圈测试用例
  17. CentOS 6.5 安装Redis并设置开机自启动
  18. 日拱一卒,“功不唐捐
  19. 摄影口诀--针对不同情景
  20. 《Python自然语言处理-雅兰·萨纳卡(Jalaj Thanaki)》学习笔记:07 规则式自然语言处理系统

热门文章

  1. 如何修改计算机mac,苹果电脑MAC地址修改的方法
  2. Unity手机游戏广告接入的大致思路(Android和iOS)
  3. (1)地图的理解及地图的类型介绍
  4. 版权微talk | 两部门发文,拟出台相关方案,全面加强知识产权保护
  5. PAT 甲级1021 Deepest Root
  6. Matlab c2d离散用法
  7. 哈工大c语言作业,哈工大c语言-练习题
  8. 2018---2019 数学四班张子琪 C语言设计总结
  9. 软件开发工具——理论篇
  10. 荣耀笔记本锐龙版和linux,在家办公的最佳利器:荣耀笔记本14锐龙版体验