STM32F429如何使用定时器多路HC-SR04超声波输入捕获
发表于:2025-12-01 作者:千家信息网编辑
千家信息网最后更新 2025年12月01日,这篇文章主要介绍了STM32F429如何使用定时器多路HC-SR04超声波输入捕获,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。介绍S
千家信息网最后更新 2025年12月01日STM32F429如何使用定时器多路HC-SR04超声波输入捕获
这篇文章主要介绍了STM32F429如何使用定时器多路HC-SR04超声波输入捕获,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
介绍
STMF429IGT开发板,通过定时器2接入2路超声波模块。使用Timer2的输入捕获功能来实现。超声波模块使用HC-SR04模组。
关于hc-sr04的工作原理这里不再介绍,请自行百度。废话不多说,直接上代码:
Timer2 GPIO配置代码:
TIM_HandleTypeDef TIM2_Handler; //定时器2句柄//timer2 gpio配置void Timer2_Cap_Init(u32 arr,u16 psc){ //GPIO³õʼ»¯ GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_TIM2_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /**TIM2 GPIO Configuration PA5 ------> TIM2_CH1 PB3 ------> TIM2_CH2 */ GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLDOWN; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLDOWN; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF1_TIM2; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* TIM2 interrupt Init */ HAL_NVIC_SetPriority(TIM2_IRQn, 2, 0); HAL_NVIC_EnableIRQ(TIM2_IRQn); //TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_IC_InitTypeDef sConfigIC = {0}; TIM2_Handler.Instance = TIM2; TIM2_Handler.Init.Prescaler = psc; TIM2_Handler.Init.CounterMode = TIM_COUNTERMODE_UP; TIM2_Handler.Init.Period = arr; TIM2_Handler.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //下面几句不能开启,开启后输入捕获异常 //HAL_TIM_Base_Init(&TIM2_Handler); //sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; //HAL_TIM_ConfigClockSource(&TIM2_Handler, &sClockSourceConfig); if (HAL_TIM_IC_Init(&TIM2_Handler) != HAL_OK) { //Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&TIM2_Handler, &sMasterConfig) != HAL_OK) { //Error_Handler(); } sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; //配置为上升沿检测 sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; sConfigIC.ICFilter = 0; //配置ch2 if (HAL_TIM_IC_ConfigChannel(&TIM2_Handler, &sConfigIC, TIM_CHANNEL_1) != HAL_OK) { //Error_Handler(); } //配置ch3 if (HAL_TIM_IC_ConfigChannel(&TIM2_Handler, &sConfigIC, TIM_CHANNEL_2) != HAL_OK) { //Error_Handler(); } HAL_TIM_IC_Start_IT(&TIM2_Handler,TIM_CHANNEL_2); //开启ch3输入捕获 HAL_TIM_IC_Start_IT(&TIM2_Handler,TIM_CHANNEL_1); //开启ch2输入捕获 __HAL_TIM_ENABLE_IT(&TIM2_Handler,TIM_IT_UPDATE); //使能更新中断}输入捕获数值的获取:
//TIM2CHx_CAPTURE_STA记录捕获状态//[7]:0,没有捕获 1,成功捕获//[6]:0,还没捕获到低电平 1.捕获到低电平//[5:0]:捕获低电平溢出次数u8 TIM2CH1_CAPTURE_STA=0; //输入捕获状态 u32 TIM2CH1_CAPTURE_VAL; //输入捕获值(TIM2/TIM5是32位)u32 TIM2CH1_count = 0;u8 TIM2CH2_CAPTURE_STA=0; //输入捕获状态 u32 TIM2CH2_CAPTURE_VAL; //输入捕获值(TIM2/TIM5是32位)u32 TIM2CH2_count = 0;//timer2中断服务程序void TIM2_IRQHandler(void){ HAL_TIM_IRQHandler(&TIM2_Handler);} //定时器更新中断处理回调函数,该函数在HAL_TIM_IRQHandler()中被调用void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//更新中断发生时执行{ if(htim->Instance ==TIM2) { if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) { if((TIM2CH1_CAPTURE_STA&0X80)==0)//还未成功捕获 { if(TIM2CH1_CAPTURE_STA&0X40)//捕获到一次高电平 { if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长,导致溢出了 { TIM2CH1_CAPTURE_STA|=0X80; //标记完成一次捕获 TIM2CH1_CAPTURE_VAL=0XFFFFFFFF; } else { TIM2CH1_CAPTURE_STA++; } } } } else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) { if((TIM2CH2_CAPTURE_STA&0X80)==0) { if(TIM2CH2_CAPTURE_STA&0X40) { if((TIM2CH2_CAPTURE_STA&0X3F)==0X3F) { TIM2CH2_CAPTURE_STA|=0X80; TIM2CH2_CAPTURE_VAL=0XFFFFFFFF; } else { TIM2CH2_CAPTURE_STA++; } } } } }}//定时器输入捕获回调函数,会在HAL_TIM_IRQHandler()中被调用void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//捕获中断发生时执行{ if(htim->Instance ==TIM2) { if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) { //printf("TIM_CHANNEL_1\n"); if((TIM2CH1_CAPTURE_STA&0X80)==0)//还未成功捕获 { if(TIM2CH1_CAPTURE_STA&0X40) //捕获到一个下降沿 { TIM2CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽 TIM2CH1_CAPTURE_VAL=HAL_TIM_ReadCapturedValue(&TIM2_Handler,TIM_CHANNEL_1) - TIM2CH1_count;//获取当前捕获值 TIM_RESET_CAPTUREPOLARITY(&TIM2_Handler,TIM_CHANNEL_1); //清除原配置 //配置上升沿捕获 TIM_SET_CAPTUREPOLARITY(&TIM2_Handler,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING); } else //还未开始捕获,第一次捕获到上升沿 { TIM2CH1_CAPTURE_STA=0; //清零 TIM2CH1_CAPTURE_VAL=0; TIM2CH1_count = 0; TIM2CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿 //记录第一次捕获值 TIM2CH1_count = HAL_TIM_ReadCapturedValue(&TIM2_Handler,TIM_CHANNEL_1); TIM_RESET_CAPTUREPOLARITY(&TIM2_Handler,TIM_CHANNEL_1); //清除原配置 //设置为下降沿捕获 TIM_SET_CAPTUREPOLARITY(&TIM2_Handler,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);// } } } else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) { //printf("TIM_CHANNEL_2\n"); if((TIM2CH2_CAPTURE_STA&0X80)==0) { if(TIM2CH2_CAPTURE_STA&0X40) { TIM2CH2_CAPTURE_STA|=0X80; TIM2CH2_CAPTURE_VAL=HAL_TIM_ReadCapturedValue(&TIM2_Handler,TIM_CHANNEL_2)- TIM2CH2_count; TIM_RESET_CAPTUREPOLARITY(&TIM2_Handler,TIM_CHANNEL_2); TIM_SET_CAPTUREPOLARITY(&TIM2_Handler,TIM_CHANNEL_2,TIM_ICPOLARITY_RISING);// } else { TIM2CH2_CAPTURE_STA=0; TIM2CH2_CAPTURE_VAL=0; TIM2CH2_count = 0; TIM2CH2_CAPTURE_STA|=0X40; TIM2CH2_count = HAL_TIM_ReadCapturedValue(&TIM2_Handler,TIM_CHANNEL_2); TIM_RESET_CAPTUREPOLARITY(&TIM2_Handler,TIM_CHANNEL_2); TIM_SET_CAPTUREPOLARITY(&TIM2_Handler,TIM_CHANNEL_2,TIM_ICPOLARITY_FALLING);// } } } }}HC_sr04 trig信号触发,gpio配置,使用PC0来做触发引脚:
//使用PC0触发信号void FFIntell_hcsr04_trig_gpio_init(void){ GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); /*Configure GPIO pin : PC0 */ GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET);}调用,在初始化timer2 gpio初始化后,发送trig信号后,直接获取数据即可
//发送trig信号void FFIntell_hcsr04_trig(){ __HAL_TIM_ENABLE(&TIM2_Handler);//使能定时器 PCout(0) = 1; delay_us(20); //20us延时 PCout(0) = 0;}//获取距离数据int FFIntell_hcsr04_get_data(void){ //ch2获取到了数据 if(TIM2CH1_CAPTURE_STA&0X80) { dist_info.ch2_distance = TIM2CH1_CAPTURE_VAL *0.058; //计算距离 TIM2CH1_CAPTURE_STA=0; //清状态 } if(TIM2CH2_CAPTURE_STA&0X80) { dist_info.ch3_distance = TIM2CH2_CAPTURE_VAL*0.058; TIM2CH2_CAPTURE_STA=0; } __HAL_TIM_DISABLE(&TIM2_Handler); //关闭定时器 __HAL_TIM_SET_COUNTER(&TIM2_Handler, 0); //计数清零 return 0;}通过上述配置可以很方便的扩展到4路输入捕获。
感谢你能够认真阅读完这篇文章,希望小编分享的"STM32F429如何使用定时器多路HC-SR04超声波输入捕获"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!
输入
定时器
配置
电平
超声
超声波
成功
信号
状态
篇文章
函数
数据
标记
更新
多路
代码
原配
模块
第一次
生时
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
这个网络安全是学什么
好玩网络技术有限公司
什么叫ladp服务器
小程序给数据库添加数据
论文企业的网络安全问题
夸克web服务器拒绝了连接
数据库 全局变量
瑞达网络安全
惠普服务器内存条维保期查询
自购服务器怎样搭建
淮安南京服务器规格
海南网络安全培训中心
网络安全存储服务器机箱生产
wordpress 数据库设计
交通银行软件开发笔试真题
内网同步数据库
app服务器要分开吗
数据库管理系统的特性
我的世界东京食种服务器
笨马网络技术销售工程师
亦辉网络技术有限公司
重启软件开发
怎么实现多服务器登录
个人用云服务器做什么
照片排版软件开发
北京数据软件开发服务以客为尊
数据库基础及应用书答案
联发科5g射频软件开发配置
网络安全周直播入口郑州
视频图片数据库的制作c