STM32F103入门 | 12.PWM实现呼吸灯

发布者:MoonlightStar最新更新时间:2021-11-01 来源: eefocus关键字:STM32F103  PWM  呼吸灯 手机看文章 扫描二维码
随时随地手机看文章

12.1. PWM简介


PWM全称为“Pulse Width Modulation”。中文翻译为:脉冲宽度调制。脉冲宽度指的是 脉冲持续的时间,既高电平或低电平保持(持续)的时间。而PWM通俗的说就是人为的(通过微处理器)去控制电平高低保持的时间。这里引出一个新名词,占空比:在一个脉冲的循环中,通电时间相对于总时间所占的比例。


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



12.2. PWM相关寄存器


除了定时器章节介绍的几个寄存器( ARR、PSC、 CR1 等) 外,还会用到 4 个寄存器(通用定时器则只需要 3 个),来控制 PWM 的输出。这四个寄存器分别是:捕获/比较模式寄存器( TIMx_CCMR1/2)、捕获/比较使能寄存器( TIMx_CCER)、捕获/比较寄存器( TIMx_CCR1~4) 以及刹车和死区寄存器( TIMx_BDTR)。


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


该寄存器总共有 2 个, TIMx _CCMR1 和 TIMx _CCMR2。TIMx_CCMR1 控制 CH1 和 CH2,而 TIMx_CCMR2 控制 CH3 和 CH4。


寄存器分了 2 层,上面一层对应输出时的设置而下面的则对应输入时的设置。模式设置位 OCxM,此部分由 3 位组成。总共可以配置成 7 种模式,我们使用的是 PWM 模式,这 3 位必须设置为110/111。这两种 PWM 模式的区别就是输出电平的极性相反。 另外 CCxS 用于设置通道的方向(输入/输出)默认设置为 0,就是设置通道作为输出使用。


/**

  * 没有重映射时,TIM3的四个通道CH1, CH2, CH3, CH4分别对应PA6, PA7, PB0, PB1

  * 部分重映射时,TIM3的四个通道CH1, CH2, CH3, CH4分别对应PB4, PB5, PB0, PB1

  * 完全重映射时,TIM3的四个通道CH1, CH2, CH3, CH4分别对应PC6, PC7, PC8, PC9

  * 

  * 110:PWM模式1 - 在向上计数时,一旦TIMx_CNT  * 否则为无效电平;在向下计数时,一旦TIMx_CNT>TIMx_CRRx时,通道x为无效电平,

  * 否则为有效电平。

  *

  * 111:PWM模式2 - 在向上计数时,一旦TIMx_CNT  * 否则为有效电平;在向下计数时,一旦TIMx_CNT>TIMx_CRRx时,通道x为有效电平,

  * 否则为无效电平。

  */

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


这里只用到了 CC1E 位,该位是输入/捕获 1 输出使能位,要想PWM 从 IO 口输出,这个位必须设置为 1。


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


该寄存器总共有 4 个,对应 4 个输通道 CH1~CH4。在输出模式下,该寄存器的值与 CNT 的值比较,根据比较结果产生相应动作。利用这点,我们通过修改这个寄存器的值,就可以控制 PWM 的输出脉宽了。


(4)刹车和死区寄存器( TIMx_BDTR)


如果是通用定时器,则配置以上三个寄存器就够了,但是如果是高级定时器,则还需要配置:刹车和死区寄存器( TIMx_BDTR)。该寄存器,我们只需要关注最高位: MOE 位,要想高级定时器的 PWM 正常输出,则必须设置 MOE 位为 1,否则不会有输出。注意:通用定时器不需要配置这个。


12.3. PWM波形产生原理


通用定时器可以利用 GPIO 引脚进行脉冲输出,在配置为比较输出、PWM 输出功能时,捕获/比较寄存器 TIMx_CCR 被用作比较功能,下面把它简称为比较寄存器。


这里直接举例说明定时器的PWM输出工作过程:若配置脉冲计数器TIMx_CNT 为向上计数,而重载寄存器 TIMx_ARR 被配置为 N,即 TIMx_CNT 的当前计数值数值X在 TIMxCLK 时钟源的驱动下不断累加,当 TIMx_CNT 的数值X大于 N 时,会重置 TIMx_CNT 数值为 0 重新计数。


而在 TIMxCNT 计数的同时,TIMxCNT 的计数值X会与比较寄存器TIMx_CCR 预先存储了的数值 A 进行比较,当脉冲计数器 TIMx_CNT 的数值X小于比较寄存器 TIMx_CCR 的值A时,输出高电平(或低电平),相反地,当脉冲计数器的数值X大于或等于比较寄存器的值 A 时,输出低电平(或高电平)。


如此循环,得到的输出脉冲周期就为重载寄存器 TIMx_ARR 存储的数值 (N+1) 乘以触发脉冲的时钟周期,其脉冲宽度则为比较寄存器 TIMx_CCR 的值 A 乘以触发脉冲的时钟周期,即输出PWM的占空比为 A/(N+1) 。


12.4 PWM配置步骤


1.开启TIM3时钟、GPIOB时钟和复用功能时钟

2.配置GPIOB5为复用输出

3.设置TIM3_CH2重映射到PB5上

4.初始化TIM3,设置ARR和PSC

5.设置TIM3_CH2的PWM模式

6.使能TIM3的CH2输出

7.使能TIM3

8.在主函数中改变占空比完成呼吸灯


12.5 定时器引脚复用功能映射

根据以上重映像表,我们使用定时器3的通道2作为PWM的输出引脚,所以需要对PB5引脚进行配置。注意:如果使用PB4当做TIM3部分重映射的CH1输出,除了要进行部分重映射配置外,还需要禁用JTAG!并在开启复用时钟后禁用JTAG!


GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);  //禁用JTAG,在开启复用时钟后禁用


1. 新建两个文件,pwm.c 和 pwm.h

2. 在头文件 pwm.h 添加下面代码:


#ifndef _PWM_H

#define _PWM_H

#include "stm32f10x.h"

 

void PWM_Init(u16 arr, u16 psc);

 

#endif;

3. 把 pwm.c 添加到工程中

4. 在 pwm.c 中添加以下代码:


#include "pwm.h"

 

void PWM_Init(u16 arr,u16 psc)

{

    GPIO_InitTypeDef GPIO_InitStructure;              //定义GPIO结构体

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;    //定义TIMx定时器结构体

    TIM_OCInitTypeDef TIM_OCInitStructure;            //定义定时器脉宽调制结构体

    

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

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);//使能GPIOB时钟和AFIO复用时钟

    

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

    

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;                               //TIM_CH2

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

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;                       //配置输出速率

    GPIO_Init(GPIOB,&GPIO_InitStructure);                                   //初始化GPIOB

    

    TIM_TimeBaseStructure.TIM_Period = arr;                                 //设置自动重装载寄存器周期的值 arr=value-1

    TIM_TimeBaseStructure.TIM_Prescaler = psc;                              //设置预分频值 psc=value-1

    TIM_TimeBaseStructure.TIM_ClockDivision = 0;                            //设置时钟分割:TDTS = Tck_tim

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;             //TIM向上计数模式

    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);                          //初始化TIMx时间基数

    

    //初始化TIM3 Channel2 PWM模式     

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;                       //选择定时器模式:TIM脉冲宽度调制模式1

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;           //使能比较输出

    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;               //输出极性:TIM输出比较极性高

    TIM_OC2Init(TIM3,&TIM_OCInitStructure);                                 //根据T指定的参数初始化外设TIM3 OC2

 

    TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);                        //使能TIM3在CCR2上的预装载寄存器

    TIM_Cmd(TIM3, ENABLE);                                                  //使能TIM3

}

 

5. 实现PWM呼吸灯功能


#include "stm32f10x.h"

#include "delay.h"

#include "led.h"

#include "tim.h"

#include "key.h"

#include "pwm.h"

 

int main(void)

{

    u16 pwmValue = 0;

    u8 dir = 0;

 

    delay_init();

    PWM_Init(999, 719);

 

    while(1)

    {

        if(dir) {

            if(pwmValue > 550) TIM_SetCompare2(TIM3, --pwmValue);

            else dir = 0;

        }

        else {

            if(pwmValue < 990) TIM_SetCompare2(TIM3, ++pwmValue);

            else dir = 1;

        }

        delay_ms(3);

    }

}


小提示:如果身边没有LED电阻面包板搭电路,可以用杜邦线连接PB5和PC13,同时PC13设置成开漏输出(GPIO_Mode_Out_OD),这样就能完成呼吸灯实验了(不瞒你说我也是这样干的)。

关键字:STM32F103  PWM  呼吸灯 引用地址:STM32F103入门 | 12.PWM实现呼吸灯

上一篇:STM32F103 呼吸灯的实现
下一篇:stm32f103呼吸灯(PWM脉冲宽度调制)

推荐阅读最新更新时间:2024-11-13 10:56

stm32f103 低功耗调试笔记 低功耗模式下一直有个800多uA的电流
最新在做一个低功耗项目 ,用到stm32f103芯片,用到的stop模式和standby模式。 因 stop 只比 standby 模式多1-3uA,最终选用了 stop 模式。下面是官方文档中对几种模式的说明。 根据文档介绍,理论 stm32f103 standby 模式可低至2.1uA, stop 模式 3-5uA的样子。 但实在我们的项目中最终 无论是 stop 和是 standby 都有800uA的电流消不去。 最后把所有的引脚都设为模拟输入状态还是一样,经过一步一步分析,最终发现是在进入低功耗之前开启的ADC转换功能, 发现问题后 ,在时入低功耗之前关闭ADC转换使能即可,参考代码如下:
[单片机]
<font color='red'>stm32f103</font> 低功耗调试笔记 低功耗模式下一直有个800多uA的电流
STM32 六步PWM输出
之前说过STM32的只有两个高级定时器TIM1与TIM8才能互补输出。这里我们说的六步PWM输出要用到互补输出,所以只有TIM1与TIM8才能实现。什么是六步PWM输出?下面就来解释下。当一个定时器需要互补输出的时候,可以预先设置输出比较模式位OCxM(向TIM_OCMode_Timing,TIM_OCMode_PWM1等)、通道的使能位CCxE、互补通道的使能位CCxNE,然后当发生COM换相事件时,就可在中断函数中将刚预先设置位设置好,这样的话,就决定了下一步的配置了。这里之所以说是六步,其实并不是说一定要六步,你完全可以自己决定要设置几步配置,但是六步配置最为典型,所以我这里只讲六步配置。六步PWM输出非常适合控制机器人,因为
[单片机]
STM32F103标准库开发---Uart串口通信实验---初始化配置
一、Uart 串口通信 1. Uart 简介 UART 全称为Universal Asynchronous Receiver/Transmitter,即通用异步收发器 ,是一种通用串行数据总线,用于异步通信。 该总线双向通信,可以实现全双工数据发送和接收。 常用于单片机和电脑之间以及单片机和单片机之间的板级通信。 2. 接口连接方式 Uart 串口通信的数据由发送设备通过自身的TXD接口传输到接收设备的RXD接口,硬件连接比较简单,仅需要3条线。 具体连接图如下: 3. 传输方式 Uart 串口通信的数据由发送设备通过自身的TXD接口传输到接收设备的RXD接口, 一个字符一个字符地传输,每个字符一位一位地传输,并且传输
[单片机]
<font color='red'>STM32F103</font>标准库开发---Uart串口通信实验---初始化配置
51单片机+PWM控制渐变七彩灯C51程序
一、硬件介绍: (采用5050LED 2W) RGB三色LED控制引脚分别为单片机P1.2 、 P1.1 、 P1.0。LED正极接主电源(24V)正极,负极接驱动3颗三极管的集电极,单片机控制脚分别接3颗NPN三极管,三极管发射极接地,而单片机的供电是来自三端稳压器7805,祥细原理如下: 二、实物图片: 三、软件部分: 1、/*原理: 先亮红灯(保持一会儿)----红绿过度(绿加1、红减1循环240次)------ 绿灯亮起(保持一会儿)----绿兰过度(兰加1、绿减1循环240次) -----兰灯亮起(保持)-----兰白过度(绿加1、红加1循环240次、兰不变) ---白红过度,技术支持网站: http
[单片机]
STM32F103C8T6实现串口IAP方式升级固件
首先下载官方STM32F10X的IAP Bootloader源码,STM32F10x_AN2557_FW_V3.3.0。 源码包地址:http://download.csdn.net/download/yunyin_link/10151170 用Keil4打开工程代码STM32F10x_AN2557_FW_V3.3.0\Project\IAP\MDK-ARM\IAP.uvproj 第一步:因为我们是用的STM32F103C8T6 是64K Flash,所以特别重要的是修改Flash宏,如下图示,改为:STM32F10X_MD。 代码中对不同规格的Flash做了处理。 第二步:限定一下IAP Boot
[单片机]
<font color='red'>STM32F103</font>C8T6实现串口IAP方式升级固件
10、PIC系列-输出比较-PWM脉宽调制模式
1、PIC32参考资源 PIC32系列参考手册 中文版 链接地址:PIC32系列参考手册 第16章 输出比较 2、脉宽调制模式介绍 当控制位 OCM 2:0 (OCxCON 2:0 )被设置为 110 或 111 时,选定的输出比较通道被配置为 PWM (脉宽调制)工作模式。有以下两种 PWM 模式可供使用: • 不带故障保护输入的 PWM • 带故障保护输入的 PWM 第二种 PWM 模式需使用 OCFA 或 OCFB 故障输入引脚。在该模式下,OCFx 引脚上的异步逻辑电平 0 会使选定的 PWM 通道关闭。 在 PWM 模式下, OCxR 寄存器是只读从占空比寄存器, OCxRS 是缓冲寄存器,由用户写
[单片机]
10、PIC系列-输出比较-<font color='red'>PWM</font>脉宽调制模式
STM32F407入门开发: 配置定时器输出PWM方波
第一章 定时器PWM功能介绍 STM32F407的定时器的 TIM6 和 TIM7 是普通定时器,除此之外,其他的定时器都可以用来产生 PWM 输出。其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也能同时产生多达4路的PWM输出;在开发四轴无人机、机器人等需要控制大量电机的产品里运用起来非常方便。 第二章 PWM波形输出通道介绍 定时器3的硬件PWM通道:PA6 PA7 PB0 PB1 下面截图是介绍定时器3通道的复用IO口模式配置方式 第三章 配置PWM波形输出代码示例 3.1 在工程中增加pwm.c文件,写入以下代码 #include pwm.h
[单片机]
STM32F407入门开发: 配置定时器输出<font color='red'>PWM</font>方波
PWM在直流伺服系统中的应用研究
0 引言      伺服系统 是自动控制领域一种重要的 控制系统 ,随着科学技术的发展, 伺服系统 在现代工业、军事等领域发挥着日益重要的作用。 伺服 系统可以分为液压 伺服 系统、交流伺服系统、直流伺服系统等。液压伺服系统技术成熟,但存在漏油、易污染、难维护等缺点交流伺服系统性能虽已接近直流系统,但构成复杂,成本较高;PWM直流伺服系统则具有效率高、响应快、噪声小、调速范围宽等显著优点。随着电磁兼容技术的不断发展和解决,PWM直流伺服系统在工程中得到越来越多的重视和应用,本文提出并研究了一种基于直流PWM的速度伺服 控制系统 。 1 系统组成     1.1 PWM系统工作     PWM放大器的波形图如图1所示。若控制信号UC
[嵌入式]

推荐帖子

linux下Jflash 给 s3c2440外接的K9S1208 flash下载程序出错
#Jflash-s3c2410led_on/t=5+------------------------------------+|SECJTAGFLASH(SJF)v0.11+|modifiedbyMIZI2002.7.13++------------------------------------+flashType=5S3C2410X(ID=0x0032409d)isdetected.ERROR:K9S1208isnot
chyzh Linux与安卓
【设计工具】Virtex-5 设备的SEU策略
  单次事件的颠覆很可能形响到大多数的数宇电子电路。赛灵思很严肃地对待SEU问题,设计设备时充分考虑了如何降低对这些辐射引起的事件的敏感性。因为赛灵思也意识到SEU在商用和实用限制内是不可避免的,因此该公司在Virtex.-5和Spartan0-3A9伸系列产品中提供了内置的SEU检测功能,以简化并改咎系统设计。  KenChapman和LesJones编写的一条应用笔记中讨论了处理SEU的策略以及典型计算.重点讨论了解决这些低概率事件的可靠性。附带的参考设计经过优化后可用于Virt
GONGHCU FPGA/CPLD
DWDM基本原理介绍
DWDM基本原理介绍了DWDM技术是基本原理DWDM基本原理介绍
mdreamj 测试/测量
求以下模块原理图PT2272
求以下模块原理图PT2272PT2262和SC2262,PT2272应该是一样比较早的片子了本论坛有资料https://download.eeworld.com.cn/detail/nonogugu66/397035https://download.eeworld.com.cn/detail/%E9%9B%AA%E4%BA%BA001/49413
xueqian2560 RF/无线
LED电源驱动IC资料(隔离非隔离的)及小功率电源AC-DC芯片资料
本帖最后由NB88于2015-5-2815:37编辑 隔离型LED电源驱动芯片TW9022(最大5W)资料非隔离型LED电源驱动芯片TW9833D(最大24W)资料小功率AC-DC电源芯片TW112(最大12W,12V/1A、5V/2A常用)资料芯片方案技术需求交流,免费样品试用联系QQ:3095193848参考图参考图LED电源驱动IC资料(隔离非隔离的)及小功率电源AC-DC芯片资料都是多大功率的?qwqwqw2088发表于2015-5-280
NB88 电源技术
W77E58 TIME2做串口0的波特率发生器的时候的设置
第一次用W77E58单片机,想用time2来做串口0的波特率发生器,不知道怎么个设置,请大侠们指教,比如晶振是12MHZ,波特率为9600。W77E58TIME2做串口0的波特率发生器的时候的设置
guobin_lwh1258 51单片机
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved