当前位置:   article > 正文

STM32F407定时器实现方波频率占空比测量_基于stm32f407的频率计

基于stm32f407的频率计

参考代码

  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : main.c
  5. * @brief : Main program body
  6. ******************************************************************************
  7. * @attention
  8. *
  9. 此算法频率越低,占空比测量越精确
  10. 1kHz时,占空比测量可以精确到小数点后三位,如37.2%(第四位不稳定)
  11. 周期测量,可以精确到10ns之内,如1000ns(1k)-> 1007左右浮动
  12. 1Hz时,T = 1006290 ns,误差控制在1%之内,占空比测量准确
  13. 100Hz时,T = 10 ns,duty = 0.333333
  14. ******************************************************************************
  15. */
  16. /* USER CODE END Header */
  17. /* Includes ------------------------------------------------------------------*/
  18. #include "main.h"
  19. #include "adc.h"
  20. #include "dac.h"
  21. #include "dma.h"
  22. #include "tim.h"
  23. #include "usart.h"
  24. #include "gpio.h"
  25. /* Private includes ----------------------------------------------------------*/
  26. /* USER CODE BEGIN Includes */
  27. #include "stdio.h"
  28. #include <stdlib.h>
  29. #include "sys.h"
  30. #include "delay.h"
  31. #include "math.h"
  32. /* USER CODE END Includes */
  33. /* Private typedef -----------------------------------------------------------*/
  34. /* USER CODE BEGIN PTD */
  35. /*define定义*/
  36. #define FFT_LENGTH 1024 //FFT长度,默认是1024点FFT
  37. #define SAMPLE_LENGTH 1024 //采样点数
  38. #define max_number 0xffffffff
  39. #define over_flow 0x3
  40. #define k 1000
  41. volatile uint8_t g_adc_dma_sta = 0;
  42. volatile uint8_t flg = 0; //0为未开始,1已经开始,2为结束
  43. volatile uint32_t capture_Buf_timer2[3] = {0}; //存放计数值
  44. volatile uint32_t num_period = 0; //溢出次数
  45. uint32_t high_time_timer2; //高电平时间
  46. uint32_t whole_time_timer2; //高电平时间
  47. uint32_t capture_Buf[3] = {0}; //存放计数值
  48. uint8_t capture_Cnt = 0; //状态标志位
  49. uint32_t high_time; //高电平时间
  50. //float fft_amp_buf[FFT_LENGTH]; //幅度输出数组
  51. //float fft_phase_buf[FFT_LENGTH]; //相位输出数组
  52. // Complex data[FFT_LENGTH];
  53. //float fft_inputbuf[FFT_LENGTH*2]; //FFT输入输出数组,此数组为arm_cfft_radix4_f32的输入输出数组,前一个元素为实部,后一个为虚部,每两个元素代表一个点.
  54. //float fft_outputbuf[FFT_LENGTH]; //arm_cmplx_mag_f32()幅度输出数组
  55. uint16_t ADC1_Value[SAMPLE_LENGTH];
  56. float voltage[SAMPLE_LENGTH];
  57. /* USER CODE END PTD */
  58. /* Private define ------------------------------------------------------------*/
  59. /* USER CODE BEGIN PD */
  60. int fputc(int ch, FILE *f)
  61. {
  62. while ((USART1->SR & 0X40) == 0); /* 等待上一个字符发送完成 */
  63. USART1->DR = (uint8_t)ch; /* 将要发送的字符 ch 写入到DR寄存器 */
  64. return ch;
  65. }
  66. int fgetc(FILE *f)
  67. {
  68. uint8_t ch = 0;
  69. HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  70. return ch;
  71. }
  72. /* USER CODE END PD */
  73. /* Private macro -------------------------------------------------------------*/
  74. /* USER CODE BEGIN PM */
  75. /* USER CODE BEGIN 0 */
  76. uint8_t RxBuff[1]; //进入中断接收数据的数组
  77. uint8_t DataBuff[10]; //保存接收到的数据的数组
  78. int RxLine=0; //接收到的数据长度
  79. float frequency;
  80. /* USER CODE END 0 */
  81. /*测频测周变量定义*/
  82. /*相位变量定义*/
  83. uint32_t capture_period=0,capture_sta=0,capture_period1=0,capture_sta1=0;
  84. float Phase=0,capture_period2=0;
  85. /* USER CODE END PM */
  86. /* Private variables ---------------------------------------------------------*/
  87. /* USER CODE BEGIN PV */
  88. /* USER CODE END PV */
  89. /* Private function prototypes -----------------------------------------------*/
  90. void SystemClock_Config(void);
  91. /* USER CODE BEGIN PFP */
  92. /* USER CODE END PFP */
  93. /* Private user code ---------------------------------------------------------*/
  94. /* USER CODE BEGIN 0 */
  95. /* USER CODE END 0 */
  96. /**
  97. * @brief The application entry point.
  98. * @retval int
  99. */
  100. int main(void)
  101. {
  102. /* USER CODE BEGIN 1 */
  103. /* USER CODE END 1 */
  104. /* MCU Configuration--------------------------------------------------------*/
  105. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  106. HAL_Init();
  107. /* USER CODE BEGIN Init */
  108. /* USER CODE END Init */
  109. /* Configure the system clock */
  110. SystemClock_Config();
  111. /* USER CODE BEGIN SysInit */
  112. /* USER CODE END SysInit */
  113. /* Initialize all configured peripherals */
  114. MX_GPIO_Init();
  115. MX_DMA_Init();
  116. MX_USART1_UART_Init();
  117. MX_TIM3_Init();
  118. MX_DAC_Init();
  119. MX_ADC1_Init();
  120. MX_TIM2_Init();
  121. MX_TIM4_Init();
  122. /* USER CODE BEGIN 2 */
  123. HAL_UART_Receive_IT(&huart1, (uint8_t *)RxBuff, 1);
  124. /* USER CODE END 2 */
  125. /* Infinite loop */
  126. /* USER CODE BEGIN WHILE */
  127. while (1)
  128. {
  129. //测量方波的频率和相位差
  130. switch (flg){
  131. case 0:
  132. flg = 1;
  133. __HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING);
  134. HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2); //启动输入捕获 或者: __HAL_TIM_ENABLE(&htim2);
  135. __HAL_TIM_ENABLE_IT(&htim2,TIM_IT_UPDATE); //使能更新中断
  136. break;
  137. case 3:
  138. high_time_timer2 = num_period*max_number+(capture_Buf_timer2[1]- capture_Buf_timer2[0]); //高电平时间
  139. break;
  140. case 4:
  141. whole_time_timer2 = num_period*max_number+(capture_Buf_timer2[2]- capture_Buf_timer2[0]); //总时间
  142. printf("T = %d ns\r\n",whole_time_timer2/3);
  143. printf("duty = %.3f \r\n",high_time_timer2*1.0/whole_time_timer2*1.0);
  144. flg = 0;
  145. num_period = 0;
  146. high_time_timer2 = 0;
  147. whole_time_timer2 = 0;
  148. break;
  149. }
  150. /* USER CODE END 2 */
  151. /* USER CODE END WHILE */
  152. /* USER CODE BEGIN 3 */
  153. }
  154. /* USER CODE END 3 */
  155. }
  156. /**
  157. * @brief System Clock Configuration
  158. * @retval None
  159. */
  160. void SystemClock_Config(void)
  161. {
  162. RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  163. RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  164. /** Configure the main internal regulator output voltage
  165. */
  166. __HAL_RCC_PWR_CLK_ENABLE();
  167. __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  168. /** Initializes the RCC Oscillators according to the specified parameters
  169. * in the RCC_OscInitTypeDef structure.
  170. */
  171. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  172. RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  173. RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  174. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  175. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  176. RCC_OscInitStruct.PLL.PLLM = 8;
  177. RCC_OscInitStruct.PLL.PLLN = 168;
  178. RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  179. RCC_OscInitStruct.PLL.PLLQ = 4;
  180. if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  181. {
  182. Error_Handler();
  183. }
  184. /** Initializes the CPU, AHB and APB buses clocks
  185. */
  186. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  187. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  188. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  189. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  190. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  191. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  192. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  193. {
  194. Error_Handler();
  195. }
  196. }
  197. /* USER CODE BEGIN 4 */
  198. /* USER CODE BEGIN 4 */
  199. /*
  200. 代码分析
  201. __HAL_TIM_SET_CAPTUREPOLARITY包含了TIM_RESET_CAPTUREPOLARITY(重置)和TIM_SET_CAPTUREPOLARITY(设置极性)操作
  202. __HAL_TIM_DISABLE(&htim3);
  203. TIM_RESET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_1); //一定要先清除原来的设置!!
  204. TIM_SET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);//配置TIM5通道1上升沿捕获
  205. __HAL_TIM_ENABLE(&htim3);//使能定时器5
  206. 或者
  207. __HAL_TIM_DISABLE(&htim3);
  208. __HAL_TIM_SET_CAPTUREPOLARITY(&htim3, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
  209. __HAL_TIM_ENABLE(&htim3);//使能定时器5
  210. */
  211. /* USER CODE BEGIN 1 */
  212. //定时器更新中断(计数溢出)中断处理回调函数, 该函数在HAL_TIM_IRQHandler中会被调用
  213. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  214. {
  215. if(htim->Instance == TIM2){
  216. //每次溢出时间为65536us
  217. if(flg==1)//还未成功捕获
  218. {
  219. if((num_period&0X3F)==0X3F)//电平太长了
  220. {
  221. flg=4; //标记成功捕获了一次
  222. }else num_period ++;
  223. }
  224. }
  225. }
  226. //定时器输入捕获中断处理回调函数,该函数在HAL_TIM_IRQHandler中会被调用
  227. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//捕获中断发生时执行
  228. {
  229. if(htim->Instance == TIM2)//PB3
  230. {
  231. switch (flg){
  232. case 1:
  233. capture_Buf_timer2[0] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);//获取当前的捕获值.
  234. __HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_2,TIM_ICPOLARITY_FALLING); //设置为下降沿捕获
  235. flg = 2;
  236. break;
  237. case 2:
  238. capture_Buf_timer2[1] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);//获取当前的捕获值.
  239. __HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING);
  240. flg = 3;
  241. break;
  242. case 3:
  243. capture_Buf_timer2[2] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);//获取当前的捕获值.
  244. HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_2); //停止捕获 或者: __HAL_TIM_DISABLE(&htim2);
  245. flg = 4;
  246. break;
  247. }
  248. }
  249. }
  250. void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
  251. {
  252. g_adc_dma_sta = 1;
  253. };
  254. /* USER CODE END 1 */
  255. /* USER CODE END 4 */
  256. /**
  257. * @brief This function is executed in case of error occurrence.
  258. * @retval None
  259. */
  260. void Error_Handler(void)
  261. {
  262. /* USER CODE BEGIN Error_Handler_Debug */
  263. /* User can add his own implementation to report the HAL error return state */
  264. __disable_irq();
  265. while (1)
  266. {
  267. }
  268. /* USER CODE END Error_Handler_Debug */
  269. }
  270. #ifdef USE_FULL_ASSERT
  271. /**
  272. * @brief Reports the name of the source file and the source line number
  273. * where the assert_param error has occurred.
  274. * @param file: pointer to the source file name
  275. * @param line: assert_param error line source number
  276. * @retval None
  277. */
  278. void assert_failed(uint8_t *file, uint32_t line)
  279. {
  280. /* USER CODE BEGIN 6 */
  281. /* User can add his own implementation to report the file name and line number,
  282. ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  283. /* USER CODE END 6 */
  284. }
  285. #endif /* USE_FULL_ASSERT */

 

  1. 部分代码分析
  2. __HAL_TIM_SET_CAPTUREPOLARITY包含了
  3. TIM_RESET_CAPTUREPOLARITY(重置)和TIM_SET_CAPTUREPOLARITY(设置极性)操作
  4. __HAL_TIM_DISABLE(&htim3);//关闭定时器3
  5. TIM_RESET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_1); //清除原来的设置
  6. TIM_SET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);//配置TIM3通道1上升沿捕获
  7. __HAL_TIM_ENABLE(&htim3);//使能定时器5
  8. 或者使用下面代码
  9. __HAL_TIM_DISABLE(&htim3);
  10. __HAL_TIM_SET_CAPTUREPOLARITY(&htim3, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
  11. __HAL_TIM_ENABLE(&htim3);//使能定时器3

CUBEMX配置

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/930599
推荐阅读
相关标签
  

闽ICP备14008679号