完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
0、前言 有关STM32实现定时器输入捕获原理戳这里。 1、硬件设计 1.1、超声波模块 硬件设计采用CS102驱动的收发一体超声波探头作为传感器,产品型号为US-116,可实现 25.5cm-350cm 的非接触测距功能,通过计算可知输出脉冲宽度大约为1.5~206ms。 ▲ 超声波板原理图 以下文字及图片来源于CS102数据手册。工作原理:在 TRIG 管脚输入一个 10US 以上的高电平(一般建议 50US~100US),芯片(TP,TN管脚)便可发出 8 个 40KHZ的超声波脉冲,然后(RP,RN)检测回波信号。当检测到回波信号后,通过 ECHO 管脚输出,如下图所示: ▲ 测距时序图 根据 ECHO 管脚输出高电平的持续时间可以计算距离值。即距离值为:(高电平时间*340m/s)/2。 当测量距离超过测量范围时,CS102仍会通过 ECHO 管脚输出高电平的信号,高电平的宽度约为 33ms。如下图所示: ▲ 超出测量范围时序图 测量周期:当芯片通过ECHO 管脚输出的高电平脉冲后,便可进行下一次测量,所以测量周期取决于测量距离,当测距很近时,ECHO返回的脉冲宽度较窄,测量周期就很短;当测距较远时,ECHO返回的脉冲宽度较宽,测量周期也就相应的变长。 最坏情况下,被测物体超出测量范围,此时返回的脉冲宽度最长,约为 33ms,所以最坏情况下的测量周期稍大于 33ms 即可(取 40ms足够)。 ▲ US116主要威廉希尔官方网站 参数 上图指出了本次实验使用的超声波模块的威廉希尔官方网站 参数,值得注意的是探测距离为25.5-350cm,也就是说在该范围之外的超声波数据可以认为错误数据而舍去。 1.2、STM32L151 将PA6即TIM3_CH1用于输入捕获。PA7用以发送超声波触发信号。 ▲ STM32L151官方文档截图 2、CubeMX配置 ▲ CubeMX 输入捕获TIM配置图 为什么取32-1分频? 根据数据手册显示的数据来计算,高电平最高持续时间按40ms来计算则65536/(40/1000)=1,638,400Hz也就是说定时器的时钟频率要小于这个频率,留下一部分冗余取整可取1MHz,最小计时精度为1us,若按照标准声速340m/s计算测量误差在±0.34mm在接受范围内。 ▲ CubeMX 打开TIM3全局中断 ▲ CubeMX 设置输入捕获GPIO下拉 有一点疑问的是在CubeMX的默认设置中GPIO会被设置成复用推挽输出而手动将其更改为输入模式后将会导致捕获功能不可用。 ▲ CubeMX 配置超声波触发信号发送引脚 3、软件设计 实现us级延时 //实现简单的us级延时 void RCCdelay_us(uint32_t udelay) { __IO uint32_t Delay = udelay * 32 / 8;//(SystemCoreClock / 8U / 1000000U) do { __NOP(); } while (Delay --); } main.c ... int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART1_UART_Init(); MX_TIM3_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { if(CapValReady == 1) { //25.5cm-350cm USData = CapVal * 34000/1000000/2;//声速34000cm/s TIM3Freq:1000000Hz if(USData <= 350 && USData >= 25.5) { printf("US:%.2fcmrn",USData); } __HAL_TIM_DISABLE(&htim3); HAL_Delay(500); __HAL_TIM_SET_COUNTER(&htim3,0);//设置定时器3计数值为0 __HAL_TIM_ENABLE(&htim3); CapValReady = 0; USTrig(); HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);//定时器3通道1输入捕获使能 } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } tim.c /* USER CODE BEGIN 0 */ uint8_t CapIndex = 0; uint8_t CapValReady = 1; float USData = 0; uint16_t CapVal = 0; /* USER CODE END 0 */ ... /* USER CODE BEGIN 1 */ void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if(htim->Instance == TIM3) { if(CapIndex == 0) { CapIndex = 1; __HAL_TIM_SET_COUNTER(htim,0);//设置定时器3计数值为0 //清除原来的捕获极性 TIM_RESET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1); //定时器2通道1设置为下降沿捕获 TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING); } else { HAL_TIM_IC_Stop_IT(htim,TIM_CHANNEL_1);//关闭TIM2_CH1输入捕获 CapVal = __HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_1); CapValReady = 1; //清除原来的捕获极性 TIM_RESET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1); //定时器2通道1设置为上升沿捕获 TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING); CapIndex = 0; } } } /* USER CODE END 1 */ gpio.c ... /* USER CODE BEGIN 2 */ //实现简单的us级延时 void RCCdelay_us(uint32_t udelay) { __IO uint32_t Delay = udelay * 32 / 8;//(SystemCoreClock / 8U / 1000000U) do { __NOP(); } while (Delay --); } void USTrig() { HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_SET); RCCdelay_us(50); HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_RESET); } /* USER CODE END 2 */ 函数及宏定义介绍: __HAL_TIM_SET_COUNTER 说明: 设置运行时的TIM计数器寄存器值。 参数: __HANDLE__:TIM handle. __COUNTER__: 指定计数器寄存器新值。 __HAL_TIM_GET_COMPARE 说明: 获取运行时的TIM捕获比较寄存器值。 参数: __HANDLE__:TIM handle. __CHANNEL__: 与捕获比较寄存器相关联的TIM通道此参数可以是以下值之一: TIM_CHANNEL_1:获取捕获/比较1寄存器值 TIM_CHANNEL_2:获取捕获/比较2寄存器值 TIM_CHANNEL_3:获取捕获/比较3寄存器值 TIM_CHANNEL_4:获取捕获/比较4寄存器值 HAL_StatusTypeDef HAL_TIM_IC_Start_IT (TIM_HandleTypeDef * htim, uint32_t Channel) 说明: 在中断模式下启动TIM输入捕获测量。 参数: htim: 指向包含TIM模块配置信息的TIM_HandleTypeDef结构的指针。 Channel: 将启用TIM通道。 此参数可以是以下值之一: TIM_CHANNEL_1:选择TIM通道1 TIM_CHANNEL_2:选择TIM通道2 TIM_CHANNEL_3:选择TIM通道3 TIM_CHANNEL_4:选择TIM通道4 返回值:HAL status HAL_StatusTypeDef HAL_TIM_IC_Stop_IT (TIM_HandleTypeDef * htim, uint32_t Channel) 说明: 在中断模式下停止TIM输入捕获测量。 参数: htim: 指向包含TIM模块配置信息的TIM_HandleTypeDef结构的指针。 Channel: 将启用TIM通道。 此参数可以是以下值之一: TIM_CHANNEL_1:选择TIM通道1 TIM_CHANNEL_2:选择TIM通道2 TIM_CHANNEL_3:选择TIM通道3 TIM_CHANNEL_4:选择TIM通道4 返回值:HAL status ▲ 实现效果图 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1159 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1189 浏览 1 评论
607 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
454 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1107 浏览 2 评论
1655浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
319浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
319浏览 3评论
312浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
287浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-28 18:11 , Processed in 0.857385 second(s), Total 78, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号