• 【STM32 PWM输出+串口调整PWM周期和占空比】


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


    前言

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

    上次学习了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
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    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);      //使能
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    3.3 可以配置比较中断

    在这里插入图片描述

    TIM_ITConfig( TIM1, TIM_IT_CC1, ENABLE);
    
    • 1

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

    在这里插入图片描述
    在这里插入图片描述

    TIM_CtrlPWMOutputs(TIM1, ENABLE);
    
    • 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
    }
    
    
    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);      //使能
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    五、实验测试

    六、串口控制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++);
    
    • 1

    总结

  • 相关阅读:
    ​软考-高级-系统架构设计师教程(清华第2版)【第4章 信息安全技术基础知识(P160~189)-思维导图】​
    五子棋(c语言实现)
    【EI会议】2022年国际土木与海洋工程联合会议(JCCME 2022)
    数据结构与算法(Java)--栈和递归
    Vue:搭建前端项目
    TypeScript文件的编译执行
    数字化文化的守护之星:十八数藏的非遗创新之道
    dijkstra算法:堆优化 + 输出所有最短路径(得到所有最优解)
    vue3.0 新增组件
    【大数据存储技术】第4章&第5章 HBase 原理与使用
  • 原文地址:https://blog.csdn.net/ganhui13000/article/details/134254253