本人使用STM32F407 想要同时实现TIM3 TIM4两个定时器同时的PWM输出 并且每个定时器都有中断应用
目前单独调用一个定时器用示波器看 都有正常的波形输出 但是两个同时调用 main里边先初始化的定时器对应端口有输出 第二个初始化的定时器就没有输出 想问问各位 这种情况是那种地方没有注意
在中断函数的优先级也有区别,代码如下
TIM4.H
#ifndef __TIM4_H
#define __TIM4_H
#include "stm32f4xx.h"
#define TIM4_OCPWM_PIN GPIO_Pin_6
#define TIM4_OCPWM_GPIO_PORT GPIOB
#define TIM4_OCPWM_GPIO_CLK RCC_AHB1Periph_GPIOB
#define TIM4_OCPWM_PINSOURCE GPIO_PinSource6
#define TIM4_OCPWM_AF GPIO_AF_TIM4
#define TIM4_TIM TIM4
#define TIM4_TIM_CLK RCC_APB1Periph_TIM4
#define ZHUANPAN_TIM_IRQn TIM4_IRQn
#define ZHUANPAN_TIM_IRQHandler TIM4_IRQnHandler
#define ZHUANPAN_TIM_NVIC_PreemptionPriority 0
#define ZHUANPAN_TIM_NVIC_SubPriority 1
void TIM4_Configuration(void);
#endif /* __TIM4_H */
TIM4.C
#include "./tim/bsp_general_tim.h"
/**
* @brief 配置TIM复用输出PWM时用到的I/O
* @param 无
* @retval 无
*/
static void TIM4_GPIO_Config(void)
{
/*定义一个GPIO_InitTypeDef类型的结构体*/
GPIO_InitTypeDef GPIO_InitStructure;
/*开启相关的GPIO外设时钟*/
RCC_AHB1PeriphClockCmd (TIM4_OCPWM_GPIO_CLK, ENABLE);
/* 定时器通道引脚复用 */
GPIO_PinAFConfig(TIM4_OCPWM_GPIO_PORT,TIM4_OCPWM_PINSOURCE,TIM4_OCPWM_AF);
/* 定时器通道引脚配置 */
GPIO_InitStructure.GPIO_Pin = TIM4_OCPWM_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(TIM4_OCPWM_GPIO_PORT, &GPIO_InitStructure);
}
/*
* 注意:TIM_TimeBaseInitTypeDef结构体里面有5个成员,TIM6和TIM7的寄存器里面只有
* TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的时候只需初始化这两个成员即可,
* 另外三个成员是通用定时器和高级定时器才有.
*-----------------------------------------------------------------------------
* TIM_Prescaler 都有
* TIM_CounterMode TIMx,x[6,7]没有,其他都有(基本定时器)
* TIM_Period 都有
* TIM_ClockDivision TIMx,x[6,7]没有,其他都有(基本定时器)
* TIM_RepetitionCounter TIMx,x[1,8]才有(高级定时器)
*-----------------------------------------------------------------------------
*/
static void TIM4_PWMOUTPUT_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
// 开启TIMx_CLK,x[2,3,4,5,12,13,14]
RCC_APB1PeriphClockCmd(TIM4_TIM_CLK, ENABLE);
/* 累计 TIM_Period个后产生一个更新或者中断*/
//当定时器从0计数到8399,即为8400次,为一个定时周期
TIM_TimeBaseStructure.TIM_Period = 8400-1;
// 通用控制定时器时钟源TIMxCLK = HCLK/2=84MHz
// 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=100KHz
TIM_TimeBaseStructure.TIM_Prescaler = 840-1;
// 采样时钟分频
TIM_TimeBaseStructure.TIM_ClockDivision=0;
// 计数方式
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
// 初始化定时器TIMx, x[2,3,4,5,12,13,14]
TIM_TimeBaseInit(TIM4_TIM, &TIM_TimeBaseStructure);
/*PWM模式配置*/
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //配置为PWM模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 2800-1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //当定时器计数值小于CCR1_Val时为高电平
TIM_OC1Init(TIM4_TIM, &TIM_OCInitStructure); //使能通道1
/*使能通道1重载*/
TIM_OC1PreloadConfig(TIM4_TIM, TIM_OCPreload_Enable);
// 使能定时器
TIM_Cmd(TIM4_TIM, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = ZHUANPAN_TIM_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ZHUANPAN_TIM_NVIC_PreemptionPriority;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ZHUANPAN_TIM_NVIC_SubPriority;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
}
/**
* @brief 初始化控制通用定时器
* @param 无
* @retval 无
*/
void TIM4_Configuration(void)
{
TIM4_GPIO_Config();
TIM4_PWMOUTPUT_Config();
}
void ZHUANPAN_TIM_IRQHandler(void){
//判断标志位
if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET)
{
//PFout(10)^=1;//对led进行闪烁操作
//清空标志位
}
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
}
TIM3.H
#ifndef __TIM3_H
#define __TIM3_H
#include "stm32f4xx.h"
#define TIM3_OCPWM_PIN GPIO_Pin_6
#define TIM3_OCPWM_GPIO_PORT GPIOA
#define TIM3_OCPWM_GPIO_CLK RCC_AHB1Periph_GPIOA
#define TIM3_OCPWM_PINSOURCE GPIO_PinSource6
#define TIM3_OCPWM_AF GPIO_AF_TIM3
#define TIM3_TIM TIM3
#define TIM3_TIM_CLK RCC_APB1Periph_TIM3
#define SIGANG_TIM_IRQn TIM3_IRQn
#define SIGANG_TIM_IRQHandler TIM3_IRQnHandler
#define SIGANG_TIM_NVIC_PreemptionPriority 1
#define SIGANG_TIM_NVIC_SubPriority 1
void TIM3_Configuration(void);
#endif /* __TIM3_H */
TIM3.C
#include "tim2.h"
/**
* @brief 配置TIM复用输出PWM时用到的I/O
* @param 无
* @retval 无
*/
static void TIM3_GPIO_Config(void)
{
/*定义一个GPIO_InitTypeDef类型的结构体*/
GPIO_InitTypeDef GPIO_InitStructure;
/*开启相关的GPIO外设时钟*/
RCC_AHB1PeriphClockCmd (TIM3_OCPWM_GPIO_CLK, ENABLE);
/* 定时器通道引脚复用 */
GPIO_PinAFConfig(TIM3_OCPWM_GPIO_PORT,TIM3_OCPWM_PINSOURCE,TIM3_OCPWM_AF);
/* 定时器通道引脚配置 */
GPIO_InitStructure.GPIO_Pin = TIM3_OCPWM_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(TIM3_OCPWM_GPIO_PORT, &GPIO_InitStructure);
}
/*
* 注意:TIM_TimeBaseInitTypeDef结构体里面有5个成员,TIM6和TIM7的寄存器里面只有
* TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的时候只需初始化这两个成员即可,
* 另外三个成员是通用定时器和高级定时器才有.
*-----------------------------------------------------------------------------
* TIM_Prescaler 都有
* TIM_CounterMode TIMx,x[6,7]没有,其他都有(基本定时器)
* TIM_Period 都有
* TIM_ClockDivision TIMx,x[6,7]没有,其他都有(基本定时器)
* TIM_RepetitionCounter TIMx,x[1,8]才有(高级定时器)
*-----------------------------------------------------------------------------
*/
static void TIM3_PWMOUTPUT_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
// 开启TIMx_CLK,x[2,3,4,5,12,13,14]
RCC_APB1PeriphClockCmd(TIM3_TIM_CLK, ENABLE);
/* 累计 TIM_Period个后产生一个更新或者中断*/
//当定时器从0计数到8399,即为8400次,为一个定时周期
TIM_TimeBaseStructure.TIM_Period = 8400-1;
// 通用控制定时器时钟源TIMxCLK = HCLK/2=84MHz
// 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=100KHz
TIM_TimeBaseStructure.TIM_Prescaler = 840-1;
// 采样时钟分频
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
// 计数方式
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
// 初始化定时器TIMx, x[2,3,4,5,12,13,14]
TIM_TimeBaseInit(TIM3_TIM, &TIM_TimeBaseStructure);
/*PWM模式配置*/
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //配置为PWM模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 2800-1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //当定时器计数值小于CCR1_Val时为高电平
TIM_OC1Init(TIM3_TIM, &TIM_OCInitStructure); //使能通道1
/*使能通道1重载*/
TIM_OC1PreloadConfig(TIM3_TIM, TIM_OCPreload_Enable);
// 使能定时器
TIM_Cmd(TIM3_TIM, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = SIGANG_TIM_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = SIGANG_TIM_NVIC_PreemptionPriority;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = SIGANG_TIM_NVIC_SubPriority;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//TIM_ITConfig(TIM3_TIM, TIM_IT_Update, ENABLE);
}
/**
* @brief 初始化控制通用定时器
* @param 无
* @retval 无
*/
void TIM3_Configuration(void)
{
TIM3_GPIO_Config();
TIM3_PWMOUTPUT_Config();
}
void SIGANG_TIM_IRQHandler(void){
//判断标志位
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)
{
//PFout(10)^=1;//对led进行闪烁操作
//清空标志位
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
MAIN.C
#include "stm32f4xx.h"
#include "./tim/bsp_general_tim.h"
#include "tim2.h"
/**
* @brief 主函数
* @param 无
* @retval 无
*/
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* 初始化通用定时器PWM输出 */
TIM3_Configuration();
TIM4_Configuration();
//TIM3_Configuration();
while(1)
{
}
}
本章节就为大家讲解这么多,相对比较容易掌握,望初学者熟练运用。
引用chatGPT作答,首先需要注意的是,两个定时器同时输出PWM时,需要确保定时器时钟的源和频率一致,否则可能会产生干扰和冲突。其次,在设置定时器中断时,需要考虑中断优先级的设置,确保两个定时器中断不会相互干扰。
在您提供的代码中,TIM4和TIM3的配置和初始化函数都没有给出,因此无法确定具体的问题所在。建议您检查以下几个方面:
1.检查TIM3和TIM4的初始化函数,确保时钟源和频率一致,并且没有冲突或干扰。
2.检查定时器中断的优先级设置,确保两个定时器中断不会相互干扰。
3.检查引脚复用和配置,确保两个定时器的PWM输出引脚没有重叠或冲突。
另外,建议您将问题更具体地描述一下,例如您的波形输出具体是什么样的,有无异常,能否提供示波器截图等信息,以便更好地定位问题。