STM32F429如何使用定时器多路HC-SR04超声波输入捕获
发表于:2025-01-23 作者:千家信息网编辑
千家信息网最后更新 2025年01月23日,这篇文章主要介绍了STM32F429如何使用定时器多路HC-SR04超声波输入捕获,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。介绍S
千家信息网最后更新 2025年01月23日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安全错误
数据库的锁怎样保障安全
slor服务器
中国的电信网络技术
魔兽旧服务器出售
互联网科技园总部在哪里
杭州青鸾网络技术有限公司
阿里通话服务器拒绝
世界全明星网络安全大赛
饥荒服务器没人会暂停嘛
青岛世纪华鑫网络技术
数据库表字段值排序
2021乌镇互联网大会黑科技
查询两张表字段不同的数据库
电脑拨号设置服务器ip
服务器启动芯片故障现象
数据库难不难学
网络安全情报 反恐
2020-2021网络安全事件
嵌入式软件开发团队
数据库岗前培训班
教育软件开发利弊
个人数据库旁征博引
车联网络安全委员会
计算机网络技术课程介绍
软件开发的发展路线
50万并发服务器大吗
电脑拨号设置服务器ip
传真服务器cma检测报告
网络安全与执法专业全部课程
jdbc使用数据库
福田网络安全宣传