硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1004|回复: 3
收起左侧

[有问必答] STM32G473的TIM2&TIM5输出异常,怀疑内核问题

[复制链接]

5

主题

38

回帖

53

积分

初级会员

积分
53
发表于 2024-6-24 09:48:08 | 显示全部楼层 |阅读模式
使用STM32F473VET6(M4内核)初始化了8个TIM输出8路PWM,发现TIM2&TIM5重新赋值后使能pwm输出,发现其余6路的PWM会正常输出,而TIM2&TIM5的pwm会延时后(大约15S)输出。

附代码

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* 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 */
void user_debug(void);
/* 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 */
//__disable_irq();
  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
        #if 1
  MX_GPIO_Init();
  MX_TIM15_Init();
  MX_TIM16_Init();
  MX_TIM17_Init();
  MX_TIM1_Init();
  MX_TIM2_Init();
  MX_TIM3_Init();
  MX_TIM5_Init();
  MX_TIM20_Init();
  MX_USART1_UART_Init();
        #endif

  /* USER CODE BEGIN 2 */
user_debug();


  TIM15->PSC = 1 - 1;
  TIM15->ARR = 42500 - 1;
  TIM15->CCR1 = 42500 / 2;

  TIM3->PSC = 1 - 1;
  TIM3->ARR = 42500 - 1;
  TIM3->CCR2 = 42500 / 2;

  TIM16->PSC = 1 - 1;
  TIM16->ARR = 42500 - 1;
  TIM16->CCR1 = 42500 / 2;

  TIM17->PSC = 1 - 1;
  TIM17->ARR = 42500 - 1;
  TIM17->CCR1 = 42500 / 2;

  TIM20->PSC = 1 - 1;
  TIM20->ARR = 42500 - 1;
  TIM20->CCR1 = 42500 / 2;

  TIM5->PSC = 1 - 1;
  TIM5->ARR = 42500 - 1;
  TIM5->CCR3 = 42500 / 2;

  TIM1->PSC = 1 - 1;
  TIM1->ARR = 42500 - 1;
  TIM1->CCR2 = 42500 / 2;

  TIM2->PSC = 1 - 1;
  TIM2->ARR = 42500 - 1;
  TIM2->CCR3 = 42500 / 2;

  HAL_TIM_PWM_Start(&htim15, TIM_CHANNEL_1);
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
  HAL_TIM_PWM_Start(&htim16, TIM_CHANNEL_1);
  HAL_TIM_PWM_Start(&htim17, TIM_CHANNEL_1);
  HAL_TIM_PWM_Start(&htim20, TIM_CHANNEL_1);
  HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_3);
  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
  HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3);

//  HAL_GPIO_WritePin(Relay_1_GPIO_Port, Relay_1_Pin, GPIO_PIN_SET);
  user_debug();
  HAL_Delay(1000);

  HAL_TIM_PWM_Stop(&htim15, TIM_CHANNEL_1);
  HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_2);
  HAL_TIM_PWM_Stop(&htim16, TIM_CHANNEL_1);
  HAL_TIM_PWM_Stop(&htim17, TIM_CHANNEL_1);
  HAL_TIM_PWM_Stop(&htim20, TIM_CHANNEL_1);
  HAL_TIM_PWM_Stop(&htim5, TIM_CHANNEL_3);
  HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);
  HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_3);

//  HAL_GPIO_WritePin(Relay_1_GPIO_Port, Relay_1_Pin, GPIO_PIN_RESET);
  HAL_Delay(1000);
  user_debug();

// /* USER CODE BEGIN WHILE */
// HAL_GPIO_WritePin(Relay_1_GPIO_Port, Relay_1_Pin, GPIO_PIN_SET);
  TIM5->PSC = 1 - 1;
  TIM5->ARR = 11333 - 1;
  TIM5->CCR3 = 11333 / 2;

  TIM2->PSC = 1 - 1;
  TIM2->ARR = 11333 - 1;
  TIM2->CCR3 = 11333 / 2;
  /*TIM2和TIM5重新赋值后 启动8路PWM输出 TIM2和TIM5大约会延时15s后输出 (对其余6个定时器重新赋值没有影响)*/
  HAL_TIM_PWM_Start(&htim15, TIM_CHANNEL_1);
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
  HAL_TIM_PWM_Start(&htim16, TIM_CHANNEL_1);
  HAL_TIM_PWM_Start(&htim17, TIM_CHANNEL_1);
  HAL_TIM_PWM_Start(&htim20, TIM_CHANNEL_1);
  HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_3);
  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
  HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_3);
  /* USER CODE END 2 */


  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* 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_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  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 = RCC_PLLM_DIV6;
  RCC_OscInitStruct.PLL.PLLN = 85;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  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_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */
void HAL_IncTick(void)
{

  uwTick += uwTickFreq;
}
int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);

  return (ch);
}

void user_debug(void)
{

  uint32_t CPU_Sn0, CPU_Sn1, CPU_Sn2;
  CPU_Sn0 = *(__IO uint32_t *)(0x1FFF7590);
  CPU_Sn1 = *(__IO uint32_t *)(0x1FFF7590 + 4);
  CPU_Sn2 = *(__IO uint32_t *)(0x1FFF7590 + 8);

  printf("CPU : STM32G473VET6, LQFP100, Fre: %dMHz\r\n", SystemCoreClock / 1000000);
  printf("UID = %08X %08X %08X\n\r", CPU_Sn2, CPU_Sn1, CPU_Sn0);
}
/* 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 */


TIM2&TIM5刚好挂在一起

TIM2&TIM5刚好挂在一起
回复

使用道具 举报

5

主题

38

回帖

53

积分

初级会员

积分
53
 楼主| 发表于 2024-6-24 09:55:03 | 显示全部楼层
在mdk dubug 使能定时器后CEN都正常置1,计数器正常计数,但是无PWM输出
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115434
QQ
发表于 2024-6-25 15:03:28 | 显示全部楼层
注意TIM2和TIM5是32bit定时器。其他都是16bit的
回复

使用道具 举报

0

主题

19

回帖

19

积分

新手上路

积分
19
发表于 2024-9-6 22:23:57 | 显示全部楼层
你写的ARR和CCR都是写在了预装寄存器里,而不是反应到真正起作用的影子寄存器上,要到下一次更新事件(UEV: update event)才刷进去。
下一次更新要等CNT>=ARR溢出。32溢出很慢,16位溢出很快,所以你的所有写设置,实际上都是在TIMx下一次溢出才起作用的。
如何直接操作影子寄存器?PSC没法子只能等UEV,ARR可以设CR1的ARPE=0取消预装功能。通道的CCRx也是:CCMRx的OCxPE=0取消预装功能,直接操作CCRx影子寄存器。

还有一个方法:你设置完成准备开动时,强制TIMx的UG=1,也就是强行发出一个UEV事件,也能立刻更新你的配置到影子寄存器。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-4-26 04:48 , Processed in 0.232538 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表