STM32学习笔记5:通用定时器PWM输出

发布者:Jinghua6666最新更新时间:2016-05-25 来源: eefocus关键字:STM32  通用定时器  PWM输出 手机看文章 扫描二维码
随时随地手机看文章
1.TIMER输出PWM基本概念

 

脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。一般用来控制步进电机的速度等等。

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

 

1.1PWM输出模式

STM32的PWM输出有两种模式,模式1和模式2,由TIMx_CCMRx寄存器中的OCxM位确定的(“110”为模式1,“111”为模式2)。模式1和模式2的区别如下:

110:PWM模式1-在向上计数时,一旦TIMx_CNTTIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。

111:PWM模式2-在向上计数时,一旦TIMx_CNTTIMx_CCR1时通道1为有效电平,否则为无效电平。

由此看来,模式1和模式2正好互补,互为相反,所以在运用起来差别也并不太大。

而从计数模式上来看,PWM也和TIMx在作定时器时一样,也有向上计数模式、向下计数模式和中心对齐模式,关于3种模式的具体资料,可以查看《STM32参考手册》的“14.3.9 PWM模式”一节,在此就不详细赘述了。

 

1.2PWM输出管脚

PWM的输出管脚是确定好的,具体的引脚功能可以查看《STM32参考手册》的“8.3.7定时器复用功能重映射”一节。在此需要强调的是,不同的TIMx有分配不同的引脚,但是考虑到管脚复用功能,STM32提出了一个重映像的概念,就是说通过设置某一些相关的寄存器,来使得在其他非原始指定的管脚上也能输出PWM。但是这些重映像的管脚也是由参考手册给出的。比如说TIM3的第2个通道,在没有重映像的时候,指定的管脚是PA.7,如果设置部分重映像之后,TIM3_CH2的输出就被映射到PB.5上了,如果设置了完全重映像的话,TIM3_CH2的输出就被映射到PC.7上了。

 

1.3PWM输出信号

PWM输出的是一个方波信号,信号的频率是由TIMx的时钟频率和TIMx_ARR预分频器所决定的,具体设置方法在前面一个学习笔记中有详细的交代。而输出信号的占空比则是由TIMx_CRRx寄存器确定的。其公式为“占空比=(TIMx_CRRx/TIMx_ARR)*100%”,因此,可以通过向CRR中填入适当的数来输出自己所需的频率和占空比的方波信号。

 

2.TIMER输出PWM实现步骤

1.设置RCC时钟;

2.设置GPIO时钟;

3.设置TIMx定时器的相关寄存器;

4.设置TIMx定时器的PWM相关寄存器。

 

第1步设置RCC时钟已经在前文中给出了详细的代码,在此就不再多说了。需要注意的是通用定时器TIMx是由APB1提供时钟,而GPIO则是由APB2提供时钟。注意,如果需要对PWM的输出进行重映像的话,还需要开启引脚复用时钟AFIO。

第2步设置GPIO时钟时,GPIO模式应该设置为复用推挽输出GPIO_Mode_AF_PP,如果需要引脚重映像的话,则需要用GPIO_PinRemapConfig()函数进行设置。

第3步设置TIMx定时器的相关寄存器时,和前一篇学习笔记一样,设置好相关的TIMx的时钟和技术模式等等。具体设置参看“TIMER基本定时功能”的学习笔记。

第4步设置PWM相关寄存器,首先要设置PWM模式(默认情况下PWM是冻结的),然后设置占空比(根据前面所述公式进行计算),再设置输出比较极性:当设置为High时,输出信号不反相,当设置为Low时,输出信号反相之后再输出。最重要是是要使能TIMx的输出状态和使能TIMx的PWM输出使能。

相关设置完成之后,就可以通过TIM_Cmd()来打开TIMx定时器,从而得到PWM输出了。

 

3.TIMER输出PWM源代码

由于我现在手上的奋斗开发板是将PB.5接到LED上,因此需要使用TIM3的CH2通道,并且要进行引脚重映像。打开TIM3之后,PWM输出,使得LED点亮,通过改变PWM_cfg()中的占空比可以调节LED的亮度。

 

#include "stm32f10x_lib.h"

 

void RCC_cfg();

void GPIO_cfg();

void TIMER_cfg();

void PWM_cfg();

//占空比,取值范围为0-100

int dutyfactor = 50;

 

int main()

{

 int Temp;

 RCC_cfg();

 GPIO_cfg();

 TIMER_cfg();

 PWM_cfg();

 

 //使能TIM3计时器,开始输出PWM

 TIM_Cmd(TIM3, ENABLE);

 

 while(1);

}

 

void RCC_cfg()

{

 //定义错误状态变量

 ErrorStatus HSEStartUpStatus;

 //将RCC寄存器重新设置为默认值

 RCC_DeInit();

 

 //打开外部高速时钟晶振

 RCC_HSEConfig(RCC_HSE_ON);

 

 //等待外部高速时钟晶振工作

 HSEStartUpStatus = RCC_WaitForHSEStartUp();

 if(HSEStartUpStatus == SUCCESS)

 {

 //设置AHB时钟(HCLK)为系统时钟

 RCC_HCLKConfig(RCC_SYSCLK_Div1);

 

 //设置高速AHB时钟(APB2)为HCLK时钟

 RCC_PCLK2Config(RCC_HCLK_Div1);

 

 //设置低速AHB时钟(APB1)为HCLK的2分频

 RCC_PCLK1Config(RCC_HCLK_Div2);

 //设置FLASH代码延时

 FLASH_SetLatency(FLASH_Latency_2);

 

 //使能预取指缓存

 FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

 

 //设置PLL时钟,为HSE的9倍频8MHz * 9 = 72MHz

 RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

 

 //使能PLL

 RCC_PLLCmd(ENABLE);

 

 //等待PLL准备就绪

 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

 

 //设置PLL为系统时钟源

 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

 

 //判断PLL是否是系统时钟

 while(RCC_GetSYSCLKSource() != 0x08);

 }

 

 //开启TIM3的时钟

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

 //开启GPIOB的时钟和复用功能

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE);

 

}

 

void GPIO_cfg()

{

 GPIO_InitTypeDef GPIO_InitStructure;

 

 //部分映射,将TIM3_CH2映射到PB5

// GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);

 GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);

 

 //选择引脚5

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

 //输出频率最大50MHz

 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

 //复用推挽输出

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

 

 GPIO_Init(GPIOB,&GPIO_InitStructure);

}

 

void TIMER_cfg()

{

 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

 

 //重新将Timer设置为缺省值

 TIM_DeInit(TIM3);

 //采用内部时钟给TIM3提供时钟源

 TIM_InternalClockConfig(TIM3);

 //预分频系数为0,即不进行预分频,此时TIMER的频率为72MHz

 TIM_TimeBaseStructure.TIM_Prescaler = 0;

 //设置时钟分割

 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

 //设置计数器模式为向上计数模式

 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

 //设置计数溢出大小,每计7200个数就产生一个更新事件,即PWM的输出频率为10kHz

 TIM_TimeBaseStructure.TIM_Period = 7200 - 1;

 //将配置应用到TIM3中

 TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);

}

 

void PWM_cfg()

{

 TIM_OCInitTypeDef TimOCInitStructure;

 //设置缺省值

 TIM_OCStructInit(&TimOCInitStructure);

 //PWM模式1输出

 TimOCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

 //设置占空比,占空比=(CCRx/ARR)*100%或(TIM_Pulse/TIM_Period)*100%

 TimOCInitStructure.TIM_Pulse = dutyfactor * 7200 / 100;

 //TIM输出比较极性高

 TimOCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

 //使能输出状态

 TimOCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

 //TIM3的CH2输出

 TIM_OC2Init(TIM3, &TimOCInitStructure);

 //设置TIM3的PWM输出为使能

 TIM_CtrlPWMOutputs(TIM3,ENABLE);

}

 
关键字:STM32  通用定时器  PWM输出 引用地址:STM32学习笔记5:通用定时器PWM输出

上一篇:STM32高级定时器、通用定时器TIMx、基本定时器TIM6和TIM7的区别
下一篇:STM32学习笔记time定时器

推荐阅读最新更新时间:2024-03-16 14:54

STM32_TIM定时-中断
今天讲解STM32F103定时器定时-中断功能,在昨天定时器延时的软件工程上添加TIM3定时的功能,自己也可以试着将昨天的工程添加修改得到。 今天的软件工程下载地址(360云盘): https://yunpan.cn/cPnJ9KYcXbPsP 访问密码 acd8 工程现象:间隔(定时器定时)500ms LED变化一次, 并且串口打印 STM32F103ZE有8个定时器(TIM1 – TIM8), 改工程以TIM3定时为例。 STM32F10x的资料可以在我360云盘下载: https://yunpan.cn/crBUdUGdYKam2 访问密码 ca90 关于TIM延时,我把重要的几点在下面分别讲述,工程中
[单片机]
STM32_TIM定时-中断
基于STM32和CAN总线的电动车电池管理系统设计
 随着电池能源的广泛应用,石油资源的枯竭和环境污染,电动汽车以其节能环保的优势引起越来越多的重视,在电动汽车的研究和发展上,车载电池及其管理系统的研究与制造占据着重要位置。电动汽车动力电池在应用中的主要问题表现在:生产过程中,电池的工艺,技术以及成组技术还不能保证其初始性能具有良好的一致性;使用过程中,对过充电、过放电、过温度、过电流等非常敏感,这类情况的发生会明显缩短电池寿命,甚至会导致电池报废。电池组是几十个甚至上百个单体电池串联,单体电池之间存在不一致性,随着连续的充放电循环,电池间的不一致性加剧,电池组的可用容量受容量最小的单体电池制约。对于这些情况,电池的初始性能必须要依靠企业生产工艺的优化,生产过程关键参数的控制来改善
[电源管理]
基于<font color='red'>STM32</font>和CAN总线的电动车电池管理系统设计
STM32串口输出乱码的原因
最近学习 STM32 开发,申请了一块免费的开发版,按照书上的内容学习,学到USART,发现串口输出始终乱码,妈蛋的,搞不懂为啥,代码啥的都是按照书上来的啊,最后搜索很久,发现是外部 时钟 频率配置错误导致的,库使用默认8MHz晶震,可以通过宏使用25MHz晶震。具体定义在stm32f10x.h文件中 这里提供了实用8MHz或者25MHz晶震,但是我2个都尝试了,还是乱码,最后一想,是不是我的开发版晶震不是这个值哦,最后拿着开发版一看,妈蛋的,果然不是,而是使用的12MHz晶震,立马自己定义一个宏修改成12000000,编译,烧写,一下就对了。坑啊! 怎么看自己的开发版晶震是多少,看图 然后修改上面的代码,加一个宏定义就
[单片机]
<font color='red'>STM32</font>串口<font color='red'>输出</font>乱码的原因
CM3(STM32) 内核复位与系统复位区别及应用
Ⅰ写在前面 某些系统允许复位,但对外设又有特殊要求:某一个IO状态不能因为复位而改变,某一个定时器计数器不能改变等。 例子:我一个A系统通过一个IO控制另一个B系统的电源,而这个IO置高时才开启B系统的电源。 正常工作过程中,B系统只有收到A系统关机命令任务才会进行关机(也就是说不能掉电关机),而A系统在工作过程中有复位的需求。 这个时候如果我使用常规的引脚复位,就会使IO置低,不符合要求,就需要使用到本文说到的内核复位。 Ⅱ关于复位 说到复位,我们都不会陌生,学习时,开发板上基本都有一个复位按键。 复位的种类有很多:上电复位、掉电复位、复位引脚复位、看门狗复位、软件复位等。 上面说的复位按键,也就是对应复位引脚复位;而本文说
[单片机]
STM32电机矢量控制】记录11——DMA传输
DMA传输: 原理:DMA 传输将数据从一个地址空间复制到另外一个地址空间。 DMA传输数据,但是不需要占用MCU,即在传输数据时,MCU可以做别的事,像多线程。数据传输从外设到存储器或者从存储器到存储器。DMA控制器包含了DMA1和DMA2,其中DMA1有7个通道,DMA2有5个通道,可以理解为传输数据的一种管道。要注意的是,DMA2只存在于大容量单片机中。 工作过程: 1.DMA请求 如果外设想通过DMA传输数据,必须先向DMA控制器发送DMA请求,DMA收到请求信号后,控制器会给外设一个应答信号,当外设应答且DMA控制器收到应答信号后,就会启动DMA传输,直到传输完毕。 DMA有DMA1和DMA2两个控制器,DMA1有两个
[单片机]
STM8S105系列单片机的PWM输出配置
STM8S105xx的定时器资源: (1)2个16位通用定时器(TIM2、TIM3),带有2+3个CAPCOM通道(IC、OC或PWM); (2)高级控制定时器(TIM1):16位,4个CAPCOM通道(捕获/比较通道),3个互补输出,死区插入和灵活的同步; (3)带有8位预分频器的8位基本定时器(TIM4); (4)自动唤醒定时器; (5)2个看门狗定时器:窗口看门狗和独立看门狗。 使用高级控制定时器和普通通用定时器的PWM输出功能在初始化配置上有差异,下面做简单分析: TIM1——16位高级控制定时器 带有16位预分频的16位递增、递减和双向自动重装载计数器 TIM2、TIM3——16位通
[单片机]
STM8S105系列单片机的<font color='red'>PWM</font><font color='red'>输出</font>配置
STM32上使用UCOSII--任务
一、UCOSII简介 UCOSII 是一个可以基于 ROM 运行的、可裁减的、抢占式、实时多任务内核,具有高度可 移植性,特别适合于微处理器和控制器,是和很多商业操作系统性能相当的实时操作系统 (RTOS)。为了提供最好的移植性能, UCOSII 最大程度上使用 ANSI C 语言进行开发,并且已经移植到近 40 多种处理器体系上,涵盖了从 8 位到 64 位各种 CPU(包括 DSP)。 UCOSII 是专门为计算机的嵌入式应用设计的, 绝大部分代码是用 C 语言编写的。 CPU 硬件相关部分是用汇编语言编写的、总量约 200 行的汇编语言部分被压缩到最低限度,为的是便于移植到任何一种其它的 CPU 上。用户只要有标准的 A
[单片机]
<font color='red'>STM32</font>上使用UCOSII--任务
stm32串口接收中断触发原理
如果在STM32微控制器的串口通信中,接收中断无法触发,可能有以下几个可能的原因: 1. 串口接收中断未使能:在初始化串口时,可能未正确使能接收中断。请确保在初始化代码中设置了正确的控制寄存器位来使能串口接收中断。例如,使用`USART_ITConfig()`函数或设置相应的寄存器位。 2. 中断优先级设置错误:如果其他中断具有更高的优先级,可能会导致串口接收中断无法触发。请确保正确配置了中断优先级,并确保串口接收中断的优先级高于其他中断。 3. 接收缓冲区溢出:如果接收缓冲区溢出,可能会导致串口接收中断无法触发。确保在接收中断处理函数中及时读取接收数据寄存器,以避免缓冲区溢出。 4. 硬件连接错误:检查串口接收引脚是否正确连接,
[单片机]
<font color='red'>stm32</font>串口接收中断触发原理
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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