STM32 F1PWM输出STM32定时器配置·

STM32F103C8T6 TIM4 同时配置4路PWM输出

Hugh

Hugh

19815 0

前言

首先我们来了解一下PWM的概念,PWM(Pulse Width Modulation)即为脉冲宽度调制。放到我们这里,简单点说,就是利用单片机产生指定占空比和指定频率的方波。例如,单片机输出了一个高电平0.5s,低电平0.5s的方波。那么,这个方波的占空比为0.5/(0.5+0.5)=50%,高低电平各占一半,频率为周期(0.5s+0.5s)的倒数,即为1Hz。如果高电平为0.2s,低电平为0.8s则占空比为0.2/(0.2+0.8)=20%,其他情况依次类推。 以单片机STM32F103C8T6为例讲解PWM的产生,通过单片机的内部定时器,可以在IO口输出相应的PWM信号。该单片机有8个定时器,即TIM1-TIM8。其中,TIM1、TIM8为高级定时器,每个都可以产生多达7路PWM信号,从7个IO口同时输出。TIM2-TIM5为通用定时器,每个同时产生4路PWM信号。TIM6、TIM7为基本定时器无法产生PWM信号。 实现功能: 配置TIM4的4路PWM同时输出频率为1Hz的信号,其中:

  • 第一路(TIM4_CH1)占空比10%
  • 第二路(TIM4_CH2)占空比20%
  • 第三路(TIM4_CH3)占空比50%
  • 第四路(TIM4_CH4)占空比80%

第一步:确定TIM4的4路PWM输出对应的IO口

查看官方数据手册《STM32F103x8_B增强型系列中容量产品数据手册》,P20页,截图如下:

TIM4的PWM通道TIM4_CH1-TIM4_CH4对应GPIO依次为:PB6~PB9。

int main(void)
{
      TIM4_PWM_Init(7999,8999);//方波频率1Hz

      TIM_SetCompare1(TIM4, 800);//占空比10%
      TIM_SetCompare2(TIM4,1600);//占空比20%  
      TIM_SetCompare3(TIM4,4000);//占空比50%
      TIM_SetCompare4(TIM4,6400);//占空比80%
    
      while(1);//主循环     
}

第二步:方波频率计算--void TIM4_PWM_Init(u16 arr,u16 psc)

  • 1.定时器TIM4的输入时钟CLK为72MHz,决定了输出PWM的频率最高低于72MHz;
  • 2.CLK经过预分频计数器,进行了psc+1分频,输入时钟降为72MHz/(psc+1);
  • 3.分频之后,再计数(arr+1)次后才算完成一个周期的PWM输出,因此频率又降低了(arr+1)倍;
  • 4.PWM频率=72MHz/(psc+1)/(arr+1)
  • 5.根据参数72MHz/(7999+1)/(8999+1) = 1Hz.

第三步:占空比设置--void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);

  • 1.定时器TIM4的计数寄存器从0累加到arr循环,通过将计数寄存器的值N和Compare1进行比较;
  • 2.在一个周期内,N 小于Compare1时输出高,N大于Compare1输出低;(或者设置为相反)
  • 3.因此占空比:Compare1/(arr+1);
  • 4.依据参数,10%占空比Compare1=800,即10%=800/(7999+1),其他依次类推。
void TIM4_PWM_Init(u16 arr,u16 psc)
{ 
      GPIO_InitTypeDef GPIO_InitStructure;
      TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
      TIM_OCInitTypeDef TIM_OCInitStructure;

      //使能定时器TIM4时钟,注意TIM4时钟为APB1,而非APB2
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
      //使能PWM输出GPIO口时钟
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE); 
                                                                          
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//定时器TIM4的PWM输出通道1,TIM4_CH1
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;//定时器TIM4的PWM输出通道1,TIM4_CH2
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;//定时器TIM4的PWM输出通道3,TIM4_CH3
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//定时器TIM4的PWM输出通道2,TIM4_CH4
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO

      TIM_TimeBaseStructure.TIM_Period = arr;//自动重装值
      TIM_TimeBaseStructure.TIM_Prescaler =psc; //时钟预分频数
      TIM_TimeBaseStructure.TIM_ClockDivision = 0;
      TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上计数模式
      TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //初始化TIM4
     
      //初始化TIM4_CH1的PWM模式
      TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//设置PWM模式1
      TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//比较输出使能
      TIM_OCInitStructure.TIM_Pulse = 0; //
      TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//输出极性为高
      TIM_OC1Init(TIM4, &TIM_OCInitStructure);//初始化TIM4_CH1

      //初始化TIM4_CH2的PWM模式
      TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
      TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
      TIM_OCInitStructure.TIM_Pulse = 0;
      TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
       //TIM4_CH2初始化,注意为OC2,而不是OC1,下面两个通道依次类推。
      TIM_OC2Init(TIM4, &TIM_OCInitStructure);

       //初始化TIM4_CH3的PWM模式
      TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
      TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
      TIM_OCInitStructure.TIM_Pulse = 0;
      TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
      TIM_OC3Init(TIM4, &TIM_OCInitStructure);

      //初始化TIM4_CH4的PWM模式
      TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
      TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
      TIM_OCInitStructure.TIM_Pulse = 0;
      TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
      TIM_OC4Init(TIM4, &TIM_OCInitStructure);

      //使能4个通道的预装载寄存器
      TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);//OC1
      TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);//OC2
      TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);//OC3
      TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);//OC4
      TIM_ARRPreloadConfig(TIM4, ENABLE); //使能重装寄存器

      TIM_Cmd(TIM4, ENABLE);//使能定时器TIM4,准备工作 
}

所属系列

从当前文章继续阅读它所在合集中的前后内容。

STM32单片机 第 7 / 9 篇
查看合集

本专栏嵌入式C语言开发为基础,旨在深入解析32位单片机技术开发,掌握STM32单片机工作原理、开发流程,熟悉ARM Cortex-M3处理器架构。 订阅了本专栏您将可以收获的技能: 1.系统学习STM32单片机开发 2.掌握嵌入式C语言开发流程 3.ARM Cortex-M3处理器工作原理 4了解Thumb-2指令集 适宜人群: 1.所有想了解单片机开发的人 2.一线程序员、嵌入式产品设计师 3.片上系统(SOC)工程师 4.嵌入式系统发烧友、学院研究人员等 作为订阅福利,我们建立了微信技术交流群,大家在这里可以认识更多做朋友。需要的朋友加微信:「RYMCU交流1群」。欢迎关注微信公众号「rymcucom」,订阅最新内容。

相关文章

优先推荐同专题、同标签和同作者内容,补足热门文章。

评论 0

登录 后参与评论

评论

成为第一个评论的人