• stm32f4xx-PWM输出


    一、STM32PWM工作过程

    PWM(pulse width modulation)脉冲宽度调制

    脉冲:方波,频率

    宽度:高电平的宽度,占空比

    占空比:0% 高电平一点都不占

    占空比:25% 占1/4

    占空比:50% 占1/2

    占空比:75% 占3/4

    占空比:100%

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    CCR1:捕获比较(值)寄存器(x=1,2,3,4):设置比较值。

    CCMR1: OC1M[2:0]位:对于PWM方式下,用于设置PWM模式1【110】或者PWM模式2【111】

    CCER:CC1P位:输入/捕获1输出极性。0:高电平有效,1:低电平有效。

    CCER:CC1E位:输入/捕获1输出使能。0:关闭,1:打开。

    二、库函数

    1、GPIO引脚映射

    在这里插入图片描述

    在这里插入图片描述

    2、定时器通道1配置

    在这里插入图片描述

    注意:

    通道1:TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);

    通道2:TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);

    通道3:TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);

    通道4:TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);

    3、定时器通道1比较值

    在这里插入图片描述

    注意:

    通道1:TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1);

    通道2:TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2);

    通道3:TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3);

    通道4:TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4);

    三、PWM1和PWM2模式

    在这里插入图片描述

    《STM32f4xx中文参考手册.pdf》477页

    1、定义

    PWM 模式 1——只要 TIMx_CNT(计数值)< TIMx_CCR1(捕获/比较值),通道 1 便为有效状态,否则为无效状态。

    PWM 模式 2——只要 TIMx_CNT (计数值)< TIMx_CCR1(捕获/比较值),通道 1 便为无效状态,否则为有效状态

    TIMx_CNT由TIM_TimeBaseStructure.TIM_Period决定

    TIMx_CCR1由TIM_SetComparex(x:1 2 3 4);函数决定

    有效状态由TIM_OCInitStructure.TIM_OCPolarity决定

    频率值:由计数值决定

    占空比:由比较值决定

    2、PWM输出配置步骤:

    在这里插入图片描述

    四、test

    呼吸灯
    注意:高级定时器 tim1要TIM_CtrlPWMOutputs()使能

    #include "stm32f4xx.h"
    //e 13  tim1_ch3 14  tim1_ch4
    void TIM1_UP_init(uint32_t arr,uint32_t psc)
    {
    #if 1
    	GPIO_InitTypeDef GPIO_InitStructure;
    	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    	TIM_OCInitTypeDef  TIM_OCInitStructure;
    	
    	//使能GPIOE的硬件时钟
    	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE , ENABLE);
    	//使能TIM1的硬件时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
    	
    	GPIO_PinAFConfig(GPIOE,GPIO_PinSource13,GPIO_AF_TIM1);//GPIOE 13 复用为定时器1
    	
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13  ;           //GPIOE 13 
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
    	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
    	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
    	GPIO_Init(GPIOE,&GPIO_InitStructure);              //初始化GPIOE 13 
    	
    	
    	
    	TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频
    	//TIM_TimeBaseStructure.TIM_Period = (10000/100)-1;	//计数值100hz/
    	//TIM_TimeBaseStructure.TIM_Prescaler = 16800-1;	//预分频值 16800-1 + 1 = 16800 
    	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
    	TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值
    	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
    	TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);//初始化定时器1
    	
    	
    	//初始化TIM1 Channel3    PWM模式	
    	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1
     	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    		TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
    	//TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //高电平有效状态,无效状态则为低电平
    	//TIM_OCInitStructure.TIM_Pulse = 250;			//比较值
    	
    	TIM_OC3Init(TIM1, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM1 OC1
    
    	TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);  //使能TIM1在CCR1上的预装载寄存器
        TIM_ARRPreloadConfig(TIM1,ENABLE);//ARPE使能 
    	TIM_CtrlPWMOutputs(TIM1, ENABLE);//tim1 pwm使能	---------------------------------
    	//使能定时器1工作
    	TIM_Cmd(TIM1, ENABLE);
    #else
    	//此部分需手动修改IO口设置
    	GPIO_InitTypeDef GPIO_InitStructure;
    	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    	TIM_OCInitTypeDef  TIM_OCInitStructure;
    	
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);  	//TIM14时钟使能    
    	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); 	//使能PORTF时钟	
    	
    	GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14); //GPIOF9复用为定时器14
    	
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;           //GPIOF9
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
    	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
    	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
    	GPIO_Init(GPIOF,&GPIO_InitStructure);              //初始化PF9
    	  
    	TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频
    	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
    	TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值
    	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
    	
    	TIM_TimeBaseInit(TIM14,&TIM_TimeBaseStructure);//初始化定时器14
    	
    	//初始化TIM14 Channel1 PWM模式	 
    	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
     	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
    	TIM_OC1Init(TIM14, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM1 4OC1
    
    	TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable);  //使能TIM14在CCR1上的预装载寄存器
     
      TIM_ARRPreloadConfig(TIM14,ENABLE);//ARPE使能 
    	
    	TIM_Cmd(TIM14, ENABLE);  //使能TIM14
    #endif
    }
    
    int main(void)
    {	
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
    #if 1
    	TIM1_UP_init(500-1,168-1);//168M/168=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz.   
    #else
    	TIM1_UP_init(500-1,84-1);//84M/84=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz.    
    #endif
    	uint32_t led0pwmval=0;    
    	uint8_t dir=1;
    	
    	while(1) //实现比较值从0-300递增,到300后从300-0递减,循环
    	{
     		delay_xms(10);	 
    		if(dir)led0pwmval++;//dir==1 led0pwmval递增
    		else led0pwmval--;	//dir==0 led0pwmval递减 
     		if(led0pwmval>300)dir=0;//led0pwmval到达300后,方向为递减
    		if(led0pwmval==0)dir=1;	//led0pwmval递减到0后,方向改为递增
    #if 1
    		TIM_SetCompare3(TIM1,led0pwmval);	//修改比较值,修改占空比
    #else 
    		TIM_SetCompare1(TIM14,led0pwmval);	//修改比较值,修改占空比
    #endif
    	}
    }
    
    • 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
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
  • 相关阅读:
    【计组】为什么计算机采用补码进行运算?
    C++ STL详解
    SpringCloud系列(14)--Eureka服务发现(Discovery)
    java小游戏-飞翔的小鸟
    寒假作业2月13号
    私域运营丨用户运营SOP,批量成交私域新老客户!
    armbian 安裝配置教程
    接口自动化测试的概述及流程梳理~
    信息学奥赛一本通:1310:【例2.2】车厢重组
    C语言进程的相关操作
  • 原文地址:https://blog.csdn.net/qq_45698138/article/details/126677744