您好,登錄后才能下訂單哦!
這篇文章主要介紹了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) { //GPIO3?ê??ˉ 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超聲波輸入捕獲”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。