STM32计数器/定时器之PWM脉宽捕获+超声波传感器测距 |
您所在的位置:网站首页 › 测量宽度的传感器是什么 › STM32计数器/定时器之PWM脉宽捕获+超声波传感器测距 |
2019.4.1: 调试超声波传感器时候,最先使用的是中断来判断是方法配置成功,结果一直报错,才发现是忘记添加中断配置库文件了…愚人节快乐…具体内容明天补充 其实,超声波传感器工作原理很简单,但是要想高精度、连续不断的快速实现距离测量还是很有难度的。 当然,STM32也是这样,配置PWM体会最为深刻,实现一个功能很简单,但是效率如何呢?PWM的脉宽、周期准不准确,差了几毫秒或者几微妙是为什么,还能改善么?串口通信很简单,那么串口如何连续不断的接收数据又该如何处理呢?(建立串口缓冲区) STM32的启动文件是如何的,.S文件中的具体启动流程如何,在一个简单的程序中各个寄存器是如何工作的呢/ 技术路漫漫,希望自己能够不断思考,质疑… 此外,在硬件编程中,要定义变量时候要注意使用volatitle,比如在此次超声波代码处理过程中,有些变量就没能更新。 参考文章: [1] STM32的计数器的使用 [2] STM32定时器----多通道PWM捕获 [3] STM32 同一定时器四路不同占空比PWM输出+舵机精度精准控制 [4] STM32 高级定时器 [5] STM32 高级基本定时器 1、PWM脉冲捕获STM32 的定时器功能十分强大,有 TIME1 和 TIME8 高级定时器,也有 TIME2~TIME5 通用定时器,还有 TIME6 和TIME7 基本定时器。 1.1 STM32 高级定时器简介参考[4] STM32 高级定时器 1.2 STM32 通用定时器简介STM32 的通用定时器是一个通过可编程预分频器(PSC)驱动的 16 位自动装载计数器(CNT)构成。STM32 的通用定时器可以被用于:测量输入信号的脉冲长度(PWM输入捕获)或者产生输出波形(输出比较和 PWM)等。STM32 的每个通用定时器都是完全独立的,没有互相共享的任何资源。 STM32 的通用定时器 TIMx (TIM2、TIM3、TIM4 和 TIM5) 功能包括: 16 位向上、向下、向上/向下自动装载计数器(TIMx_CNT)。16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 1~65535 之间的任意数值。4 个独立通道(TIMx_CH1~4),这些通道可以用来作为: 输入捕获输出比较PWM 生成(边缘或中间对齐模式)单脉冲模式输出 可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步电路如下事件发生时产生中断/DMA: 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)输入捕获输出比较支持针对定位的增量(正交)编码器和霍尔传感器电路触发输入作为外部时钟或者按周期的电流管理 1.3 STM32 基本定时器简介[5] STM32 基本定时器 1.2 何为捕捉PWM脉冲通过检测输入的PWM脉冲信号,获取该脉冲的占空比,频率等关键信息。 1.3 如何捕捉PWM脉冲首先通过STMPA7引脚输出PWM脉冲:STM32配置多个外部中断 通过检测引脚状态,控制相应计数器的开启与关闭来实现PWM脉冲高低电平的计数,再通过计数器的周期计算出相应PWM的高低电平时间,进而得到PWM的周期和占空比。 对于周期比较小的PWM脉冲,可以不适用计数器中断就可以实现脉冲时间的测量,但是由于计数器单次计数周期较大而导致最终测量结果误差较大。提高测量精度就需要降低单次计数周期,但是这样无法测量周期较大的PWM脉冲。此时就需要引入计数器中断来实现PWM脉冲时间的精准测量。 PWM脉冲测量代码案例: (没有使用计数器中断) /* * 检测高低电平时间,返回值单位是ms, * 函数参数flag = 0:低电平时间;flag= 1:高电平时间 */ float getH_L(u8 flag){ u8 i; float timecount[5]; for(i = 0;iCNT=0; //TIM3的计数器清零 if(flag){ while( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8) == 0); //打开定时器 TIM_Cmd(TIM4,ENABLE); while( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8) == 1); //关闭定时器 TIM_Cmd(TIM4,DISABLE); timecount[i] = TIM4->CNT * 0.001*0.125; } else{ while( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8) == 1); //打开定时器 TIM_Cmd(TIM4,ENABLE); while( GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8) == 0); //关闭定时器 TIM_Cmd(TIM4,DISABLE); timecount[i] = TIM4->CNT * 0.001*0.125;//此处0.125是根据TIM4的配置时钟来的 } } return (timecount[1]+timecount[2]+timecount[3]+timecount[4]+timecount[0])/5; } int main() { SysTick_Init(); USART1_Config(); SRF05_Config(); TIME2_Config(); TIME3_Config(); TIME4_Config(); GPIO_WriteBit(GPIOA,SRF05_Trig,Bit_RESET); while(1){ printf("high time = %f ms\r\n",getH_L(1)); printf("low time = %f ms\r\n",getH_L(0)); printf("PWM period = %f ms\r\n",getH_L(1)+getH_L(0)); printf("PWM Dutyfactor = %f \r\n",getH_L(1)/(getH_L(1)+getH_L(0))); } }PWM生成仿真: 低电平时间:0.889472ms HY-SRF05超声波传感器测距模块可提供2cm-450cm的非接触距离感测功能,测距精度可达到3mm;模块包括超声波发生器、接收器与控制电路。 引脚定义: 电气参数:
注意: 建议测量周期为 60ms以上, 以防止发射信号对回响信号的影响。此模块不宜带电连接, 若要带电连接, 则先让模块的 GND端先连接, 否则会影响模块的正常工作。测距时,被测物体的面积不少于 0.5平方米且平面尽量要求平整,否则影响测量的结果。最后结果要除以2超声波传感的供电电压要是5V才能正常工作,供电3.3V将不会工作,脾气倔 2.2 超声波传感器配置代码 float getdistance(void){ float SendBuff2 = 0,ans[Nnum]={0}; int timecount; u8 i; GPIO_WriteBit(GPIOA,SRF05_Trig,Bit_RESET); for(i = 0;i < Nnum;i++){ GPIO_WriteBit(GPIOA,SRF05_Trig,Bit_SET); delay_us(30); GPIO_WriteBit(GPIOA,SRF05_Trig,Bit_RESET); TIM2->CNT=0; //TIM3的计数器清零 while( GPIO_ReadInputDataBit(SRF05_PORT, SRF05_Echo) == 0); //打开定时器 TIM_Cmd(TIM2,ENABLE); while( GPIO_ReadInputDataBit(SRF05_PORT, SRF05_Echo) == 1); // //关闭定时器 TIM_Cmd(TIM2,DISABLE); timecount = TIM2->CNT; ans[i] = timecount*0.0001*344/2; delay_ms(100); } Sort_tab(ans,Nnum);//冒泡排序 /* 累加 N - Xnum 个 ADC 采样 */ for (i = Xnum/2; i < Nnum-Xnum/2; ++i) { SendBuff2 += ans[i]; } SendBuff2 /= Nnum - Xnum; return SendBuff2; } |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |