赞
踩
- /* USER CODE BEGIN Header */
- /**
- ******************************************************************************
- * @file : main.c
- * @brief : Main program body
- ******************************************************************************
- * @attention
- *
- 此算法频率越低,占空比测量越精确
- 1kHz时,占空比测量可以精确到小数点后三位,如37.2%(第四位不稳定)
- 周期测量,可以精确到10ns之内,如1000ns(1k)-> 1007左右浮动
- 1Hz时,T = 1006290 ns,误差控制在1%之内,占空比测量准确
- 100Hz时,T = 10 ns,duty = 0.333333
- ******************************************************************************
- */
- /* USER CODE END Header */
- /* Includes ------------------------------------------------------------------*/
- #include "main.h"
- #include "adc.h"
- #include "dac.h"
- #include "dma.h"
- #include "tim.h"
- #include "usart.h"
- #include "gpio.h"
-
- /* Private includes ----------------------------------------------------------*/
- /* USER CODE BEGIN Includes */
- #include "stdio.h"
- #include <stdlib.h>
- #include "sys.h"
- #include "delay.h"
- #include "math.h"
- /* USER CODE END Includes */
-
- /* Private typedef -----------------------------------------------------------*/
- /* USER CODE BEGIN PTD */
-
- /*define定义*/
- #define FFT_LENGTH 1024 //FFT长度,默认是1024点FFT
- #define SAMPLE_LENGTH 1024 //采样点数
- #define max_number 0xffffffff
- #define over_flow 0x3
- #define k 1000
-
-
- volatile uint8_t g_adc_dma_sta = 0;
- volatile uint8_t flg = 0; //0为未开始,1已经开始,2为结束
- volatile uint32_t capture_Buf_timer2[3] = {0}; //存放计数值
- volatile uint32_t num_period = 0; //溢出次数
- uint32_t high_time_timer2; //高电平时间
- uint32_t whole_time_timer2; //高电平时间
-
- uint32_t capture_Buf[3] = {0}; //存放计数值
- uint8_t capture_Cnt = 0; //状态标志位
- uint32_t high_time; //高电平时间
-
- //float fft_amp_buf[FFT_LENGTH]; //幅度输出数组
- //float fft_phase_buf[FFT_LENGTH]; //相位输出数组
- // Complex data[FFT_LENGTH];
-
- //float fft_inputbuf[FFT_LENGTH*2]; //FFT输入输出数组,此数组为arm_cfft_radix4_f32的输入输出数组,前一个元素为实部,后一个为虚部,每两个元素代表一个点.
- //float fft_outputbuf[FFT_LENGTH]; //arm_cmplx_mag_f32()幅度输出数组
- uint16_t ADC1_Value[SAMPLE_LENGTH];
- float voltage[SAMPLE_LENGTH];
- /* USER CODE END PTD */
-
- /* Private define ------------------------------------------------------------*/
- /* USER CODE BEGIN PD */
- int fputc(int ch, FILE *f)
- {
- while ((USART1->SR & 0X40) == 0); /* 等待上一个字符发送完成 */
-
- USART1->DR = (uint8_t)ch; /* 将要发送的字符 ch 写入到DR寄存器 */
- return ch;
- }
- int fgetc(FILE *f)
- {
- uint8_t ch = 0;
- HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
- return ch;
- }
- /* USER CODE END PD */
-
- /* Private macro -------------------------------------------------------------*/
- /* USER CODE BEGIN PM */
- /* USER CODE BEGIN 0 */
- uint8_t RxBuff[1]; //进入中断接收数据的数组
- uint8_t DataBuff[10]; //保存接收到的数据的数组
- int RxLine=0; //接收到的数据长度
-
- float frequency;
- /* USER CODE END 0 */
-
- /*测频测周变量定义*/
-
-
- /*相位变量定义*/
- uint32_t capture_period=0,capture_sta=0,capture_period1=0,capture_sta1=0;
- float Phase=0,capture_period2=0;
-
- /* 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 */
-
- /* 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_DMA_Init();
- MX_USART1_UART_Init();
- MX_TIM3_Init();
- MX_DAC_Init();
- MX_ADC1_Init();
- MX_TIM2_Init();
- MX_TIM4_Init();
- /* USER CODE BEGIN 2 */
- HAL_UART_Receive_IT(&huart1, (uint8_t *)RxBuff, 1);
-
-
- /* USER CODE END 2 */
-
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
-
-
-
- //测量方波的频率和相位差
- switch (flg){
- case 0:
- flg = 1;
- __HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING);
- HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2); //启动输入捕获 或者: __HAL_TIM_ENABLE(&htim2);
- __HAL_TIM_ENABLE_IT(&htim2,TIM_IT_UPDATE); //使能更新中断
- break;
- case 3:
- high_time_timer2 = num_period*max_number+(capture_Buf_timer2[1]- capture_Buf_timer2[0]); //高电平时间
- break;
- case 4:
- whole_time_timer2 = num_period*max_number+(capture_Buf_timer2[2]- capture_Buf_timer2[0]); //总时间
-
- printf("T = %d ns\r\n",whole_time_timer2/3);
- printf("duty = %.3f \r\n",high_time_timer2*1.0/whole_time_timer2*1.0);
-
- flg = 0;
- num_period = 0;
- high_time_timer2 = 0;
- whole_time_timer2 = 0;
-
- break;
-
- }
-
-
- /* USER CODE END 2 */
-
-
- /* USER CODE END WHILE */
-
- /* USER CODE BEGIN 3 */
-
-
- }
- /* 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 RCC Oscillators according to the specified parameters
- * in the RCC_OscInitTypeDef structure.
- */
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
- RCC_OscInitStruct.HSIState = RCC_HSI_ON;
- RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
- RCC_OscInitStruct.PLL.PLLM = 8;
- RCC_OscInitStruct.PLL.PLLN = 168;
- 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 buses 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 */
- /* USER CODE BEGIN 4 */
-
- /*
- 代码分析
- __HAL_TIM_SET_CAPTUREPOLARITY包含了TIM_RESET_CAPTUREPOLARITY(重置)和TIM_SET_CAPTUREPOLARITY(设置极性)操作
- __HAL_TIM_DISABLE(&htim3);
- TIM_RESET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_1); //一定要先清除原来的设置!!
- TIM_SET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);//配置TIM5通道1上升沿捕获
- __HAL_TIM_ENABLE(&htim3);//使能定时器5
-
- 或者
-
- __HAL_TIM_DISABLE(&htim3);
- __HAL_TIM_SET_CAPTUREPOLARITY(&htim3, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
- __HAL_TIM_ENABLE(&htim3);//使能定时器5
- */
-
- /* USER CODE BEGIN 1 */
-
-
- //定时器更新中断(计数溢出)中断处理回调函数, 该函数在HAL_TIM_IRQHandler中会被调用
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
- {
- if(htim->Instance == TIM2){
- //每次溢出时间为65536us
- if(flg==1)//还未成功捕获
- {
- if((num_period&0X3F)==0X3F)//电平太长了
- {
- flg=4; //标记成功捕获了一次
- }else num_period ++;
- }
- }
- }
-
-
-
- //定时器输入捕获中断处理回调函数,该函数在HAL_TIM_IRQHandler中会被调用
- void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//捕获中断发生时执行
- {
-
- if(htim->Instance == TIM2)//PB3
- {
- switch (flg){
-
- case 1:
- capture_Buf_timer2[0] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);//获取当前的捕获值.
- __HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_2,TIM_ICPOLARITY_FALLING); //设置为下降沿捕获
- flg = 2;
- break;
- case 2:
- capture_Buf_timer2[1] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);//获取当前的捕获值.
- __HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING);
- flg = 3;
- break;
- case 3:
- capture_Buf_timer2[2] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);//获取当前的捕获值.
- HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_2); //停止捕获 或者: __HAL_TIM_DISABLE(&htim2);
- flg = 4;
- break;
- }
-
- }
- }
-
- void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
- {
- g_adc_dma_sta = 1;
- };
- /* USER CODE END 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 */
- __disable_irq();
- while (1)
- {
- }
- /* 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,
- ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
- /* USER CODE END 6 */
- }
- #endif /* USE_FULL_ASSERT */
- 部分代码分析
- __HAL_TIM_SET_CAPTUREPOLARITY包含了
- TIM_RESET_CAPTUREPOLARITY(重置)和TIM_SET_CAPTUREPOLARITY(设置极性)操作
- __HAL_TIM_DISABLE(&htim3);//关闭定时器3
- TIM_RESET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_1); //清除原来的设置
- TIM_SET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);//配置TIM3通道1上升沿捕获
- __HAL_TIM_ENABLE(&htim3);//使能定时器5
-
- 或者使用下面代码
-
- __HAL_TIM_DISABLE(&htim3);
- __HAL_TIM_SET_CAPTUREPOLARITY(&htim3, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
- __HAL_TIM_ENABLE(&htim3);//使能定时器3
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。