zoukankan      html  css  js  c++  java
  • STM32高级定时器TIM1产生两路互补的PWM波(带死区)

    测试环境:Keil 5.20.0.0 STM32F103RBT6 固件库版本:STM32F10x_StdPeriph_Lib_V3.5.0(2011)

    本文使用TIM1的通道1,通道2,产生两路1khz,死区时间1us的互补PWM波。

    所使用的IO口:由下图知,我们使用引脚为PA9,PA10,互补输出使用PB14,PB15

    部分代码如下:

     1 /* 配置TIM1复用输出PWM时用到的I/O  */
     2 static void TIM1_GPIO_Config(void) 
     3 {
     4   GPIO_InitTypeDef GPIO_InitStructure;
     5 
     6   /* TIM1 clock enable */
     7   RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
     8 
     9   /* GPIOA and GPIOB clock enable */
    10   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
    11     
    12   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9 | GPIO_Pin_10;
    13   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    14   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    15 
    16   GPIO_Init(GPIOA, &GPIO_InitStructure);
    17 
    18   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_14 | GPIO_Pin_15;
    19   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    20   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    21 
    22   GPIO_Init(GPIOB, &GPIO_InitStructure);
    23 
    24 }
    初始化IO

     初始化定时器功能配置

     1 u16 CCR2_Val = 500;
     2 u16 CCR3_Val = 500;//占空比,周期为1000
     3 
     4 /*配置TIM1输出的PWM信号的模式,如周期、极性、占空比 */
     5 void TIM1_Mode_Config(void)
     6 {
     7     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
     8     TIM_BDTRInitTypeDef      TIM1_BDTRInitStruct;
     9     TIM_OCInitTypeDef        TIM_OCInitStructure;
    10 
    11     /* Time base configuration */
    12     TIM_TimeBaseStructure.TIM_Period = 1000-1; //计数周期,向上记到此数,计数值清零
    13     TIM_TimeBaseStructure.TIM_Prescaler = 72-1;//定时器分频系数,Ftimer = 72M/(TIM_Prescaler+1) = 1ms
    14     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//与死区时间分频有关
    15     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
    16     TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
    17     
    18     /****** 配置BDTR寄存器,配置死区时间****************/
    19     /*
    20        定时器时钟 72M   TIM_ClockDivision = TIM_CKD_DIV1时,  Tdts = 13.89ns
    21        0 - 1.764us  用算法一
    22        1.778us - 3.505us  用算法二
    23        3.556us - 7.000us  用算法三 
    24        7.1117us - 14us    用算法四
    25        需要更长时间,使用TIM_ClockDivision分频
    26     */
    27     TIM1_BDTRInitStruct.TIM_OSSRState = TIM_OSSRState_Disable;
    28     TIM1_BDTRInitStruct.TIM_OSSIState = TIM_OSSIState_Disable;
    29     TIM1_BDTRInitStruct.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
    30     TIM1_BDTRInitStruct.TIM_DeadTime = 205; //死区时间  72:1us 172:3us 205:5us
    31     TIM_BDTRConfig(TIM1,&TIM1_BDTRInitStruct);
    32  
    33 //    TIM1->BDTR |= 72;   //设置死区  注:上面那种方法也可以,这种快且简单
    34     
    35      /* PWM1 Mode configuration: Channel2 */
    36      TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;//PWM2模式
    37      TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    38      TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;//比较互补输出使能
    39      TIM_OCInitStructure.TIM_Pulse = CCR2_Val;   //比较值,即占空比
    40      TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //输出极性
    41      TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;//互补输出极性
    42      TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;//指定空闲状态下的TIM输出比较的引脚状态。
    43      TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;//指定空闲状态下的TIM互补输出比较的引脚状态。
    44      TIM_OC2Init(TIM1, &TIM_OCInitStructure);   //初始化通道二比较输出
    45      TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);      //配置通道二,自动重装载使能
    46 
    47 
    48     /* PWM1 Mode configuration: Channel3 */
    49     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
    50     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    51     TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
    52     TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
    53     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    54     TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
    55     TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
    56     TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;      
    57     TIM_OC3Init(TIM1, &TIM_OCInitStructure);
    58     TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);    
    59 
    60     TIM_ARRPreloadConfig(TIM1, ENABLE);//重载装载值 ENABLE 立即生效,DISABLE 下一个比较周期生效
    61 
    62     /* TIM1 enable counter */
    63     TIM_Cmd(TIM1, ENABLE);//使能定时器1
    64     
    65     TIM_CtrlPWMOutputs(TIM1, ENABLE);//使能PWM外围输出    
    66 }
     1 int main(void)
     2 {
     3     TIM1_GPIO_Config();
     4     TIM1_Mode_Config();    
     5     while(1)
     6     {
     7          TIM1->CCR2 = CCR2_Val;
     8          TIM1->CCR3 = CCR3_Val;
     9          CCR2_Val+=5;
    10          CCR3_Val+=10;
    11          if(CCR2_Val>900)  CCR2_Val = 100;
    12          if(CCR3_Val>900)  CCR3_Val = 100;   
    13          Delay_mS(200);
    14     }
    15 }
    main函数

    关于死区时间计算:

     先贴几张关于TIM时钟的图:

    第一张图:关于死区时间分频因子。(代码见,初始化定时器功能配置代码部分第14行所示)

    第二张图:死区时间计算

           定时器1时钟挂在APB2总线上,时钟为72M   当TIM_ClockDivision = TIM_CKD_DIV1时,  Tdts = 1/72M = 13.89ns
           0 - 1.764us  用算法一
           1.778us - 3.505us  用算法二
           3.556us - 7.000us  用算法三
           7.1117us - 14us    用算法四
           需要更长时间,使用TIM_ClockDivision分频后(可2分,4分频),设置死区时间。

    测试数据:

    实验现象:产生了两路死区时间为1us的互补PWM信号,其频率都是1kHz,占空比在10% - 90%不断变化,通道三比通道二变化要快。

    死区时间(以通道二为例):(黄:PA10  绿:PB15)

      

    通道二抓拍波形  (黄:PA10  绿:PB15)

    通道三抓拍波形  (黄:PA9 绿:PB14)

    通道二和通道三  (黄:PA9  绿:PA10)

  • 相关阅读:
    C#中的编译为什么不叫Compile而叫build
    类型(Type)
    C#中关于值类型和引用类型的区别
    php通用化api格式输出
    tp6获取参数的五种办法
    PHP 数组------分割、合并
    explain结果中的type字段的含义
    order by 排序
    SQL开发技巧
    tp5模板输出日期时间
  • 原文地址:https://www.cnblogs.com/NickQ/p/8550901.html
Copyright © 2011-2022 走看看