STM32Cube配置等精度测频和测相位差
生活随笔
收集整理的這篇文章主要介紹了
STM32Cube配置等精度测频和测相位差
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
標題STM32Cube配置等精度測頻和測相位差
一、測量精度:
1、頻率精度
頻率測量、周期測量的信號頻率范圍擴展為1Hz~20MHz(這里由于信號發生器最高產生20MHz頻率,所以更高頻率未嘗試,預計更高可達到50MHz),頻率測量、周期測量的測量誤差為0.000001.
2、相位差精度
相位差測量,可以達到量程:0~360°;測量準確度:1°;分辨率:0.1°的題目要求
二、項目配置
1、時鐘配置
stm32F429最高主頻為168MHz
配置時鐘源
2、定時器配置
3、生成工程配置
3、串口配置
配置兩個串口,一個收一個發,防止數據傳輸時大彩屏卡死;
三、Keil5編寫代碼
1、main函數代碼
/* USER CODE BEGIN Header */ /********************************************************************************* @file : main.c* @brief : Main program body******************************************************************************* @attention** <h2><center>© Copyright (c) 2019 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under BSD 3-Clause license,* the "License"; You may not use this file except in compliance with the* License. You may obtain a copy of the License at:* opensource.org/licenses/BSD-3-Clause********************************************************************************/ /* USER CODE END Header *//* Includes ------------------------------------------------------------------*/ #include "main.h" #include "tim.h" #include "usart.h" #include "gpio.h"/* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "base.h" //包含基本按鍵、燈、位帶操作等 #include "stdio.h" #include "head_define.h" #include "Algorithm.h" #include "arm_math.h" #include "hmi_user_uart.h" #include "cmd_process.h" #include "outputdata.h" /* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ #define Period_Num 1 /* USER CODE END PTD *//* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 *//*測頻測周變量定義*/ uint8_t TIM4CH1_CAPTURE_STA=0X80; //輸入捕獲狀態 uint32_t TIM5_COUNTER_VAL[Period_Num]; //定時器1計數組,測系統時鐘 uint32_t TIM2_COUNTER_VAL[Period_Num]; //定時器2計數組,被測信號周期 float TIM5_COUNTER_Val; //定時器1計數值,測系統時鐘 float TIM2_COUNTER_Val; //定時器2計數值,被測信號周期 float TIM_FREQ; //頻率值 float TIM_period; //周期值 uint8_t TIM4CH1_CAPTURE_GATE=0; //預設閘門標志位 uint8_t TIM4CH1_CAPTURE_STB=0; //數組存滿標志位 static uint8_t i,j=0; //數組用 uint32_t TIM5_COUNTER_TEMP; //定時器1計數濾波 uint32_t TIM2_COUNTER_TEMP; //定時器2計數濾波 float TIM_FREQ2; float TIM_FREQ3; float TIM_FERQ[5];/*相位變量定義*/ uint32_t capture_period=0,capture_sta=0,capture_period1=0,capture_sta1=0; float Phase=0,capture_period2=0; //校準后的頻率 /* USER CODE END 0 *//*** @brief The application entry point.* @retval int*/ 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_TIM1_Init();MX_TIM2_Init();MX_TIM3_Init();MX_TIM4_Init();MX_TIM5_Init();MX_USART1_UART_Init();MX_USART2_UART_Init();MX_TIM8_Init();MX_TIM9_Init();MX_TIM12_Init();/* USER CODE BEGIN 2 */TFT_Init(); HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4); //使能PWM波HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3); //使能PWM波 HAL_TIM_IC_Start_IT(&htim4,TIM_CHANNEL_1); //使能TIM4輸入捕獲中斷__HAL_TIM_ENABLE_IT(&htim4, TIM_CHANNEL_1); //使能更新中斷HAL_TIM_Base_Start_IT(&htim1); //使能TIM5定時器中斷HAL_TIM_IC_Start_IT(&htim9,TIM_CHANNEL_1);HAL_TIM_IC_Start_IT(&htim12,TIM_CHANNEL_1); // HAL_TIM_Base_Start_IT(&htim1);//使能定時器1中斷__HAL_TIM_SET_COUNTER(&htim5,0); //定時器1清零__HAL_TIM_SET_COUNTER(&htim2,0); //定時器2清零 TIM4CH1_CAPTURE_GATE = 1; //開啟預設閘門/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */capture_period2=capture_period/2.0;Phase=((capture_period1-capture_period2)/capture_period1)*360.0+21;SetTFTText(0,3,"%.1f度",Phase);SetTFTText(0,5,"%.2f",10.2);HAL_Delay(100);if(TIM4CH1_CAPTURE_STB)//判斷數組是否存滿{ TIM5_COUNTER_Val = (float) TIM5_COUNTER_TEMP / Period_Num; //定時器1計數濾波(100個數組求平均)TIM2_COUNTER_Val = (float) TIM2_COUNTER_TEMP / Period_Num; //定時器2計數濾波 (100個數組求平均) TIM_FREQ = 1000.0*(TIM2_COUNTER_Val*3000.0)/TIM5_COUNTER_Val; //定時器2計數值*定時器1頻率/定時器1計數值if(TIM_FREQ<=300){TIM_FREQ2=TIM_FREQ*1.00020;TIM_period=1.0/TIM_FREQ2;SetTFTText(0,1,"%.6fHz",TIM_FREQ2);SetTFTText(0,2,"%.6fs",TIM_period);}else{TIM_FREQ2=TIM_FREQ*0.9999480027038594;TIM_period=1.0/TIM_FREQ2;SetTFTText(0,1,"%.6fMHz",TIM_FREQ2/1000000.0);SetTFTText(0,2,"%.6fus",TIM_period*1000000.0);}TIM5_COUNTER_TEMP = 0; //定時器5計數值清零TIM2_COUNTER_TEMP = 0; //定時器2計數值清零TIM4CH1_CAPTURE_STB = 0; //數組存滿標志位TIM4CH1_CAPTURE_STA |= 0X80; //輸入捕獲狀態HAL_TIM_IC_Start_IT(&htim4,TIM_CHANNEL_1);//使能TIM4輸入捕獲中斷} }/* USER CODE END 3 */ }/*** @brief System Clock Configuration* @retval None*/ void SystemClock_Config(void) {RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Configure the main internal regulator output voltage */__HAL_RCC_PWR_CLK_ENABLE();__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);/** Initializes the CPU, AHB and APB busses clocks */RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = 25;RCC_OscInitStruct.PLL.PLLN = 336;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ = 4;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB busses clocks */RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK){Error_Handler();} }/* USER CODE BEGIN 4 */ //定時器TIM4輸入捕獲中斷處理回調函數,該函數在HAL_TIM_IRQHandler中會被調用 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//捕獲中斷發生時執行 { //***********************************************************************//測頻率if(TIM4CH1_CAPTURE_GATE==0){ if(TIM4CH1_CAPTURE_STA&0X40) //閘門關閉后第二次捕獲到一個上升沿 { TIM4CH1_CAPTURE_STA = 0X80; //標記成功捕獲到閘門的一次高電平脈寬TIM5_COUNTER_VAL[i] = __HAL_TIM_GET_COUNTER(&htim5); //獲取定時器1計數值TIM2_COUNTER_VAL[i] = __HAL_TIM_GET_COUNTER(&htim2); //獲取定時器2計數值TIM5_COUNTER_TEMP += TIM5_COUNTER_VAL[i];TIM2_COUNTER_TEMP += TIM2_COUNTER_VAL[i];i++;if(i == Period_Num)//100個閘門周期{ i = 0;TIM4CH1_CAPTURE_STB = 1;//數組存滿標志位TIM4CH1_CAPTURE_STA = 0;//標記捕獲到了上升沿狀態位清零HAL_TIM_IC_Stop_IT(&htim4,TIM_CHANNEL_1); //關閉輸入捕獲} HAL_TIM_Base_Stop(&htim5); //關閉定時器5HAL_TIM_Base_Stop(&htim2); //關閉定時器2 __HAL_TIM_SET_COUNTER(&htim5,0); //定時器5清零__HAL_TIM_SET_COUNTER(&htim2,0); //定時器2清零 }}if(TIM4CH1_CAPTURE_GATE==1){if(TIM4CH1_CAPTURE_STA&0X80)//第一次捕獲上升沿{TIM4CH1_CAPTURE_STA = 0X40; //標記捕獲到了上升沿開始計數HAL_TIM_Base_Start(&htim5); //使能定時器1,對標準信號一直計數HAL_TIM_Base_Start(&htim2); //使能定時器2,對被測信號一直計數}} ***********************************************************************//測相位 if(htim->Instance==TIM9){if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1){if(!capture_sta){__HAL_TIM_SET_COUNTER(&htim9,0);}} }if(htim->Instance==TIM12){if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1){HAL_TIM_IC_Stop_IT(&htim9,TIM_CHANNEL_1);capture_period=__HAL_TIM_GET_COMPARE(&htim9,TIM_CHANNEL_1); if(!capture_sta1){ __HAL_TIM_SET_COUNTER(&htim12,0); capture_sta1=1; }else{HAL_TIM_IC_Start_IT(&htim9,TIM_CHANNEL_1);__HAL_TIM_SET_COUNTER(&htim9,0);capture_period1=__HAL_TIM_GET_COMPARE(&htim12,TIM_CHANNEL_1); capture_sta1=0;}}} }//定時器TIM5溢出中斷處理回調函數 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {if(TIM1 == htim->Instance){ PCout(9)=~PCout(9);if(TIM4CH1_CAPTURE_GATE){TIM4CH1_CAPTURE_GATE = 0;}else {TIM4CH1_CAPTURE_GATE = 1;}}} /* USER CODE END 4 *//*** @brief This function is executed in case of error occurrence.* @retval None*/ void Error_Handler(void) {/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state *//* USER CODE END Error_Handler_Debug */ }#ifdef USE_FULL_ASSERT /*** @brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* @param file: pointer to the source file name* @param line: assert_param error line source number* @retval None*/ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/2、大彩屏
3、項目接線連接
需要將Time3的CH3連接到Time4中,否則無法測量。
4、項目工程代碼
如需項目工程代碼,請關注公眾號:漂流小江,在公眾號中即可獲取代碼
總結
以上是生活随笔為你收集整理的STM32Cube配置等精度测频和测相位差的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何创建mysql分区表_mysql分区
- 下一篇: MySQL中LOCATE()函数的详解