使用STM32实现串口调节PWM周期和占空比

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、PWM是什么?
  • 1. PWM 图解
  • 二、认识STM32的PWM功能
  • 1.哪些定时器有PWM输出功能
  • 1.1 高级定时器,7路PWM输出,3组是互补输出,CH1与CH1N输出的波形相反,2*3=6;CH4是独立的1 6+1=7
  • 1.2通用定时器,4路独立输出
  • 2.STM32 PWM框图
  • 2.1高级定时器简介
  • 2.2高级定时器框图
  • 2.3高级定时器rcc时钟
  • 2.4 高级定时器时基
  • 2.5 PWM输出框图
  • 三、.配置PWM输出的步骤
  • 3.1 配置引脚
  • 3.2 配置PWM比较输出
  • 3.3 可以配置比较中断
  • 3.4高级定时器还有一个主使能输出
  • 四、参考程序
  • 五、实验测试
  • 六、串口控制PWM的周期和占空比
  • 6.1 思考如何改变周期和占空比
  • 6.2占空比的思考
  • 总结

  • 前言

    提示:这里可以添加本文要记录的大概内容:

    上次学习了STM32的基本定时器功能,它只是最基本的功能,STM32的功能非常强大,定时器还有输出功能,即PWM。


    提示:以下是本篇文章正文内容,下面案例可供参考

    一、PWM是什么?

    PWM是脉冲宽度调制,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。

    1. PWM 图解


    T1:为高电平时间
    T2:为低电平时间
    T1+T2-=T
    占空比为 = T/T *100%

    二、认识STM32的PWM功能

    1.哪些定时器有PWM输出功能

    1.1 高级定时器,7路PWM输出,3组是互补输出,CH1与CH1N输出的波形相反,2*3=6;CH4是独立的1 6+1=7

    1.2通用定时器,4路独立输出

    2.STM32 PWM框图

    2.1高级定时器简介

    2.2高级定时器框图


    1、2讲过了,重点在3

    2.3高级定时器rcc时钟

    1.RCC

    2.4 高级定时器时基

    2.5 PWM输出框图


    PWM输出与 周期和比较值的关系

    输出过程

    三、.配置PWM输出的步骤

    1. 配置引脚
    1. 配置时钟
    1. 配置时基(PWM的周期)
    1. 配置比较值,配置输出极性,使能输出
  • 3.1 配置引脚


    void timer1_gpio_init()
    {
    
        GPIO_InitTypeDef GPIO_InitStruct;
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    	
    	GPIO_InitStruct.GPIO_Pin=  GPIO_Pin_8;          //TX
    	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
    	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    	
    	GPIO_Init(GPIOA, &GPIO_InitStruct);   //&x
    }
    

    3.2 配置PWM比较输出

    配置输出


    void timer1(u16 period,u16 prescaler)
    {
          /*
    	
    	1.开启APB1时钟   72MHz
    	2.配置定时器6    TimeInit()  72预分配,0-65535     1000000us/50000us =CNT=20         定时时间/中断溢出时间=计数值
    	3.中断配置       分组,优先级 。开启中断源
    	4.中断服务函数   计数值, 1us  ,计数20次后让一个LED取反
    	*/
    	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    	TIM_OCInitTypeDef  TIM_OCInitStruct;
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
    	
    	//TIM_TimeBaseInitStruct.TIM_ClockDivision=
    	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
    	TIM_TimeBaseInitStruct.TIM_Period=period-1;//50000-1;
    	TIM_TimeBaseInitStruct.TIM_Prescaler=prescaler-1;// 72-1;
    	//TIM_TimeBaseInitStruct.TIM_RepetitionCounter=
    	
    	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStruct);
    	
    	 //TIM_OCInitStruct.TIM_OCIdleState=	 
    	// TIM_OCInitStruct.TIM_OCNIdleState=
    	  TIM_OCInitStruct.TIM_OCMode= TIM_OCMode_PWM1;
    	  TIM_OCInitStruct.TIM_OCPolarity= TIM_OCPolarity_High;
    	//  TIM_OCInitStruct.TIM_OCNPolarity=
    	//  TIM_OCInitStruct.TIM_OutputNState=
    	  TIM_OCInitStruct.TIM_OutputState= TIM_OutputState_Enable;
    	  TIM_OCInitStruct.TIM_Pulse= period/2; //百分之50占空比
    		 	
    	TIM_OC1Init(TIM1, &TIM_OCInitStruct);
    	
    	TIM_CtrlPWMOutputs(TIM1, ENABLE);
    	
    	
    	//开启中断:
    	TIM_ITConfig( TIM1, TIM_IT_CC1, ENABLE);
    	
    	TIM_Cmd( TIM1, ENABLE);      //使能
    	
    }
    

    3.3 可以配置比较中断

    TIM_ITConfig( TIM1, TIM_IT_CC1, ENABLE);
    

    3.4高级定时器还有一个主使能输出


    TIM_CtrlPWMOutputs(TIM1, ENABLE);
    

    四、参考程序

    void timer1_gpio_init()
    {
    
        GPIO_InitTypeDef GPIO_InitStruct;
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    	
    	GPIO_InitStruct.GPIO_Pin=  GPIO_Pin_8;          //TX
    	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
    	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    	
    	GPIO_Init(GPIOA, &GPIO_InitStruct);   //&x
    }
    
    
    void timer1(u16 period,u16 prescaler)
    {
          /*
    	
    	1.开启APB1时钟   72MHz
    	2.配置定时器6    TimeInit()  72预分配,0-65535     1000000us/50000us =CNT=20         定时时间/中断溢出时间=计数值
    	3.中断配置       分组,优先级 。开启中断源
    	4.中断服务函数   计数值, 1us  ,计数20次后让一个LED取反
    	*/
    	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    	TIM_OCInitTypeDef  TIM_OCInitStruct;
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
    	
    	//TIM_TimeBaseInitStruct.TIM_ClockDivision=
    	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
    	TIM_TimeBaseInitStruct.TIM_Period=period-1;//50000-1;
    	TIM_TimeBaseInitStruct.TIM_Prescaler=prescaler-1;// 72-1;
    	//TIM_TimeBaseInitStruct.TIM_RepetitionCounter=
    	
    	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStruct);
    	
    	 //TIM_OCInitStruct.TIM_OCIdleState=	 
    	// TIM_OCInitStruct.TIM_OCNIdleState=
    	  TIM_OCInitStruct.TIM_OCMode= TIM_OCMode_PWM1;
    	  TIM_OCInitStruct.TIM_OCPolarity= TIM_OCPolarity_High;
    	//  TIM_OCInitStruct.TIM_OCNPolarity=
    	//  TIM_OCInitStruct.TIM_OutputNState=
    	  TIM_OCInitStruct.TIM_OutputState= TIM_OutputState_Enable;
    	  TIM_OCInitStruct.TIM_Pulse= period/2; //百分之50占空比
    		 	
    	TIM_OC1Init(TIM1, &TIM_OCInitStruct);
    	
    	TIM_CtrlPWMOutputs(TIM1, ENABLE);
    	
    	
    	//开启中断:
    	TIM_ITConfig( TIM1, TIM_IT_CC1, ENABLE);
    	
    	TIM_Cmd( TIM1, ENABLE);      //使能
    	
    }
    

    五、实验测试

    六、串口控制PWM的周期和占空比

    6.1 思考如何改变周期和占空比


    周期->是由时基来决定的。
    时基->是由预分频和周期决定的
    RCC时钟也是关键,最高设置为了72MHz

    公式 1:72000000=分频系数*周期数

    分频系数的范围是 0-65535
    周期数的范围是:0-65535。
    所以公式1 将得到很多种可能,这正是STM32预分频的神奇之处


    之前定时1s实现,

    72000000 =72*(5000020)
    20是在定时器中断里面放变量自加的。现在配置PWM没有这个内容,根据大小值都不能超过65535的原则,将20分给预分频
    timer1(50000,72
    20);
    方法1:写一个函数 关联公式1


    6.2占空比的思考

    通过看图,占空比就是改变比较值,所以改变比较值就可以了

    TIM_SetCompare1(TIM1, i++);
    

    总结

    物联沃分享整理
    物联沃-IOTWORD物联网 » 使用STM32实现串口调节PWM周期和占空比

    发表评论