找回密码
 注册

QQ登录

只需一步,快速开始

搜索

c语言实现STM32F1多路相位、占空比可调PWM

[复制链接]
zloop 发表于 2020-1-5 23:55:28 | 显示全部楼层 |阅读模式
主要是用到定时器的主从模式,举例:T2的OC1 和T5的OC4输出相位、占空比可调的两路PWM

定时器T2作为主定时器  OC1输出10%的占空比,定时器T2 的OC2用来调整相位,暂定输出30%的占空比,并设置T2的OC2为输出触发信号。主要设置代码:        
        TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable);//主模式使能,TIMx->SMCR ---- MSM
        TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_OC2Ref);//主模式选择,TIMx->CR2  MMS

T5作为从定时器,任意选择一路PWM输出,并设置好占空比以OC4为例。并选择触发源,从模式选择复位模式,主要配置代码:
        TIM_SelectInputTrigger(TIM5,TIM_TS_ITR0);//触发选择,TIMx_SMCR --  TS
        TIM_SelectSlaveMode(TIM5,TIM_SlaveMode_Reset );//从模式选择 TIMx_SMCR --  SMS

通过T2的OC2就可以调整T2的OC1和T5的OC4之间的相位差。
image.png

  1. ////--------------  TIM2 -----------------------
  2. //APB1分频系数为2,APB1的时钟为36M,TIM2-7为其2倍=72M
  3. //Tout= ((arr+1)*(psc+1))/Tclk;
  4. //arr 自动装载值,PSC 时钟预分频数
  5. void Time2Init(u16 period,u16 psc)
  6. {
  7.                 TIM_TimeBaseInitTypeDef  TIMStruct;
  8.                 NVIC_InitTypeDef  NVIC_InitStruct;       
  9.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能

  10. //        //TIM2 初始化
  11.         TIMStruct.TIM_Period=period;//自动重载计数周期的值
  12.         TIMStruct.TIM_Prescaler=psc;//预分频值,T2频率=FclkSYS/psc
  13.         TIMStruct.TIM_ClockDivision=TIM_CKD_DIV1;//CDK时钟分频因子
  14.         TIMStruct.TIM_CounterMode=TIM_CounterMode_Up;//向上计数
  15.         TIM_TimeBaseInit(TIM2,&TIMStruct);//根据指定的参数初始化TIMx的时间基数单位
  16.                
  17. //        //中断优先级
  18.                 //更新中断中断TIM_IT_Update, 比较中断TIM_IT_CC
  19.         TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//允许更新中断
  20.         NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn;
  21.         NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级
  22.         NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;//从优先级
  23.         NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
  24.         NVIC_Init(&NVIC_InitStruct);
  25.        
  26.                 //----主从配置
  27.         TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable);//主模式使能,TIMx->SMCR ---- MSM
  28.         TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_OC2Ref);//主模式选择,TIMx->CR2  MMS
  29.        
  30.        
  31.         //使能
  32.         TIM_Cmd(TIM2,ENABLE);
  33.         TIMs2.Instense=TIM2;
  34. }
  35. //CCER->CCxP = 0; PWM模式1的情况下TIMx->CRRx= 0;为低电平。TIMx->CRRx = TIMx->ARR;为高电平,TIMx->CRRx越大,正占空比越大。
  36. //CCER->CCxP = 1; PWM模式1的情况下TIMx->CRRx= 0;为高电平。TIMx->CRRx >= TIMx->ARR;为低电平,TIMx->CRRx越大,正占空比越小。
  37. //CCER->CCxP = 0; PWM模式2的情况下TIMx->CRRx= 0;为高电平。TIMx->CRRx = TIMx->ARR;为低电平,TIMx->CRRx越大,正占空比越小。
  38. //CCER->CCxP = 1; PWM模式2的情况下TIMx->CRRx= 0;为低电平。TIMx->CRRx >= TIMx->ARR;为高电平,TIMx->CRRx越大,正占空比越大。
  39. void Time2PWMInit(void)
  40. {
  41.         GPIO_InitTypeDef GPIO_InitStructure;
  42.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  43.         TIM_OCInitTypeDef  TIM_OCInitStructure;
  44.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能TIMx外设
  45.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIOB外设时钟使能
  46.         //配置IO
  47.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; //TIM_CH1
  48.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用功能输出
  49.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  50.         GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIO
  51.         //通道1
  52.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //CH1 PWM2模式       
  53.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
  54.         TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
  55.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //OC1 低电平有效
  56.         TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;//设置空闲电平
  57.         TIM_OC1Init(TIM2, &TIM_OCInitStructure);  //根据指定的参数初始化外设TIMx
  58.         TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);   
  59.         TIM_SetCompare1(TIM2,100);
  60.         //通道2
  61.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //CH1 PWM2模式       
  62.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
  63.         TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
  64.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //OC1 低电平有效
  65.         TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;//设置空闲电平
  66.         TIM_OC2Init(TIM2, &TIM_OCInitStructure);  //根据指定的参数初始化外设TIMx
  67.         TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);   
  68.                 TIM_SetCompare2(TIM2,200);//初始值为0       
  69.        
  70.          TIM_ARRPreloadConfig(TIM2, ENABLE); //使能TIMx在ARR上的预装载寄存器

  71. }

  72. void Time5Init(u16 period,u16 psc)
  73. {
  74.                 TIM_TimeBaseInitTypeDef  TIMStruct;
  75.                 NVIC_InitTypeDef  NVIC_InitStruct;       
  76.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //时钟使能

  77. //        //TIM 初始化
  78.         TIMStruct.TIM_Period=period;//自动重载计数周期的值
  79.         TIMStruct.TIM_Prescaler=psc;//预分频值,T2频率=FclkSYS/psc
  80.         TIMStruct.TIM_ClockDivision=TIM_CKD_DIV1;//CDK时钟分频因子
  81.         TIMStruct.TIM_CounterMode=TIM_CounterMode_Up;//向上计数
  82.         TIM_TimeBaseInit(TIM5,&TIMStruct);//根据指定的参数初始化TIMx的时间基数单位
  83.                
  84. //        //中断优先级
  85.                 //更新中断中断TIM_IT_Update, 比较中断TIM_IT_CC
  86.         TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE);//允许更新中断
  87.         NVIC_InitStruct.NVIC_IRQChannel=TIM5_IRQn;
  88.         NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级
  89.         NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;//从优先级
  90.         NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
  91.         NVIC_Init(&NVIC_InitStruct);
  92.        
  93.                 //----主从配置
  94.         TIM_SelectInputTrigger(TIM5,TIM_TS_ITR0);//触发选择,TIMx_SMCR --  TS
  95.         TIM_SelectSlaveMode(TIM5,TIM_SlaveMode_Reset );//从模式选择 TIMx_SMCR --  SMS
  96.        
  97.         //使能
  98.         TIM_Cmd(TIM5,ENABLE);
  99.         TIMs5.Instense=TIM5;
  100. }
  101. void Time5PWMInit(void)
  102. {
  103.         GPIO_InitTypeDef GPIO_InitStructure;
  104.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  105.         TIM_OCInitTypeDef  TIM_OCInitStructure;
  106.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //使能TIMx外设
  107.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIOB外设时钟使能
  108.         //配置IO
  109.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //TIM_CH4
  110.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用功能输出
  111.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  112.         GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIO
  113.         //通道1

  114.         //通道4
  115.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //CH1 PWM2模式       
  116.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
  117.         TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
  118.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //OC1 低电平有效
  119.         TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;//设置空闲电平
  120.         TIM_OC4Init(TIM5, &TIM_OCInitStructure);  //根据指定的参数初始化外设TIMx
  121.         TIM_OC4PreloadConfig(TIM5, TIM_OCPreload_Enable);   
  122.                 TIM_SetCompare4(TIM5,100);//初始值为0       
  123.        
  124.          TIM_ARRPreloadConfig(TIM5, ENABLE); //使能TIMx在ARR上的预装载寄存器

  125. }
复制代码


gkjswuser 发表于 2021-4-12 23:15:29 | 显示全部楼层
请问TIMs2和 TIMs5是什么呀?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|ELEOK |网站地图

GMT+8, 2024-11-23 03:15

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表