6、PWM

1、 PWM 是 Pulse Width Modulation 的缩写,中文意思就是脉冲宽度调制,简称脉宽调制。

它是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,其控制简单、灵活和动态响应好等优点而成为电力电子技术最广泛应用的控制方式,

其应用领域包括测量,通信,功率控制与变换,电动机控制、伺服控制、调光、开关电源,甚至某些音频放大器,因此研究基于 PWM 技术的正负脉宽数控调制信号发生器具有十分重要的现实意义。

2、PWM 是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用, 方波的占空比被调制用来对一个具体模拟信号的电平进行编码。

PWM 信号仍然是数字的, 因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。

电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。

通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用 PWM 进行编码。

3、STM32的定时器除了TIM6和7。其他的定时器都可以用来产生PWM输出。

其中高级定时器TIM1和TIM8可以同时产生多达7路的PWM输出。

而通用定时器也能同时产生多达4路的PWM输出,这样,STM32最多可以同时产生30路PWM输出!

4、STM32 的PWM是TIMx_ARR寄存器确定频率(周期)、由TIMx_CCRx寄存器确定占空比的信号

5、PWM  模式

脉冲宽度调制模式可以产生一个由 TIM1_ARR 寄存器确定频率、由TIM1_CCRx寄存器确定占空比的信号。在 TIM1_CCMRx寄存器中的OCxM位写入“110”(PWM 模式 1)或“111”(PWM 模式 2),

能够独立地设置每个通道工作在 PWM模式,每个 OCx 输出一路 PWM。必须通过设置 TIM1_CCMRx 寄存器 OCxPE 位使能相应的预装载寄存器,

最后还要设置 TIM1_CR1 寄存器的 ARPE 位使能自动重装载的预装载寄存器(在向上计数或中心对称模式中)。

(1)PWM 边沿对齐模式

a.  向上计数的配置

当 TIM1_CR1 寄存器中的 DIR 位为低的时候执行向上计数。   
                  在 PWM 模式 1,当 TIM1_CNT<TIM1_CCRx 时 PWM 参考信号,OCxREF 为高,否则为低。如果 TIM1_CCRx中的比较值大于自动重装载值(TIM1_ARR),则 OCxREF 保持为“1"。

如果比较值为 0,则 OCxREF 保持为“0"。

b. 向下计数的配置

当 TIM1_CR1 寄存器的 DIR 位为高时执行向下计数。
                 在 PWM 模式 1,当 TIM1_CNT>TIM1_CCRx 时参考信号 OCxREF 为低,否则为高。如果 TIM1_CCRx 中的比较值大于 TIM1_ARR 中的自动重装载值,则 OCxREF保持为“1"。

该模式下不能产生 0%的 PWM 波形。

(2)PWM 中央对齐模式

当TIM1_CR1寄存器中的CMS位不为 00时为中央对齐模式(所有其他的配置对OCxREF/OCx信号都有相同的作用)。

根据不同的CMS位的设置,比较标志可能 在计数器向上计数时被置 1、在计数器向下计数时被置 1、或在计数器向上和向下计数时被置 1。

TIM1_CR1寄存器中的计数方向位(DIR)由硬件更新,不要用软件修改它。

6、PWM初始化函数TIM_OCInit

7、复用功能映射函数GPIO_PinRemapConfig

8、示例代码:

  1 /*************************************************************************************************************************************
  2 *
  3 *  文件名称:main.c
  4 *  文件功能:主函数文件
  5 *
  6 ***************************************************************************************************************************************/
  7
  8 #include "pbdata.h"//调用自定义公共函数库
  9
 10
 11 /*********************************************************************************
 12 *
 13 * 初始化操作
 14 *
 15 *********************************************************************************/
 16 void RCC_Configuration(void);//系统时钟初始化函数声明
 17 void GPIO_Configuration(void);//GPIO初始化函数声明
 18 void TIM3_Configuration(void);//定时器中断配置函数声明
 19
 20
 21 /********************************************************************************
 22 *
 23 *  函数名称:main(void)
 24 *  函数功能:主函数
 25 *  函数说明:不能用void定义主函数
 26 *
 27 ********************************************************************************/
 28 int main(void)//void不能void定义主函数
 29 {
 30     u8 led_fx=1;
 31   u16 led_dt=0;
 32
 33     RCC_Configuration();    //系统时钟初始化
 34
 35     GPIO_Configuration();//端口初始化
 36
 37     TIM3_Configuration();//定时器T3配置
 38
 39   while(1)//主函数不做任何处理,等待进入中断函数
 40     {
 41         delay_ms(10);//每间隔10ms,改变值
 42      if(led_fx==1)
 43      {
 44          led_dt++;
 45      }
 46      else
 47      {
 48        led_dt--;
 49      }
 50
 51      if(led_dt>300)  led_fx=0;
 52         if(led_dt==0)     led_fx=1;
 53
 54      TIM_SetCompare2(TIM3,led_dt);//送入PWM
 55
 56     }
 57 }
 58
 59
 60
 61
 62 /********************************************************************************
 63 *
 64 *  函数名称:RCC_Configuration(void)
 65 *  函数功能:系统时钟高初始化函数
 66 *
 67 ********************************************************************************/
 68     void RCC_Configuration(void)//系统时钟高初始化函数
 69   {
 70
 71     SystemInit();//系统初始化
 72     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//对应GPIO时钟使能
 73         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//对应定时器T3时钟使能
 74         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//端口复用时钟使能
 75     }
 76
 77
 78
 79 /*******************************************************************************
 80 *
 81 * 函数名称:GPIO_Configuration(void)
 82 * 函数功能:GPIO初始化函数
 83 *
 84 ********************************************************************************/
 85
 86     void GPIO_Configuration(void)//GPIO初始化函数
 87   {
 88     GPIO_InitTypeDef GPIO_InitStructure;//定义一个GPIO设置的结构体变量
 89
 90 /*对LED引脚初始化*/
 91         /*结构体变量赋值*/
 92       GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;////引脚配置
 93       GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//配置频率
 94       GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//推挽输出,端口复用输出,用于PWM和推挽
 95          /*对应的GPIO初始化*/
 96       GPIO_Init(GPIOB,&GPIO_InitStructure);
 97
 98   }
 99
100
101 /*********************************************************************************
102 *
103 *  中断相关子函数部分
104 *
105 *********************************************************************************/
106
107
108 /**********************************************
109 *
110 *  函数名称:TIM3_Configuration(void)
111 *  函数功能:配置定时器
112 *
113 ***********************************************/
114 void TIM3_Configuration(void)
115 {
116     TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//定义一个结构体配置变量
117     TIM_OCInitTypeDef  TIM_OCInitStructure;
118
119     GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);//端口映射
120
121     TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//使用前清空标志位
122
123 /*定时器初始化*/
124   TIM_TimeBaseStructure.TIM_Period = 899;//初值:72MHZ,预分频设为0,分频后频率72Mhz,初值900,也就是以此计数(1/72000000)*900s
125   TIM_TimeBaseStructure.TIM_Prescaler = 0;//预分频,分频数-1;
126   TIM_TimeBaseStructure.TIM_ClockDivision = 0;//时钟
127   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//模式
128
129   TIM_TimeBaseInit(TIM3, & TIM_TimeBaseStructure);//初始化配置
130
131
132
133 /*PWM初始化*/
134     TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//PWM模式
135     TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//使能
136     TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;//输出极性,为低时发光二极管亮
137
138   TIM_OC2Init(TIM3,&TIM_OCInitStructure);//初始化执行
139
140
141     TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);//使能TIM3在PWM上的预装载寄存器
142
143
144     TIM_Cmd(TIM3,ENABLE);//打开定时器
145
146 }
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176     

/****************************************************************************************************************
*
* 文件名称:pbdata.c
* 文件功能:自定义函数或者全局变量的初始化
*
****************************************************************************************************************/

/*头文件声明*/
#include "pbdata.h"

/********************************************************************************************
*
* 自定义全局变量
*
********************************************************************************************/
u8 dt=0;

/******************************************************************************************
*
* 自定义函数
*
******************************************************************************************/

/**************************************************
*
*  函数名称:delay_us(u32 nus)
*  函数功能:微秒延时函数
*  输入参数:输入值为延时us
*
***************************************************/
void delay_us(u32 nus)
{
    u32 temp;
    SysTick->LOAD = 9*nus;//载入初值,72M/8=9M,也就是1/9us,9*1/9us,所以是执行9次
    SysTick->VAL=0X00;//清空计数器,清空后,就自动设置自己设定的计数器的值
    SysTick->CTRL=0X01;//使能,减到零动作(不发生中断),采用外部时钟

    do
    {
          temp=SysTick->CTRL;//标志位,等到一直减到0
         }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达

    SysTick->CTRL=0x00; //关闭计数器
    SysTick->VAL =0X00; //清空计数器
}

/***************************************************
*
* 函数名称:delay_ms(u16 nms)
* 函数功能:毫秒级延时
* 输入参数:输入值位延时ms
*
****************************************************/
void delay_ms(u16 nms)
{
    u32 temp;
    SysTick->LOAD = 9000*nms;//载入初值,72M/8=9M,也就是1/9us,9*1/9us,所以是执行9000次
    SysTick->VAL=0X00;//清空计数器,清空后,就自动设置自己设定的计数器的值
    SysTick->CTRL=0X01;//使能,减到零动作(不发生中断),采用外部时钟

    do
    {
          temp=SysTick->CTRL;//标志位,等到一直减到0
         }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达

    SysTick->CTRL=0x00; //关闭计数器
    SysTick->VAL =0X00; //清空计数器
}

 1 /*pbdata.h*/
 2 /***************************************************************************************************
 3 *
 4 * 文件名称:pbdata.h
 5 * 文件功能:自定义的函数和全局变量的声明头文件
 6 *
 7 ***************************************************************************************************/
 8
 9 #ifndef _pbdata_H
10 #define _pbdata_H
11
12 #include "stm32f10x.h"
13 #include "misc.h"
14 #include "stm32f10x_exti.h"
15 #include "stm32f10x_tim.h"
16
17
18
19 /********************************************************************
20 *
21 *  自定义全局变量声明
22 *
23 ********************************************************************/
24 extern u8 dt;
25
26
27
28
29
30 /********************************************************************
31 *
32 *  自定义全函数声明
33 *
34 ********************************************************************/
35 void delay(u32 nCount);
36 void delay_us(u32 nus);
37 void delay_ms(u16 nms);
38
39
40
41
42 #endif

9、工程下载:

http://download.csdn.net/detail/a1181803348/8741849

时间: 2024-10-31 14:45:03

6、PWM的相关文章

STM32F4——定时器原理及应用(中断、输入捕获、PWM输出)

一.简介: 不同的STM32系列有不同数量的定时器,针对现在学习的STM32F40x系列总共有14个定时器,针对这14个定时器可以将其分为3类,高级定时器.通用定时器和基本定时器,三种定时器大同小异,下边会针对通用定时器来介绍定时器的原理和应用.对于通用定时器根据位数和计数方式的不同又可以分为3类,相关分类的图表如下: 二.应用: 1.更新:计数器的上溢或下溢.2.事件触发.3.输入捕获.4.输出比较.5.支持针对定位的增量编码和霍尔传感器电路.5.触发输入作为外部时钟或按周期电源管理.下边会针

3、pwm 两通道输出制作呼吸灯(提供包含各种驱动的工程)

一个包含各种驱动的工程,main函数中用驱动函数实现功能 C:\Users\LiTao\Desktop\儿童智能硬件资料\my_workspace\pwm 改造实现了PWM两路输出 1 #include <stdbool.h> 2 #include <stdint.h> 3 #include "nrf_delay.h" 4 #include "nrf_gpio.h" 5 #include "boards.h" 6 #inc

5、CC2541芯片中级教程-OSAL操作系统(PWM+看门狗)

本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 中级教程-OSAL操作系统(OSAL系统解基本套路) 中级教程-OSAL操作系统(进一步了解-OLED && 普通按键和5方向按键-中断!!!)这个系统驱动层和应用层不一样~ 中级教程-OSAL操作系统(ADC-光敏电阻) OSAL操作系统-实验16 串口波特率扩展 OSAL操作系统-实验1

[nRF51822] 12、基础实验代码解析大全 &#183; 实验19 - PWM

一.PWM概述: PWM(Pulse Width Modulation):脉冲宽度调制技术,通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形. PWM 的几个基本概念: 1) 占空比:占空比是指在一个周期内,信号处于高电平的时间占整个信号周期的百分比,方波的占空比是50%. 2) 调制频率:周期的倒数. 3) 脉冲宽度:信号处于高电平的时间. 二.nRF51822的PWM产生: NRF51822 通过Timer.PPI 和GPIOTE 的配合实现PWM 的功能,由Timer 产生一个事件,

MSP432--TimerA (主要说明如何实现可调PWM)

---恢复内容开始--- 16位定时器 Timer_A 输出精密PWM 1.模式操作 Timer_A 支持     :多路捕获/比较 .PWM输出 . 定时        同时支持 :中断 Timer_A 特点: 异步16位具有四种模式的定时器/计数器               可选择.可配置的时钟资源               多达7个可配置的 捕获/比较 寄存器               具有配置PWM的功能               异步输入和输出自锁              

pwm驱动原理和代码实现

学这个pwm真是非常曲则,首先是看s3c2440的datasheet,全英文的,而且还有硬件的时序图(很多是硬件的工作原理,和软件控制不相关).看了很久加上网上看了资料才把这个pwm弄通.当然,其中牵扯到了几个知识,基本都弄通了.后面会通过blog一一列出来. 第一个知识点:I/O映射和内存映射所牵扯到的知识点,包括统一编址和独立编址,以及linux下怎么对这两种方式编程,以及这两种方式下怎么访问外设. 第二个知识点:映射到内存哪里?怎么映射?所以就涉及到linux内核的内存分布问题,顺便也分析

BeagleBone Black板第十课:测试PWM功能

BBB板第十课:测试PWM功能 上一节课我们初步学习了BBB板上ADC数据的读取方法,本节课将把学到的PWM的知识贡献给和我一样的初学者.以下这张彩图来自网上,详细标明了14个PWM和四个定时器的引脚位置.本实验中,我们只测试其中的P8_13引脚,名称为eHRPWM2B. 需要准备的实验工具:一个二极管发光管和数字万用表及其他小线材 一.PWM知识(部分知识直接摘自网上) PWM全称Pulse WidthModulation,脉冲宽度调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有

stm32之PWM

PWM是pulse width modulation的缩写,即脉冲宽度调制.其通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形: 1.PWM是一种对模拟信号电平进行数字编码的方法.通过高分辨率计数器的使用,方波的占空比被调制,用来对一个具体模拟信号的电平进行编码.等效的实现是基于采样定理中的一个重要结论:冲量相等而形状不同的窄脉冲加在具有惯性的环节上时,其效果基本相同.冲量即指窄脉冲的面接.这里所说的效果基本相同,是指该环节的输出响应波形基本相同. 2.如把各输出波形用傅立叶分析,则它们的

nRF51822使用Timer制作4路PWM波详解

Date:2015.5.8 Author:杨正  QQ:1209758756 <[email protected]> 一.            pwm简介 PWM英文名叫Pulse Width Modulation,中文名叫脉宽调制.那它到底是什么呢?其实它是由定时器产生的,比普通的定时器多了一个比较寄存器.PWM里面有一个词叫占空比,即一个周期内,高电平持续时间与周期的比值.如下图: 占空比(dutycycle) = t/T. PWM用途:控制电机调速,控制蜂鸣器播放音乐,控制led灯亮度