当前位置: 首页 > news >正文

网站登记模板包头企业网站建设

网站登记模板,包头企业网站建设,开发网站如何赚钱,wordpress 列表分页所用单片机:STM32F103C8T6 超声波测距模块链接(拼多多):https://mobile.yangkeduo.com/mall_page.html?psWIvk5gnEbW 一、模块使用说明 该链接的超声波模块---HC-SR04支持3种接口模式:GPIO、UART、IIC。本文章仅对常用的GPIO口驱动模式进行说明&#…

所用单片机:STM32F103C8T6

超声波测距模块链接(拼多多):https://mobile.yangkeduo.com/mall_page.html?ps=WIvk5gnEbW

一、模块使用说明

        该链接的超声波模块---HC-SR04支持3种接口模式:GPIO、UART、IIC。本文章仅对常用的GPIO口驱动模式进行说明,读者可自行验证其它接口的可行性。

1.1 特性说明

1.2 工作方式

        如果要用其它接口模式的话,需要对模块的电阻进行配置,如下图:

        GPIO口驱动的工作方式为,单片机给超声波模块Trig引脚发送一个大于10us的高电平,触发HC-SR04发出8个40kHz的方波,并自动检测是否有信号返回,如果有信号返回,就会通过Echo对单片机输出一个高电平,高电平的持续时间就是超声波从发射到返回的时间。 如下时序图;

        必须要注意的一点是,在下面的时序图中也可以看出,单片机给Trig引脚发送10us的高电平后,紧接着要给这个引脚发送低电平;周期最小是200ms!!!也就是说给Trig引脚发送高电平后,不能立刻就读取Echo引脚返回的高电平持续时间!!

         等待Trig一个周期完后,检测Echo引脚高电平的持续时间T,如前所说,高电平的持续时间T就是超声波从发射到返回的时间;那么只要知道声波的速度C,用T*C/2就能得到设备与障碍物的距离D。商家提供的声速计算如下:

        

    二、定时器输入捕获检测Echo高电平的原理    

        定时器输入捕获原理看B站这个up,几分钟就说明白了:【【STM32】动画讲解输入捕获 并实现超声波测距】https://www.bilibili.com/video/BV1HM4m1R75B/?share_source=copy_web&vd_source=91acb6de0cf2d9aa6a14eec0c8d82cdb


        假定定时器工作在向上计数模式,上图中的t1~t2时间段就是我们要测量的高电平持续时间。

        首先设置定时器输入通道X为上升沿捕获,这样t1时刻就会捕获到当前的cnt值。为了方便后续的计算,此时要将计数器的值清零,并且设置定时器输入通道X为下降沿捕获。等到t2时刻,又会触发下降沿捕获,此时的CNT值就是除去溢出时间外的高电平持续时间,记作CCR,再将输入通道X设为上升沿捕获,如此循环。。。。

        如果障碍物距离实在太远,可能导致Echo引脚返回的高电平时间实在太长,以至于超出了定时器重装载计数器的最大值0xffff,此时就会发生溢出。如果代码没有设计考虑溢出的话,就会导致误差过大(整个溢出时间的高电平)。

        因此,驱动这个模块,不仅要使用定时器输入捕获中断,还要使用定时器更新中断,记录溢出的次数。最终的脉宽时间 = 溢出次数 *(计数器重装载值+1)+ (CCR+1)

三、参考代码

3.1 硬件驱动实现

#include "stm32f10x.h"                  // Device header
#include "stdio.h"
#include "stdbool.h"
#include "delay.h"#define TIM_PERIOD	0XFFFFstatic void GpioCofig(void)
{/*GPIO时钟使能*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);/*GPIO引脚配置*/GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;	//超声波Trig触发引脚GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStruct);	GPIO_WriteBit(GPIOB, GPIO_Pin_13, Bit_RESET);//默认上电不触发GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;	//超声波Echo引脚,默认下拉输入0	GPIO_Init(GPIOA, &GPIO_InitStruct);	
}static void TimerCofig(void)
{/*- - - - - - - -使能定时器时钟- - - - - - - - */RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);TIM_InternalClockConfig(TIM1);/*- - - - - - - -时基单元初始化- - - - - - - - */TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStruct.TIM_Prescaler = 72 - 1;TIM_TimeBaseInitStruct.TIM_Period = TIM_PERIOD;TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStruct);/*- - - - - - - -输入捕获结构体初始化- - - - - - - - */TIM_ICInitTypeDef TIM_ICInitStruct;TIM_ICStructInit(&TIM_ICInitStruct);TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;//上升沿捕获TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;//影子寄存器cc1映射到捕获通道TI1TIM_ICInit(TIM1, &TIM_ICInitStruct);/*设置中断*/TIM_ClearFlag(TIM1, TIM_FLAG_Update | TIM_IT_CC1);//清除更新和捕获中断标志位TIM_ITConfig(TIM1, TIM_IT_Update | TIM_IT_CC1, ENABLE);/*- - - - - - - -NVIC配置- - - - - - - - */
//	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//一个工程只分组一次NVIC_InitTypeDef  NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel = TIM1_CC_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;NVIC_Init(&NVIC_InitStruct);NVIC_InitStruct.NVIC_IRQChannel = TIM1_UP_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 3;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3;NVIC_Init(&NVIC_InitStruct);/*- - - - - - - -定时器使能,开始计数- - - - - - - - */TIM_Cmd(TIM1, ENABLE);
}/**
***************************************************
* @brief	超声波测距驱动初始化
* @param
* @return 
***************************************************
*/
void UltrasoundDrvInit(void)
{GpioCofig();TimerCofig();
}

3.2 功能实现代码

        这里我没有使用温度与声速的关系式计算声速,而是直接采取了20℃下的典型值,只是为了方便验证,如果要求更准确可以加温度校准。

typedef struct 
{uint8_t capFinishFlag;		//捕获结束标志位uint8_t capStartFlag;		//捕获开始标志位uint16_t capCcrValue;		//捕获寄存器的值uint16_t capPeriods;		//自动重装载寄存器更新溢出次数
}TIM_ICUserValueType_t;static TIM_ICUserValueType_t g_icValueType = 
{.capFinishFlag = 0,.capStartFlag = 0,.capCcrValue = 0,.capPeriods = 0,
};/**
***************************************************
* @brief	触发超声波探测
* @param
* @return 
***************************************************
*/
void UltrasoundProc(void)
{GPIO_WriteBit(GPIOB, GPIO_Pin_13, Bit_SET);DelayNus(20);GPIO_WriteBit(GPIOB, GPIO_Pin_13, Bit_RESET);/*应当保证低电平时间符合周期要求,这里我有其它办法,就不用延时死等了*/
}static bool CalPulseWidth(uint32_t* pulseWidth)//触发探测后,计算高电平的持续时间
{if (g_icValueType.capFinishFlag == 0){return false;}*pulseWidth = g_icValueType.capPeriods * (TIM_PERIOD + 1) + (g_icValueType.capCcrValue + 1);g_icValueType.capFinishFlag = 0;//捕获结束标志位清零printf("capPeriods is %d\n",g_icValueType.capPeriods);return true;
}/**
***************************************************
* @brief	获取最终和障碍物的距离,cm
* @param	
* @return 
***************************************************
*/
void GetDistance(float* distance)
{uint32_t pulseWidth = 0;
//	while ( CalPulseWidth(&pulseWidth) == false );(void)CalPulseWidth(&pulseWidth);*distance = ((float)pulseWidth*1.0f/10.0f*0.34f)/2.0f;
}
/**
***************************************************
* @brief	定时器1更新中断服务函数
* @param
* @return 
***************************************************
*/
void TIM1_UP_IRQHandler(void)
{if ( TIM_GetITStatus(TIM1, TIM_IT_Update) ){/*实现功能*/g_icValueType.capPeriods ++;TIM_ClearITPendingBit(TIM1, TIM_IT_Update);}TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
}/**
***************************************************
* @brief	定时器1输入捕获中断服务函数
* @param
* @return 
***************************************************
*/
void TIM1_CC_IRQHandler(void)
{if ( TIM_GetITStatus(TIM1, TIM_IT_CC1) != RESET ){//第一次捕获if ( g_icValueType.capStartFlag == 0 ){TIM_SetCounter(TIM1,0);//计数器清零g_icValueType.capPeriods = 0;//之前的自动重装载寄存器溢出次数清零g_icValueType.capCcrValue =0;//存放捕获比较寄存器值的变量清零TIM_OC1PolarityConfig(TIM1, TIM_ICPolarity_Falling);//第一次捕获到上升沿后就把捕获设置为下降沿g_icValueType.capStartFlag = 1;//捕获开始标志置一}//表示为下降沿捕获中断else{g_icValueType.capCcrValue = TIM_GetCapture1(TIM1);//获取捕获比较寄存器的数值,这就是除去溢出外的高电平时间TIM_OC1PolarityConfig(TIM1, TIM_ICPolarity_Rising);//把捕获设置为上升沿g_icValueType.capStartFlag = 0;//开始捕获标志清零g_icValueType.capFinishFlag = 1;//捕获结束标志置一}}TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);//无条件,必须要
}

3.3 .h头文件

#ifndef _ULTRASOUND_DRV_H_
#define _ULTRASOUND_DRV_H_#include "stdint.h"
/**
***************************************************
* @brief	超声波测距驱动初始化
* @param
* @return 
***************************************************
*/
void UltrasoundDrvInit(void);/**
***************************************************
* @brief	触发超声波探测,两次触发之间最好间隔60ms,因此函数60ms调用一次
* @param
* @return 
***************************************************
*/
void UltrasoundProc(void);/**
***************************************************
* @brief	获取最终和障碍物的距离,cm
* @param
* @return 
***************************************************
*/
void GetDistance(float* distance);
#endif

3.4 主函数测试代码

        能够显示数值,验证功能就行,下面的代码仅供参考,需要自己根据自己的工程进行修改。

注意,代码中有个60ms的延时一定是要放在UltrasoundProc();后不可改位置不可删除的,用于保证Trig的触发信号不会影响到Echo的回响信号,也就是之前提到的200ms周期!!

static void DrvInit(void)
{DelayInit();SystickInit();BleDrvInit();CarDrvInit();SteeringDrvInit();UltrasoundDrvInit();
}static void AppInit(void)
{RegTaskScheduleCb(TaskScheduleCb);
}int main(void)
{DrvInit();AppInit();float  distance = 1.0f;while(1){TaskHandler();//这个不用管,忽略,你们不用写UltrasoundProc();DelayNms(60);//这个延时十分重要,不可省略,保证周期(虽然不是200ms,也能用)GetDistance(&distance);printf("DISTANCE:%.2fcm\r\n\n",distance);//需要会串口,不会可以搜文章、视频,或者用其它显示distance = 0;DelayNms(2000);}
}

http://www.dtcms.com/a/534516.html

相关文章:

  • 网站搭建服务器需要多少钱房地产网站推广
  • 永嘉网站优化企业邮箱来一个
  • 网站设计大概收费范围宜宾市规划建设局网站
  • 佛山专业的做网站的wordpress开发商城
  • 建单页网站网站正在建设中单页
  • 台州哪家做企业网站比较好2345网站登录
  • 橙色 网站六安政务中心网站
  • 做电子手抄报的网站建设一个网站平台
  • 温州网站设计哪家公司好网站空间空间
  • 北辰网站建设公司永湖网站建设
  • 如何写网站建设报告页面升级每天自动更新
  • 邯郸网址场百度推广和优化有什么区别
  • 怎么了解百度蜘蛛到哪个网站公司注册名字
  • 建立自己的网站费用网站的关键字 设置
  • 杭州网站开发凡客logo设计网站排行榜
  • 免费自助建站排名上海全上海全国网站建设
  • 哪里网站建设专业app和微网站的区别是什么
  • html5 wap网站毕业设计做网站有什么好处
  • 2023年没有封闭的网站有哪些seo怎么收费的
  • 网站开发毕设任务书建设厅查询网站
  • 阜宁做网站网站建设培训的心得
  • 知了网站后台建设自己网站软件下载
  • 描写做网站专业的句子域名抢注哪个平台好
  • 做网站的可以信吗在线音乐网站 用什么做
  • 网站添加备案wordpress 手机网站支付宝
  • 广东建设教育协会网站首页视频网站直播如何做
  • 邢台做网站推广费用北京珠宝网站建设
  • 上海手机网站案例什么是网络营销理论
  • 温州市建设质量监督站网站做外贸如何访问国外网站
  • 响应式网站源码上海造价信息网官网