STM32 的定时器除了 TIM6 和 7,其他的定时器都可以用来产生 PWM 输出。其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。通用定时器也能同时产生多达 4路的 PWM 输出。

今天的实验,我们仅利用 TIM3的 CH2 通道产生一路 PWM 输出。

1.相关寄存器介绍

1)捕获/比较模式寄存器 (TIMx_CCMR1/2)

捕获/比较模式寄存器(TIMx_CCMR1/2),该寄存器总共有 2 个,TIMx  _CCMR1和 TIMx _CCMR2。TIMx_CCMR1 控制 CH1 和 CH2,而 TIMx_CCMR2 控制 CH3 和 CH4。

OCxx描述了通道在输出模式下的功能(上行),ICxx描述了通道在输出模式下的功能(下行)。因此必须注意,同一个位在输出模式和输入模式下的功能是不同的。

这里我们需要说明的是模式设置位 OCxM,此部分由 3 位组成。总共可以配置成 7 种模式,我们使用的是 PWM 模式,所以这 3 位必须设置为 110/111。这两种PWM 模式的区别就是输出电平的极性相反。

这里的有效电平或者无效电平是可以配置的。

2) 捕获/比较使能寄存器(TIMx_CCER)

3)捕获/比较寄存器(TIMx_CCR1~4)

该寄存器总共有 4 个,对应 4 个通道 CH1~CH4。因为这 4 个寄存器都差不多,我们仅以 TIMx_CCR1 为例介绍。

我们通过修改这个寄存器的值,就可以控制 PWM 的输出脉宽。

2. TIM3_REMAP 重映射

我们要利用 TIM3 的 CH2 输出 PWM 来控制 LED的亮度,但是 TIM3_CH2 默认是接在 PA7上面的,而我们的 LED接在 PB5 上面,如果是普通 MCU,可能就只能用飞线把 PA7 飞到 PB5上;不过,我们用的是 STM32,可以通过重映射功能,把 TIM3_CH2映射到 PB5 上。

3.代码难点分析

1)RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//使能TIM3时钟

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);  

//使能GPIOB时钟(PB5连接LED)和AFIO复用功能时钟

为什么要使能RCC_APB2Periph_AFIO呢?

参考手册上说:

对寄存器AFIO_EVCR(事件控制寄存器),AFIO_MAPR( 复用重映射和调试I/O配置寄存器),AFIO_EXTICRX(外部中断配置寄存器)进行读写操作前,应当首先打开AFIO的时钟。

因为我们在这个实验中用到了AFIO_MAPR,所以要打开AFIO时钟。

2)GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射,TIM3_CH2->PB5

3)GPIO配置

//设置该引脚为复用输出功能,输出TIM3-CH2的PWM波形

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; 

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //推挽复用输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, &GPIO_InitStructure);

4)TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

可以参考捕获/比较使能寄存器(TIMx_CCER)位0, 输出使能。

5)TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

可以参考捕获/比较使能寄存器(TIMx_CCER)位1, 高/低 电平有效。

6)TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); 预装载使能

可以参考捕获/比较模式寄存器 (TIMx_CCMR1/2) 位3.

7)TIM_SetCompare2(TIM3,300);

参考捕获/比较寄存器(TIMx_CCR1~4),这里设置比较值为300.

4. 代码参考

//PWM输出初始化函数
//arr:自动重装载值
//psc: 预分频系数
void TIM3_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能TIM3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
//使能GPIOB时钟(PB5连接LED)和AFIO复用功能时钟 GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射,TIM3_CH2->PB5 //设置该引脚为复用输出功能,输出TIM3-CH2的PWM波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化TIM3
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler = psc;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //TIM3 Channel2 PWM 初始化
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //PWM2模式
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //捕获/比较使能寄存器(TIMx_CCER) 输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //高电平有效
TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //预装载使能 TIM_Cmd(TIM3, ENABLE); //开启TIM3 }

main函数如下

int main(void)
{ TIM3_PWM_Init(999,71); //72/(71+1)=1MHz, T=1us*(999+1) = 1ms
TIM_SetCompare2(TIM3,300); //脉宽= 300/1000 *1ms = 0.3ms
while(1)
{
;
}
}

仿真说明:我们的代码设置为:

PWM2模式,向上计数,高电平有效。

所以,TIMx_CNT<TIMx_CCRx时通道x为低,否则为高。

5.仿真效果图如下

6. 疑问

如果调换main函数两句的顺序,则无法达到预期效果。

<span style="font-size:18px;">int main(void) //实验失败
{
TIM_SetCompare2(TIM3,300); //脉宽= 300/1000 *1ms = 0.3ms
TIM3_PWM_Init(999,71); //72/(71+1)=1MHz, T=1us*(999+1) = 1ms while(1)
{
;
}
}</span>

至于原因,这里不讨论,留待以后思考。

7. 用PWM控制LED的亮度

int main(void)
{
u16 led0pwmval = 0; //比较值
u8 dir = 1;
delay_init(); TIM3_PWM_Init(899,0); while(1)
{
delay_ms(10); if(dir)
led0pwmval++;
else
led0pwmval--; if(led0pwmval>300)
dir=0;
if(led0pwmval==0)
dir=1; TIM_SetCompare2(TIM3,led0pwmval);
}
}

这里,我们将 led0pwmval 这个值设置为 PWM 比较值,也就是通过 led0pwmval 来控制 PWM 的占空比,进而控制LED的平均电流,达到控制LED亮度的目的。

led0pwmval 的值从 0 变到 301,然后又从 301 变到 0,如此循环,LED的亮度也会跟着从暗变到亮,然后又从亮变到暗。至于这里的值,我们为什么取 300,是因为 PWM 的输出占空比达到并且超过这个值的时候, LED 亮度变化就不明显了。

stm32 PWM输出学习的更多相关文章

  1. STM32 PWM输出(映射)

    STM32 的定时器除了 TIM6 和 7.其他的定时器都可以用来产生 PWM 输出.其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出.而通用定时器也能同时产生多达 4 ...

  2. STM32 HAL库学习系列第4篇 定时器TIM----- 开始定时器与PWM输出配置

    基本流程: 1.配置定时器 2.开启定时器 3.动态改变pwm输出,改变值  HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); 函数总结: __HAL_TIM ...

  3. stm32寄存器版学习笔记05 PWM

    STM32除TIM6和TIM7外都可以产生PWM输出.高级定时器TIM1和TIM8可以同时产生7路PWM,通用定时器可以产生4路PWM输出. 1.TIM1 CH1输出PWM配置步骤 ①开启TIM1时钟 ...

  4. STM32(7)——通用定时器PWM输出

    1.TIMER输出PWM基本概念         脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种 ...

  5. Arduino学习经验(一)之解决舵机库和pwm输出冲突

    一.前言 最近在公司学习Arduino uno ,用它实现小车超声波避障功能.实现的功能很简单,就是在小车前方挂一个超声波模块,当碰到障碍物时,会通过舵机进行摆头,判断两边的距离,进行左右转弯.但是碰 ...

  6. STM32 PWM的输出与Keil软件仿真

    导读:PWM(Pulse Width Modulation)控制——脉冲宽度调制技术,通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形(含形状和幅值). PWM控制技术在逆变电路中应用最广,应用 ...

  7. STM32 精确输出PWM脉冲数控制电机(转)

    STM32 精确输出PWM脉冲数控制电机 发脉冲两种目的1)速度控制2)位置控制 速度控制目的和模拟量一样,没有什么需要关注的地方发送脉冲方式为PWM,速率稳定而且资源占用少 stm32位置控制需要获 ...

  8. STM32—TIMx输出PWM信号驱动MG996R舵机

    文章目录 一.前言 二.MG996R舵机简介 三.TIM定时器简介 四.通用定时器TIMx 1.TIMx主要功能 2.TIMx框图 3.计数单元 4.时钟选择 5.输出比较PWM 五.TIM3输出双路 ...

  9. (stm32f103学习总结)—stm32 PMW输出实验

    一.PWM简介 PWM是 Pulse Width Modulation 的缩写,中文意思就是脉冲宽度调 制,简称脉宽调制.它是利用微处理器的数字输出来对模拟电路进行控 制的一种非常有效的技术,其控制简 ...

随机推荐

  1. 2013蓝桥杯JavaA组T10 大臣的旅费(树的直径)

    大臣的旅费   时间限制:1.0s   内存限制:256.0MB 问题描述 很久以前,T王国空前繁荣.为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市. 为节省经费,T国的大 ...

  2. 【Arcgis for android】spatialite打开shapefile

    互联网(free and share) 本文参考下面的博文: http://blog.csdn.net/arcgis_all/article/details/8232976 Preparation: ...

  3. CentOS6.5上Zabbix3.0的RPM安装【四】-乱码

    当Agent添加完成后,部分显示(如cpu负载)出现乱码情况: 解决步骤如下: 1, 在windows7中找一个自己喜欢的字体或者去网上下载一个字体.[以“楷体 常规”为例] 2, 右击”楷体 常规” ...

  4. server12装.NET 3.5

    参考:https://support.microsoft.com/en-us/help/2734782/net-framework-3-5-installation-error-0x800f0906- ...

  5. java读取 500M 以上文件,java读取大文件

    java 读取txt,java读取大文件 设置缓存大小BUFFER_SIZE ,Config.tempdatafile是文件地址 来源博客http://yijianfengvip.blog.163.c ...

  6. srs录制视频时间戳有点问题

    srs2或者srs3目前最新的版本和之前的版本,使用dvr功能录制flv文件.使用本地播放器,如ffplay.potplayer.vlc.KMP和MPV等,都是正常的播放完整视频.但是使用web fl ...

  7. EA888发动机系列

    EA888发动机是一个发动机系列,有很多型号,比如从二代机开始,二代机叫做Evolution 2,简称EVO2,分别有CEA:1.8T 横置:CCU:1.8T 纵置:CGM:2.0T横置,CRH:2. ...

  8. webpack基础理解以及使用搭建

    1.webpack 是一个前端资源加载/打包工具,前端的常用资源都可以作为一个模板导出,我们在代码中直接引用即可,最后把我们的代码打包整合起来. 前端资源,包括(js,css,图片,模块)等. 下面是 ...

  9. 2015苏州大学ACM-ICPC集训队选拔赛(2) 1001 1003 1010

    草爷要的榜 Problem Description 苏州大学代表队又勤奋地开始了训练.今天开了一场时长5小时的组队训练赛,苏州大学的n(1<=n<=100)支校队奋力拼(hua)搏(shu ...

  10. poj1064 Cable master(二分)

    Cable master 求电缆的最大长度(二分法)   Description Inhabitants of the Wonderland have decided to hold a region ...