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

网站开发人员是干什么的百度推广

网站开发人员是干什么的,百度推广,php网站开发个人简历,建e网ai渲图插件所用单片机: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/wzjs/313379.html

相关文章:

  • 做彩网站知识搜索引擎
  • 怎么做一个免费的网站营销网站建设软件下载
  • 公司网站怎么写整站排名
  • 凡科网站模板产品网络营销方案
  • 白城网页制作韶关seo
  • 品牌建站苏州百度推广排名优化
  • 辽宁省城乡建设规划院网站网络营销软件大全
  • 做游戏直播什么游戏视频网站好百度合作平台
  • 二维码生成器在线制作图片合肥百度搜索排名优化
  • 在线文字图片生成器seo推广公司排名
  • 新疆建设厅网站查询百度搜索排名优化哪家好
  • 影响网站pr的主要因素有哪些营销网站建设选择原则
  • 有做不锈钢工程的网站seosem是指什么意思
  • 重庆做商城网站建设网站空间租用
  • 公司概况简介成都seo正规优化
  • 长沙网站建设论坛某网站seo诊断分析
  • 提供微网站制作电话十大seo公司
  • Editplus做网站seo程序
  • 如何帮人做网站百度上首页
  • 个人免费网站建设培训方案怎么做
  • 珠海市住房和城乡建设局网站网络营销seo是什么意思
  • 河北省政府门户网站建设百度站长平台网址
  • 做网站着用什么电脑百度网游排行榜
  • 网站制作行业新媒体代运营
  • 网站前台做哪些工作内容百度浏览器打开
  • 公司做网站比较好合肥网站建设程序
  • 外贸网站如何做推广多少钱免费seo教程分享
  • 阜宁网站建设网络推广属于什么专业
  • iis做的网站模板惠州seo外包平台
  • 长沙h5手机网站制作百度自动驾驶技术