STM32F4XX芯片TIM4产生PWM波的方式与其他定时器是不一样的

因为之前学习STM32系列芯片的时候编程用的是寄存器的方式,现在开始学习使用库函数版本来完成相应的功能,在我用开发板学习完定时器3(TIM3)中断控制led后就想用定时器(TIM4)产生PWM波来控制LED。我按照TIM3产生PWM波的方式完成初始化工作:

//arr自动重装载值
//psc预分频系数

void TIM3_PWM_Init(u32 arr,u32 psc)
{		 					 
	//此部分需手动修改IO口设置
	
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  	//TIM3时钟使能    
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 	//使能PORTA时钟	
	
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_TIM3); //GPIOA6复用为定时器3
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;           //GPIOFA
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
	GPIO_Init(GPIOA,&GPIO_InitStructure);              //初始化PA6
	  
	TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
	TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
	
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);//初始化定时器3
	
	//初始化TIM14 Channel1 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
	TIM_OC1Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM1 4OC1

	TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR1上的预装载寄存器
 
  TIM_ARRPreloadConfig(TIM3,ENABLE);//ARPE使能 
	
	TIM_Cmd(TIM3, ENABLE);  //使能TIM3
 
										  
}  

完成之后按照TIM3的方式完成主函数的编程,一运行之后发现LED没反应,检查之后发现硬件没问题,我就把初始化代码中TIM4替换掉,变成上面的那段代码,一运行发现可以,这个时候我就猜想应该是两者之间有什么不同导致,然后再网上查找相关资料发现的却是不同,两者产生PWM波的方式不一样:

其他定时器使用:TIM_SetCompare1(TIM14,625);来设置产生PWM

但是这个办法对TIM4行不通。

TIM4使用

TIM_OCInitStructure.TIM_Pulse = dutyCycle;

于是我参考网上关于TIM4的初始化代码完成相应的操作运行之后发现可以正常运行

pwm.c代码:


void TIM4_PWM_Init(u32 arr,u32 psc,u32 date)
{                              
    //此部分需手动修改IO口设置
    
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);      //TIM3时钟使能    
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);     //使能PORTA时钟    
    
    GPIO_PinAFConfig(GPIOD,GPIO_PinSource15,GPIO_AF_TIM4); //GPIOA6复用为定时器3
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;           //GPIOFA
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;    //速度100MHz
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
    GPIO_Init(GPIOD,&GPIO_InitStructure);              //初始化PA6
      
    TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
    TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
    
    TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);//初始化定时器3
    
    //初始化TIM14 Channel1 PWM模式     
    TIM_OCInitStructure.TIM_Pulse=date;
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
    TIM_OC4Init(TIM4, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM1 4OC1

    TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);  //使能TIM3在CCR1上的预装载寄存器
 
  TIM_ARRPreloadConfig(TIM4,ENABLE);//ARPE使能 
    
    TIM_Cmd(TIM4, ENABLE);  //使能TIM3
                               
}  

main.c代码:

int main()
{
    u16 led0pwmval=0;    
  u8 dir=1;
    delay_init(168);
    led_init();
    while(1)
    {
        delay_ms(10);    
        
        if(dir)led0pwmval++;//dir==1 led0pwmval递增 
        else led0pwmval--;    //dir==0 led0pwmval递减 
         if(led0pwmval>400)dir=0;//led0pwmval到达300后,方向为递减
        if(led0pwmval==0)dir=1;    //led0pwmval递减到0后,方向改为递增
       
        TIM4_PWM_Init(500,840,led0pwmval);//定时器4
        
    }
    
}

写这个笔记是想让自己以后记得。

接触到HAL库的时候发现HAL库里面也存在这种现象,不过其它定时器也可以使用TIM4的方法改变输出的PWM占空比,

HAL库其它定时器改变占空比的函数:__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, pwm_value);

TIM4需要自定义函数来实现改变Pulse从而改变占空比:

void user_pwm_setvalue(uint16_t pwm_value)
{
     TIM_OC_InitTypeDef sConfigOC;
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = pwm_value;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2);
  HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);//这个函数在main函数的begin2-end2之间还要再调用一次
}

 

你可能感兴趣的:(M4)