你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32G431RBTx 基本模块 TIM OC输出

[复制链接]
STMCU小助手 发布时间:2023-3-1 20:55
1.CubeMx的配置步骤
修改上一次IC捕获的ioc文件来生成工程

2dc00d051c5c461e96277f98ebb603a4.png

修改PA2,PA3为定时器15的通道1和通道2。

cf9daf957ff44608a1ed5c3f5ee54b19.png

c161298b50224fe6a99551c8c46d1ae5.png

17c529d9985b418aa14ffb6b8a303aed.png

2.生成工程
点击GENERATE CODE生成代码后点击Open Project即可。

03e1e8fdfabf4a92ad903add83876ee4.png


3.测试代码

interrupt.h:
  1. #ifndef __INTERRUPT_H__
  2. #define __INTERRUPT_H__

  3. #include "main.h"

  4. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim);
  5. void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim);

  6. #endif

复制代码

interrupt.c:
  1. #include "interrupt.h"
  2. #include "lcd.h"
  3. #include "stdio.h"
  4. unsigned int Period = 0;
  5. unsigned int HighTime = 0;
  6. unsigned char OC1_Duty = 25;
  7. unsigned char OC2_Duty = 75;
  8. unsigned short OC1_Pulse = 1000;
  9. unsigned short OC2_Pulse = 4000;


  10. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
  11. {
  12.         if(htim->Instance == TIM2)
  13.         {
  14.                 if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
  15.                 {
  16.                         Period = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); //读取直接通道
  17.                         HighTime = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); //读取间接通道
  18.                         __HAL_TIM_SetCounter(htim, 0);
  19.                         HAL_TIM_IC_Start_IT(htim, TIM_CHANNEL_1); //开启中断以便于下次采值
  20.                         HAL_TIM_IC_Start_IT(htim, TIM_CHANNEL_2);
  21.                 }
  22.         }
  23. }

  24. void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
  25. {
  26.         if(htim->Instance == TIM15)
  27.         {
  28.                 unsigned short CapVal = 0;
  29.                 if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
  30.                 {
  31.                         CapVal = __HAL_TIM_GetCompare(htim, TIM_CHANNEL_1);
  32.                         if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2) == GPIO_PIN_RESET)
  33.                         {
  34.                                 __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_1, CapVal + OC1_Pulse - OC1_Duty / 100.0 * OC1_Pulse);
  35.                         }
  36.                         else
  37.                         {
  38.                                 __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_1, CapVal + OC1_Duty / 100.0 * OC1_Pulse);
  39.                         }
  40.                                
  41.                 }
  42.                 else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
  43.                 {
  44.                         CapVal = __HAL_TIM_GetCompare(htim, TIM_CHANNEL_2);
  45.                         if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) == GPIO_PIN_RESET)
  46.                         {
  47.                                 __HAL_TIM_SetCompare(htim, TIM_CHANNEL_2, CapVal + (1 - OC2_Duty / 100.0) * OC2_Pulse);
  48.                         }
  49.                         else
  50.                         {
  51.                                 __HAL_TIM_SetCompare(htim, TIM_CHANNEL_2, CapVal + OC2_Duty / 100.0 * OC2_Pulse);
  52.                         }
  53.                 }
  54.         }
  55. }

复制代码

main.c:
  1. /* USER CODE BEGIN Header */
  2. /**
  3.   ******************************************************************************
  4.   * @file           : main.c
  5.   * @brief          : Main program body
  6.   ******************************************************************************
  7.   * @attention
  8.   *
  9.   * <h2><center>© Copyright (c) 2023 STMicroelectronics.
  10.   * All rights reserved.</center></h2>
  11.   *
  12.   * This software component is licensed by ST under BSD 3-Clause license,
  13.   * the "License"; You may not use this file except in compliance with the
  14.   * License. You may obtain a copy of the License at:
  15.   *                        opensource.org/licenses/BSD-3-Clause
  16.   *
  17.   ******************************************************************************
  18.   */
  19. /* USER CODE END Header */
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "main.h"
  22. #include "tim.h"
  23. #include "gpio.h"

  24. /* Private includes ----------------------------------------------------------*/
  25. /* USER CODE BEGIN Includes */
  26. #include "lcd.h"
  27. #include "stdio.h"
  28. /* USER CODE END Includes */

  29. /* Private typedef -----------------------------------------------------------*/
  30. /* USER CODE BEGIN PTD */

  31. /* USER CODE END PTD */

  32. /* Private define ------------------------------------------------------------*/
  33. /* USER CODE BEGIN PD */
  34. /* USER CODE END PD */

  35. /* Private macro -------------------------------------------------------------*/
  36. /* USER CODE BEGIN PM */

  37. /* USER CODE END PM */

  38. /* Private variables ---------------------------------------------------------*/

  39. /* USER CODE BEGIN PV */
  40. extern unsigned int Period;
  41. extern unsigned int HighTime;
  42. char text[30];
  43. /* USER CODE END PV */

  44. /* Private function prototypes -----------------------------------------------*/
  45. void SystemClock_Config(void);
  46. /* USER CODE BEGIN PFP */

  47. /* USER CODE END PFP */

  48. /* Private user code ---------------------------------------------------------*/
  49. /* USER CODE BEGIN 0 */

  50. /* USER CODE END 0 */

  51. /**
  52.   * @brief  The application entry point.
  53.   * @retval int
  54.   */
  55. int main(void)
  56. {
  57.   /* USER CODE BEGIN 1 */

  58.   /* USER CODE END 1 */

  59.   /* MCU Configuration--------------------------------------------------------*/

  60.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  61.   HAL_Init();

  62.   /* USER CODE BEGIN Init */

  63.   /* USER CODE END Init */

  64.   /* Configure the system clock */
  65.   SystemClock_Config();

  66.   /* USER CODE BEGIN SysInit */

  67.   /* USER CODE END SysInit */

  68.   /* Initialize all configured peripherals */
  69.   MX_GPIO_Init();
  70.   MX_TIM2_Init();
  71.   MX_TIM15_Init();
  72.   MX_TIM3_Init();
  73.   /* USER CODE BEGIN 2 */
  74.         HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
  75.         HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);
  76.         HAL_TIM_OC_Start_IT(&htim15, TIM_CHANNEL_1);
  77.         HAL_TIM_OC_Start_IT(&htim15, TIM_CHANNEL_2);
  78.         LCD_Init();
  79.         LCD_Clear(Black);
  80.         LCD_SetBackColor(Black);
  81.         LCD_SetTextColor(White);
  82.   /* USER CODE END 2 */

  83.   /* Infinite loop */
  84.   /* USER CODE BEGIN WHILE */
  85.   while (1)
  86.   {
  87.     /* USER CODE END WHILE */

  88.     /* USER CODE BEGIN 3 */
  89.                 sprintf(text, "frq:%.2f   ", 1000000.0 / Period); //分频成1MHz所以这里1000000.0作为被除数
  90.                 LCD_DisplayStringLine(Line0,  text);
  91.                 sprintf(text, "Duty:%.2f   ", HighTime / (float)Period * 100); //占空比为高电平时间 / 周期 * 100%
  92.                 LCD_DisplayStringLine(Line1,  text);
  93.   }
  94.   /* USER CODE END 3 */
  95. }

  96. /**
  97.   * @brief System Clock Configuration
  98.   * @retval None
  99.   */
  100. void SystemClock_Config(void)
  101. {
  102.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  103.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  104.   /** Configure the main internal regulator output voltage
  105.   */
  106.   HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
  107.   /** Initializes the RCC Oscillators according to the specified parameters
  108.   * in the RCC_OscInitTypeDef structure.
  109.   */
  110.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  111.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  112.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  113.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  114.   RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV3;
  115.   RCC_OscInitStruct.PLL.PLLN = 20;
  116.   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  117.   RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  118.   RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  119.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  120.   {
  121.     Error_Handler();
  122.   }
  123.   /** Initializes the CPU, AHB and APB buses clocks
  124.   */
  125.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  126.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  127.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  128.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  129.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  130.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  131.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  132.   {
  133.     Error_Handler();
  134.   }
  135. }

  136. /* USER CODE BEGIN 4 */

  137. /* USER CODE END 4 */

  138. /**
  139.   * @brief  This function is executed in case of error occurrence.
  140.   * @retval None
  141.   */
  142. void Error_Handler(void)
  143. {
  144.   /* USER CODE BEGIN Error_Handler_Debug */
  145.   /* User can add his own implementation to report the HAL error return state */
  146.   __disable_irq();
  147.   while (1)
  148.   {
  149.   }
  150.   /* USER CODE END Error_Handler_Debug */
  151. }

  152. #ifdef  USE_FULL_ASSERT
  153. /**
  154.   * @brief  Reports the name of the source file and the source line number
  155.   *         where the assert_param error has occurred.
  156.   * @param  file: pointer to the source file name
  157.   * @param  line: assert_param error line source number
  158.   * @retval None
  159.   */
  160. void assert_failed(uint8_t *file, uint32_t line)
  161. {
  162.   /* USER CODE BEGIN 6 */
  163.   /* User can add his own implementation to report the file name and line number,
  164.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  165.   /* USER CODE END 6 */
  166. }
  167. #endif /* USE_FULL_ASSERT */

  168. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

复制代码

4.演示效果

d297c5a6339242a5af92b5fb08e33ef2.gif


总结
从结果来看我们目标是PA2输出1000Hz占空比为25%的PWM波但最后测量频率为1026和23%的波形,误差比较大。PA3目标输出250Hz占空比为75%的PWM波,但最后输出的是252.84Hz和74.72%的PWM波,误差虽然存在但与PA2输出的波形比较,误差算是少一点,我们可以知道OC输出高频率PWM波时存在很严重的波形失真现象,但在输出低频率PWM波时这种情况就好一点,TIM的PWM模式不会有这样的问题但是PWM模式下定时器各个通道输出PWM波频率相同(占空比可以不同),不能实现每个通道占空比不同且频率也不同的情况。OC模式下虽然不支持输出高频率PWM波,但是它能实现每个通道的PWM波频率不同占空比也不同。


以上就是OC的配置过程,测试代码以及测试效果
————————————————
版权声明:火花页.


收藏 评论0 发布时间:2023-3-1 20:55

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版