STM32G0 定时器中断 PWM 无法正常工作的问题
STM32G0 problems with Timer Interrupt PWM doesnt work correctly
我想使用 stm32 生成 PWM 信号,但我必须能够在每个信号后更改占空比。
我的问题是,如果我尝试它无法正常工作。它发送 3-5 个具有相同占空比的脉冲,然后更改值。我不明白为什么每次脉冲后它都不会改变。
还有一个问题,我必须在每个脉冲后重新启用通道的 CCER 位,否则它会因任何原因重置。
我使用的是 STM32G071 Nucleo-64 开发板,搭配 Keil uVision 5
我用 STM32CubeMX 生成了开始并添加了我的代码所以它可以工作,但它没有。我不知道该怎么办。我很乐意提供一些建议。
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define HIGH_PWM_SIGNAL 70//( 45 )
#define LOW_PWM_SIGNAL 10//( 27 )
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim3;
/* USER CODE BEGIN PV */
uint8_t PWM_Count = 0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM3_Init(void);
static void MX_NVIC_Init(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_TIM3_Init();
/* Initialize interrupts */
MX_NVIC_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT( &htim3 );
HAL_TIM_PWM_Start_IT( &htim3, TIM_CHANNEL_1 );
/* 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)
{
// STM32CUbeMX generated deleted for readablitity
}
/**
* @brief NVIC Configuration.
* @retval None
*/
static void MX_NVIC_Init(void)
{
/* TIM3_IRQn interrupt configuration */
HAL_NVIC_SetPriority(TIM3_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(TIM3_IRQn);
}
/**
* @brief TIM3 Initialization Function
* @param None
* @retval None
*/
static void MX_TIM3_Init(void)
{
/* USER CODE BEGIN TIM3_Init 0 */
HAL_TIM_Base_DeInit( &htim3 );
HAL_TIM_PWM_DeInit( &htim3 );
/* USER CODE END TIM3_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
/* USER CODE BEGIN TIM3_Init 1 */
/* USER CODE END TIM3_Init 1 */
htim3.Instance = TIM3;
htim3.Init.Prescaler = 0;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 80;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 10;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM3_Init 2 */
HAL_NVIC_SetPriority( TIM3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ( TIM3_IRQn );
// Update interrupt
HAL_TIM_GenerateEvent( &htim3, TIM_EVENTSOURCE_UPDATE );
// PWM interrupt
HAL_TIM_GenerateEvent( &htim3, TIM_EVENTSOURCE_CC1 );
/* USER CODE END TIM3_Init 2 */
HAL_TIM_MspPostInit(&htim3);
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
// STM32CUbeMX generated deleted for readablitity
}
/* USER CODE BEGIN 4 */
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim){
// Change PWM Duty Cycle
PWM_Count += 1;
if ( PWM_Count > 1 )
PWM_Count = 0;
if ( PWM_Count == 0 ) TIM3->CCR1 = LOW_PWM_SIGNAL;
else TIM3->CCR1 = HIGH_PWM_SIGNAL;
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
// I have to re enable it or it doesn't output anything
TIM_CCxChannelCmd(htim3.Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
}
/* 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 */
}
它不会改变每个信号的占空比,它需要大约 3-5 个信号,然后它会改变占空比。
Oscilloscope: Output PWM Channel1
我找到了解决方案。我正在使用 lib "stm32g0xx_hal_tim.c",它非常方便。但是它用了很多时间。
它是为解决每个问题而构建的,因此会检查所有内容(所有中断标志)。
这有很多 if else 需要一些时间。
我自己对它进行了编程,它只检查我需要的东西,然后它就起作用了。
感谢您的帮助。
我想使用 stm32 生成 PWM 信号,但我必须能够在每个信号后更改占空比。 我的问题是,如果我尝试它无法正常工作。它发送 3-5 个具有相同占空比的脉冲,然后更改值。我不明白为什么每次脉冲后它都不会改变。 还有一个问题,我必须在每个脉冲后重新启用通道的 CCER 位,否则它会因任何原因重置。
我使用的是 STM32G071 Nucleo-64 开发板,搭配 Keil uVision 5
我用 STM32CubeMX 生成了开始并添加了我的代码所以它可以工作,但它没有。我不知道该怎么办。我很乐意提供一些建议。
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define HIGH_PWM_SIGNAL 70//( 45 )
#define LOW_PWM_SIGNAL 10//( 27 )
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim3;
/* USER CODE BEGIN PV */
uint8_t PWM_Count = 0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM3_Init(void);
static void MX_NVIC_Init(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_TIM3_Init();
/* Initialize interrupts */
MX_NVIC_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT( &htim3 );
HAL_TIM_PWM_Start_IT( &htim3, TIM_CHANNEL_1 );
/* 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)
{
// STM32CUbeMX generated deleted for readablitity
}
/**
* @brief NVIC Configuration.
* @retval None
*/
static void MX_NVIC_Init(void)
{
/* TIM3_IRQn interrupt configuration */
HAL_NVIC_SetPriority(TIM3_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(TIM3_IRQn);
}
/**
* @brief TIM3 Initialization Function
* @param None
* @retval None
*/
static void MX_TIM3_Init(void)
{
/* USER CODE BEGIN TIM3_Init 0 */
HAL_TIM_Base_DeInit( &htim3 );
HAL_TIM_PWM_DeInit( &htim3 );
/* USER CODE END TIM3_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
/* USER CODE BEGIN TIM3_Init 1 */
/* USER CODE END TIM3_Init 1 */
htim3.Instance = TIM3;
htim3.Init.Prescaler = 0;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 80;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 10;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM3_Init 2 */
HAL_NVIC_SetPriority( TIM3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ( TIM3_IRQn );
// Update interrupt
HAL_TIM_GenerateEvent( &htim3, TIM_EVENTSOURCE_UPDATE );
// PWM interrupt
HAL_TIM_GenerateEvent( &htim3, TIM_EVENTSOURCE_CC1 );
/* USER CODE END TIM3_Init 2 */
HAL_TIM_MspPostInit(&htim3);
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
// STM32CUbeMX generated deleted for readablitity
}
/* USER CODE BEGIN 4 */
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim){
// Change PWM Duty Cycle
PWM_Count += 1;
if ( PWM_Count > 1 )
PWM_Count = 0;
if ( PWM_Count == 0 ) TIM3->CCR1 = LOW_PWM_SIGNAL;
else TIM3->CCR1 = HIGH_PWM_SIGNAL;
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
// I have to re enable it or it doesn't output anything
TIM_CCxChannelCmd(htim3.Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
}
/* 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 */
}
它不会改变每个信号的占空比,它需要大约 3-5 个信号,然后它会改变占空比。 Oscilloscope: Output PWM Channel1
我找到了解决方案。我正在使用 lib "stm32g0xx_hal_tim.c",它非常方便。但是它用了很多时间。
它是为解决每个问题而构建的,因此会检查所有内容(所有中断标志)。 这有很多 if else 需要一些时间。
我自己对它进行了编程,它只检查我需要的东西,然后它就起作用了。
感谢您的帮助。