一.PWM简介

  PWM是 Pulse Width Modulation 的缩写,中文意思就是脉冲宽度调 制,简称脉宽调制。它是利用微处理器的数字输出来对模拟电路进行控 制的一种非常有效的技术,其控制简单、灵活和动态响应好等优点而成 为电力电子技术最广泛应用的控制方式,其应用领域包括测量,通信, 功率控制与变换,电动机控制、伺服控制、调光、开关电源,甚至某些 音频放大器,因此学习PWM具有十分重要的现实意义。 其实我们也可以这样理解,PWM是一种对模拟信号电平进行数字编码 的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个 具体模拟信号的电平进行编码。PWM 信号仍然是数字的,因为在给定的 任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。电压 或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去 的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被 断开的时候。只要带宽足够,任何模拟值都可以使用 PWM 进行编码。

二.STM32F1 PWM介绍

  STM32F1除了基本定时器TIM6和TIM7,其他定时器都可以产生PWM输出 。其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出 。而通用定时器也能同时产生多达 4路的 PWM 输出,这些在定时器中断 章节中已经介绍过。 PWM的输出其实就是对外输出脉宽可调(即占空比调节)的方波信号 ,信号频率是由自动重装寄存器 ARR 的值决定,占空比由比较寄存器 CCR 的值决定。

  PWM输出比较模式总共有8种,具体由寄存器 CCMRx 的位 OCxM[2:0] 配置。我们这里只讲解最常用的两种PWM输出模式:PWM1和PWM2,其他几 种模式可以参考《STM32F10x中文参考手册》13、14、15定时器章节。

  PWM1和PWM2这两种模式用法差不多,区别之处就是输出电平的极性不 同。

  PWM模式根据计数器CNT计数方式,可分为边沿对齐模式和中心对齐模 式。

(1)PWM边沿对齐模式

  当 TIMx_CR1 寄存器中的 DIR 位为低时执行递增计数,计数器CNT从 0 计数到自动重载值(TIMx_ARR 寄存器的内容),然后重新从 0 开始 计数并生成计数器上溢事件。 以 PWM 模式 1 为例。只要TIMx_CNT < TIMx_CCRx, PWM 参考信号 OCxREF 便为有效的高电平,否则为无效的低电平。如果 TIMx_CCRx 中 的比较值小于自动重载值(TIMx_ARR 中),则 OCxREF 保持为“ 1”。 如果比较值为 0, 则 OCxREF 保持为“ 0”。

  当 TIMx_CR1 寄存器中的 DIR 位为高时执行递减计数,计数器CNT从 自动重载值(TIMx_ARR 寄存器的内容)递减计数到0,然后重新从 TIMx_ARR值开始计数并生成计数器下溢事件。 以 PWM 模式 1 为例。只要TIMx_CNT >TIMx_CCRx, PWM 参考信号 OCxREF 便为无效的低电平,否则为有效的高电平。如果 TIMx_CCRx 中 的比较值大于自动重载值(TIMx_ARR 中),则 OCxREF 保持为“ 1”。 此模式下不能产生0%的PWM波形。

(2)PWM中心对齐模式

  在中心对齐模式下,计数器 CNT 是工作做递增/递减模式下。开始的 时候, 计数器CNT 从 0 开始计数到自动重载值减 1(ARR-1),生成计数 器上溢事件;然后从自动重载值开始向下计数到 1 并生成计数器下溢事 件。之后从 0 开始重新计数。

  我们以ARR=8,CCRx=4为例进行介绍。第一阶段计数器CNT工作在递增 计数方式,从0开始计数,当TIMx_CNT < TIMx_CCRx时,PWM 参考信号 OCxREF为高电平,当TIMx_CNT >= TIMx_CCRx时,PWM 参考信号 OCxREF 为低电平。第二阶段计数器CNT工作在递减计数方式,从ARR开始递减计 数,当TIMx_CNT > TIMx_CCRx时,PWM 参考信号 OCxREF为低电平,当 TIMx_CNT <= TIMx_CCRx时,PWM 参考信号 OCxREF为高电平。

三.PWM输出配置步骤

(1)使能定时器及端口时钟,并设置引脚复用器映射 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE); 可选的参数在 stm32f10x_gpio.h 都已经列出来非常详细

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

(2)初始化定时器参数,包含自动重装值,分频系数,计数方式等

void TIM_TimeBaseInit(TIM_TypeDef*TIMx,TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);

(3)初始化PWM输出参数,包含PWM模式、输出极性,使能等

void TIM_OCxInit(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);

(4)开启定时器

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState); TIM_Cmd(TIM3,ENABLE); //开启定时器

(5)修改TIMx_CCRx的值控制占空比

void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1);

(6)使能TIMx在CCRx上的预装载寄存器 使能输出比较预装载库函数是:

void  TIM_OCxPreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);

第一个参数用于选择定时器,第二个参数用于选择使能还是失能输出比较预装载寄存器,可选择为TIM_OCPreload_Enable、TIM_OCPreload_Disable。

(7)使能 TIMx 在 ARR 上的预装载寄存器允许位 使能 TIMx 在 ARR 上的预装载寄存器允许位库函数是:

void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);  //第一个参数用于选择定时器,第二个参数用于选择使能还是失能。

  高级定时器要想输出PWM波形,必须要设置一个 MOE 位(TIMx_BDTR 的第 15 位),以使能主输出,否则不会输出 PWM。库函数设置的函数为:

   void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);

pwm.h
1 #ifndef _pwm_H
2 #define _pwm_H
3
4 #include "system.h"
5
6 void TIM3_CH1_PWM_Init(u16 per,u16 psc);
7
8 #endif

问题一:19行问什么要AFIO使能   27行改变管脚映射怎么回事

  27行改变管脚映射是对应第三步而言的,就是将定时器输出的管脚TIM_CH1即PA6管脚映射到PC6管脚输出(这里以TIM_CH1为例)

  而管脚映射需要用到AFIO这个外设里面寄存器的配置才能实现

问题二:24行为什么GPIOC使用复用推挽输出,为什么使用复用功能

  复用功能是接受其他外设所传递的数据(这里是复用的定时器结构图右下角所输出的数据)然后通过管脚输出

  总结:所比较的数据从TIM3_CH1口出来,经过AFIO外设内寄存器的配置将TIM3_CH1管脚即PA6管脚所映射到的PC6管脚上,经过PC6管脚的复用功能输出的模式将TIM3_CH1的数据输出

四、PWM代码

pwm.c
1 #include "pwm.h"
2
3 /*******************************************************************************
4 * 函 数 名 : TIM3_CH1_PWM_Init
5 * 函数功能 : TIM3通道1 PWM初始化函数
6 * 输 入 : per:重装载值
7 psc:分频系数
8 * 输 出 : 无
9 *******************************************************************************/
10 void TIM3_CH1_PWM_Init(u16 per,u16 psc)
11 {
12 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
13 TIM_OCInitTypeDef TIM_OCInitStructure;
14 GPIO_InitTypeDef GPIO_InitStructure;
15
16 /* 开启时钟 */
17 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
18 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
19 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //AFIO使能
20
21 /* 配置GPIO的模式和IO口 */
22 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
23 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
24 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
25 GPIO_Init(GPIOC,&GPIO_InitStructure);
26
27 GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);//改变指定管脚的映射
28
29 TIM_TimeBaseInitStructure.TIM_Period=per; //自动装载值
30 TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //分频系数
31 TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
32 TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数模式
33 TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
34
35 TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
36 TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
37 TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
38 TIM_OC1Init(TIM3,&TIM_OCInitStructure); //输出比较通道1初始化
39
40 TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable); //使能TIMx在 CCR1 上的预装载寄存器
41 TIM_ARRPreloadConfig(TIM3,ENABLE);//使能预装载寄存器
42
43 TIM_Cmd(TIM3,ENABLE); //使能定时器
44
45 }
 main.c
1 #include "system.h"
2 #include "SysTick.h"
3 #include "led.h"
4 #include "pwm.h"
5
6 int main()
7 {
8 u16 i=0;
9 u8 fx=0;
10 SysTick_Init(72);
11 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组 分2组
12 LED_Init();
13 TIM3_CH1_PWM_Init(500,72-1); //频率是2Kh
14
15 while(1)
16 {
17
18 if(fx==0)
19 {
20 i++;
21 if(i==300)
22 {
23 fx=1;
24 }
25 }
26 else
27 {
28 i--;
29 if(i==0)
30 {
31 fx=0;
32 }
33 }
34 TIM_SetCompare1(TIM3,i); //i值最大可以取499,因为ARR最大值是499.
35 delay_ms(10);
36 }
37 }

(stm32f103学习总结)—stm32 PMW输出实验的更多相关文章

  1. (stm32f103学习总结)—待机唤醒实验

    一.STM32待机模式介绍 1.1 STM32低功耗模式介绍 很多单片机具有低功耗模式,比如MSP430.STM8L等,我们的STM32 也不例外.默认情况下,系统复位或上电复位后,微控制器进入运行模 ...

  2. (stm32f103学习总结)—ADC模数转换实验

    一.STM32F1 ADC介绍 TM32F103 系列一般都有 3 个 ADC,这些 ADC 可以独立使用,也可 以使用双重(提高采样率).STM32F1 的 ADC 是 12 位逐次 逼近型的模拟数 ...

  3. MM32 备份域学习(兼容STM32)

    MM32 备份域学习(兼容STM32) 内容提要 备份域工作原理 备份域特性 备份域的保护:侵入检测 备份域侵入检测 备份域电源与主要内容 备份域特性 20字节数据后备寄存器(中容量和小容量产品),或 ...

  4. 第六周学习总结&第四次实验报告

    第六周学习总结&第四次实验报告 学习总结 这周我们简单的学习了一点点关于接口的内容,接口是Java中最重要的概念之一,接口可以理解为一个特殊的类, 里面由全局常量和公共的抽象方法组成,接口摆脱 ...

  5. MM32看门狗学习(兼容STM32)

    MM32看门狗学习(兼容STM32) IWDG独立看门狗 思维导图 IWDG框图与理解 1.独立看门狗分为两个部分,配置寄存器在1.8V供电区,计数器的核心部分在VDD供电区(即使停机/待机模式计数器 ...

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

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

  7. Redis学习笔记六:持久化实验(AOF,RDB)

    作者:Grey 原文地址:Redis学习笔记六:持久化实验(AOF,RDB) Redis几种持久化方案介绍和对比 AOF方式:https://blog.csdn.net/ctwctw/article/ ...

  8. stm32 PWM输出学习

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

  9. (stm32f103学习总结)—stm32定时器中断

    一.定时器介绍 STM32F1的定时器非常多,由2个基本定时器(TIM6.TIM7).4个通 用定时器(TIM2-TIM5)和2个高级定时器(TIM1.TIM8)组成.基本定 时器的功能最为简单,类似 ...

随机推荐

  1. Docker入坑系列(一)

    Docker入坑系列(一) 引用嘛,当然是来引用别人说的东西啦. Docker 是一个开源项目,诞生于 2013 年初,它基于 Google 公司推出的 Go 语言实现. 项目后来加入了 Linux ...

  2. java复习面向对象(二)

    java复习面向对象(二) 1.static关键字 举例图片 静态变量 使用static修饰的成员变量是静态变量 如果一个成员变量使用了关键字static,那么这个变量不属于对象自己,而属于所在的类多 ...

  3. 用Assert(断言)封装异常,让代码更优雅(附项目源码)

    有关Assert断言大家并不陌生,我们在做单元测试的时候,看业务事务复合预期,我们可以通过断言来校验,断言常用的方法如下: public class Assert { /** * 结果 = 预期 则正 ...

  4. CoLAKE: 如何实现非结构性语言和结构性知识表征的同步训练

    原创作者 | 疯狂的Max 论文CoLAKE: Contextualized Language and Knowledge Embedding 解读 01 背景与动机 随着预训练模型在NLP领域各大任 ...

  5. Lua中如何实现类似gdb的断点调试—08支持通过包名称添加断点

    在前一篇中我们支持了通过函数名称来添加断点,我们同时也提到了在Lua中一个函数的名称的并不是确定的.准确的说,Lua中的函数并没有名称,所谓名称其实是保存这个函数值的变量的名称. 于是通过函数名称添加 ...

  6. 配置DHCP Relay的功能原理是什么?

    DHCP中继代理,就是在DHCP服务器和客户端之间转发DHCP数据包.当DHCP客户端与服务器不在同一个子网上,就必须有DHCP中继代理来转发DHCP请求和应答消息.DHCP中继代理的数据转发,与通常 ...

  7. Unknown column ‘avatar_url‘ in ‘field list‘

    报错: Unknown column 'avatar_url' in 'field list' 解决: 查看mysql数据库中字段名前面是否有空格或则换行

  8. 前端好用API之Fullscreen

    前情 在前端开发需求中,特别网页有视频需求时,需要做视频全屏功能,或者在某些可视化大屏项目也要做全屏. Fullscreen介绍 让你可以简单地控制浏览器,使得一个元素与其子元素,如果存在的话,可以占 ...

  9. 内网渗透----Linux下信息收集

    基础信息 1.系统类型 cat /etc/issue查看系统名称 Lsb-release查看系统名称.版本号 2. 内核版本 uname –a 查看所有信息 ls /root |grep vmlinu ...

  10. 2022IDEA配置启动lilishop的swagger展示

    目录 一.概述 二.基本构建 三.Git 导入编译器 四.模块描述浅析 五.配置文档 1.注释配置文件 2.添加配置 3.暂时关闭权限 4.浏览器测试访问 5.其他需要修改模块 六.参考文献 结语 一 ...