打印
[STM32]

用stm32高级定时器产生4路两两互补的PWM移相带死区,定时器进不来中断,产生波形不对

[复制链接]
2267|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
136297jia|  楼主 | 2015-10-30 10:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
extern char Upflag;

void TIM_config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_OCInitTypeDef  TIM_OCInitStructure;  
        TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
    /* 互补管脚定义设置 */  
        //RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB , ENABLE);  //使能GPIO外设时钟使能
  
    /* TIM1 clock enable */  
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//
  
    /*  管脚设配置*/  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;  
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   //复用满负载输出为3.3V
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  GPIO_Init(GPIOA, &GPIO_InitStructure);  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;
  GPIO_Init(GPIOB, &GPIO_InitStructure);  

        /* TIM时钟配置*/       
        TIM_TimeBaseStructure.TIM_Prescaler =0;                //预分频
        TIM_TimeBaseStructure.TIM_Period =1799;        //0~65535        ,50HZ
        TIM_TimeBaseStructure.TIM_CounterMode =TIM_CounterMode_CenterAligned1;
        TIM_TimeBaseStructure.TIM_ClockDivision =0;        //采样分频
        TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;        //重复预分频,更新PWM占空比
        TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);                //        初始化时钟
       
       
        /* PWM配置*/
        TIM_OCInitStructure.TIM_OCMode =TIM_OCMode_PWM1;        //输出比较模式,PWM模式1、2区别
        /*       
                        PWM模式1-        在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平;
                                                                        在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。
                        PWM模式2-         在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为无效电平,否则为有效电平;
                                                                        在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。
        */
        TIM_OCInitStructure.TIM_OutputState =TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_OCPolarity =TIM_OCPolarity_High;       
        TIM_OCInitStructure.TIM_Pulse =200;                        // 此处直接赋值设置占空比, 或者在其他地方调用TIM_SetCompare1(TIM1,3000); 也可以更改占空比,本程序是main函数中调用修改的占空比

        /*互补配置*/
        TIM_OCInitStructure.TIM_OutputNState =TIM_OutputNState_Enable;
        TIM_OCInitStructure.TIM_OCNPolarity =TIM_OCNPolarity_High;
        TIM_OCInitStructure.TIM_OCIdleState =TIM_OCIdleState_Reset;                //刹车之后的输出状态
        TIM_OCInitStructure.TIM_OCNIdleState =TIM_OCNIdleState_Reset;        //刹车之后的互补输出状态
        TIM_OC1Init(TIM1,&TIM_OCInitStructure);
       
        TIM_OCInitStructure.TIM_Pulse = 416;
        TIM_OC2Init(TIM1, &TIM_OCInitStructure);
        TIM_OCInitStructure.TIM_Pulse = 632;
        TIM_OC3Init(TIM1, &TIM_OCInitStructure);
       
       
        /* 死区配置*/
        TIM_BDTRInitStructure.TIM_OSSRState =TIM_OSSRState_Enable;                //运行模式下输出
        TIM_BDTRInitStructure.TIM_OSSIState =TIM_OSSIState_Enable;                //空闲模式下输出
        TIM_BDTRInitStructure.TIM_LOCKLevel =TIM_LOCKLevel_OFF;                        //锁定级别
        TIM_BDTRInitStructure.TIM_DeadTime =0x48;                                                //设置死区时间  0-0xff;1us
        /*               
                                                       
                例如  10us   应该在第四区域
                死区时间 =1/72*1000*(32+DTG)*16=10us;                (72Mhz)
                即:   13.89*(32+DTG)*16 =10000;
                DTG =12.99  ~  13;
                DTG[4:0]=13    对应16进制    D
                因为是第四区域 DTG[7:5]=111   对应16进制 E
                所以DTG = DTG[7:5]  +DTG[4:0] =0x0ED;
                即TIM_BDTRInitStructure.TIM_DeadTime =0x0ED;
        */
       
        TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;                        //刹车使能关闭
  TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;        //刹车输出极性,即刹车控制引脚PB12接GND时,PWM停止输出  
        /*  刹车控制引脚为TIM1_BKIN pin(PB.12),将PB12接GND,channel和其互补通道,都变为刹车后的电平,具体为0还是1,要看之前互补配置时 对下列2个参数的设置:
                        .TIM_OCIdleState = TIM_OCIdleState_Reset;   //刹车之后,PWM通道变为0
                        .TIM_OCNIdleState = TIM_OCNIdleState_Reset; //刹车之后,PWM互补通道变为0        
                        注意:如果没必要,还是不要开启刹车功能,因为会对PWM产生影响,特别是当PB12悬空时,波形将会有很大的波动。
                        这里不打开刹车功能,即.TIM_Break = TIM_Break_Disable;
        */  

        TIM_BDTRInitStructure.TIM_AutomaticOutput =TIM_AutomaticOutput_Enable;
        TIM_BDTRConfig(TIM1,&TIM_BDTRInitStructure);
       
        TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断

        /*开启PWM输出*/
        TIM_CtrlPWMOutputs(TIM1,ENABLE);        //PWM输出开启
        TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);  //CH1预装载使能
        TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);  //CH1预装载使能
        TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);  //CH1预装载使能
       
        TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器  影子寄存器 启用
       
       
        //中断优先级NVIC设置
        NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;  //TIM3中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能

        TIM_Cmd(TIM1,ENABLE);
       
       
       
       
        //         /* 时钟频率计算 */  
        //    TimerPeriod = (SystemCoreClock / 100000) - 1;   
        //    /*  计算相位差*/  
        //    Channel1Pulse= (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10);
        /* Compute CCR2 value to generate a duty cycle at 25%  for channel 2 */  
        //  Channel2Pulse = 604;// = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 100);
        /* Compute CCR3 value to generate a duty cycle at 12.5%  for channel 3 */  
        // Channel3Pulse = 1108;// = (uint16_t) (((uint32_t) 125 * (TimerPeriod - 1)) / 1000);

}

//定时器1中断服务程序
void TIM1_IRQHandler(void)   //TIM1中断
{
        if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)  //检查TIM1更新中断发生与否
                {
                  TIM_ClearITPendingBit(TIM1, TIM_IT_Update  );  //清除TIMx更新中断标志
                        LED1=0;
                       
        if(Upflag==0)
  {
                 Upflag=1;
                 TIM_SetCompare1(TIM1,1600);
                 TIM_SetCompare2(TIM1,1384);
                 TIM_SetCompare3(TIM1,1168);
  }

  else if(Upflag==1)
  {
                 Upflag=0;                 
                 TIM_SetCompare1(TIM1,200);
                 TIM_SetCompare2(TIM1,416);
                 TIM_SetCompare3(TIM1,632);
  }       
               
                }
}

相关帖子

沙发
136297jia|  楼主 | 2015-10-30 10:55 | 只看该作者
进入不了定时器中断重新设置ccr的值,波形不对,求大神

使用特权

评论回复
板凳
阿南| | 2015-10-30 11:42 | 只看该作者
进入不了定时器中断,先查定时器是否产生计数,再检查定时中断是否打开,检查定时中断是否有置位溢出中断标志,中断向量表及中断服务程序是否正确等。

使用特权

评论回复
地板
136297jia|  楼主 | 2015-10-31 14:36 | 只看该作者
我想产生20Khz、死区时间2us、移相3us的PWM,定时器可以计数,出来波形不对,但已经打开了中断标志,但没进去,不知为什么,求解,麻烦大神看看代码有什么问题?

使用特权

评论回复
5
阿南| | 2015-11-2 09:03 | 只看该作者
是没进去,还是程序飞掉了?如果飞掉了,应该和中断向量表有关

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

13

帖子

0

粉丝