STM32F429如何使用定时器多路HC-SR04超声波输入捕获
发表于:2024-11-26 作者:千家信息网编辑
千家信息网最后更新 2024年11月26日,这篇文章主要介绍了STM32F429如何使用定时器多路HC-SR04超声波输入捕获,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。介绍S
千家信息网最后更新 2024年11月26日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安全错误
数据库的锁怎样保障安全
网络安全开展工作计划
中国名家数据库是个什么机构
浏览器连接服务器无法显示网页
大兴区网络技术质量推荐
网络技术助理
案件关于网络安全
网络安全年会广州
新乡市千翼网络技术有限公司
关于网络安全的议论文200字
网络安全集成书籍排行榜
h3c服务器网络不好使
技术机网络技术专科目前
服务器内存只有12g可用
阜阳通信软件开发公司
斗破苍穹的游戏不同服务器
网络安全板块股票代号
北京技术软件开发怎么样
管理服务器是啥
小微企业征信数据库
未来网络安全发展综述
哈尔滨网络安全工程师简历
傲游互联网科技公司
网络技术转本科学什么专业好
阿里关系型数据库
楚雄州网络安全培训
惠普675w服务器电源改装教程
盒马app服务器加载异常
删除数据库起死回生
螺旋跑酷塔服务器地址
jeesite数据库