datasheet

STM32之定时器(实例)

2019-07-12来源: eefocus关键字:STM32  定时器  实例

PWM输出实例: 

PWM在电力电子技术中占据着重要的地位,被广泛地用在逆变电路之中。利用STM32定时器的PWM输出功能,可以直接获取PWM波。根据面积等效原理,利用规则采样法、查表法可以调制出SPWM波及各种调制PWM波形。 

这里实现的是输入占空比固定的PWM波形 

PS: 

通用定时器TIM3产生4路不同占空比的PWM波。(仅仅适合本实例)) 

TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50% 

TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5% 

TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25% 

TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%


main函数: 

int main(void) 

TIM3_PWM_Init(); 

while(1) 

{} 

}


main函数十分简单,调用 TIM3_PWM_Init()把TIM初始化成PWM输出模式后,内核就把所有的工作都交给TIM外设,完全有TIM来控制GPIO引脚输出PWM波.


定时器初始化: 

void TIM3_PWM_Init(void) 

TIM3_GPIO_Config(); 

TIM3_Mode_Config(); 

调用TIM3_GPIO_Config()作为TIM外设通道复用的GPIO引脚进行初始化,再调用TIM3_Mode_Config()对TIM外设进行初始化.


GPIO初始化: 

static void TIM3_GPIO_Config(void) 

GPIO_InitTypeDef GPIO_InitStructure; 

/使能TIM3时钟/ 

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); 

/使能GPIO引脚 4个通道 GPIOA_Pin6和Pin7 GPIOB_Pin0和Pin1/ 

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;

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

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/*都是一样的配置*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;

GPIO_Init(GPIOB, &GPIO_InitStructure);


使能了TIM3外设的时钟,并对TIM3通道相应的GPIO引脚作了相应的配置,使能GPIO时钟,分别是PA6、PA7、PB0和PB1。它们被配置为复用输出,翻转速率为50MHz。 

(关于TIM3通道的GPIO引脚映射可以在《STM32 数据手册》的引脚定义表找到,GPIO复用模式配置可从《STM32 参考手册》的GPIO章节找到) 

 这里写图片描述 

TIM引脚定义 

 这里写图片描述 

TIM模式配置


定时器3模式初始化: 

static void TIM3_Mode_Config(void) 

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 

TIM_OCInitTypeDef TIM_OCInitStructure;


//PWM 信号电平跳变值 

u16 CCR1_Val = 500;

u16 CCR2_Val = 375;

u16 CCR3_Val = 250;

u16 CCR4_Val = 125;


//这里为时基配置

TIM_TimeBaseStructure.TIM_Period = 999;

//当定时器从0计数到999,即为1000次,为一个定时周期

TIM_TimeBaseStructure.TIM_Prescaler = 0;

//配置TIMx_CLK预分频值

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

//设置时钟分频系数:不分频

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

//向上计数模式

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);


//

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

//配置为 PWM 模式 1

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;


TIM_OCInitStructure.TIM_Pulse = CCR1_Val;

//设置跳变值,当计数器计数到这个值时,电平发生跳变

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

//当定时器计数值小于 CCR1_Val 时为高电平

TIM_OC1Init(TIM3, &TIM_OCInitStructure); //使能通道 1

TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);

/* PWM1 Mode configuration: Channel2 */

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_Pulse = CCR2_Val;

//设置通道 2 的电平跳变值,输出另外一个占空比的 PWM

TIM_OC2Init(TIM3, &TIM_OCInitStructure); //使能通道 2

TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);

/* PWM1 Mode configuration: Channel3 */

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_Pulse = CCR3_Val;

//设置通道 3 的电平跳变值,输出另外一个占空比的 PWM

TIM_OC3Init(TIM3, &TIM_OCInitStructure); //使能通道 3

TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);

/* PWM1 Mode configuration: Channel4 */

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_Pulse = CCR4_Val;

//设置通道 4 的电平跳变值,输出另外一个占空比的 PWM

TIM_OC4Init(TIM3, &TIM_OCInitStructure); //使能通道 4

//装载捕获、比较寄存器

TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);

TIM_ARRPreloadConfig(TIM3, ENABLE);

// 使能 TIM3 重载寄存器 ARR


TIM_Cmd(TIM3, ENABLE); //使能定时器 3


这个配置可以分为3部分,分别为时基初始化,输出模式初始化和装载捕获、比较寄存器的数值。


时基初始化: 

使用了一个TIM_TimeBaseInitTypeDef类型的结构体。时基初始化,即配置基本定时器只具有的那部分功能


TIM_TimeBaseStructure.TIM_Period = 999; 

定时周期,实质就是存储到重载寄存器 TIMx——ARR的数值,脉冲计数器从0累加到这个值上溢或从这个值下溢。这个数值加1然后乘以时钟源周期就是实际定时周期。 

这里设置为999,所以定时周期为(999+1)*T,T为时钟源周期


TIM_TimeBaseStructure.TIM_Prescaler = 0; 

对定时器时钟TIMxCLK的预分频值,分频后作为脉冲计数器TIMx_CNT的驱动时钟,得到脉冲计数器的时钟频率为:f CK_CNT=f TIMx_CLK /(N+1),其中N为赋给本成员的是时钟分频值. 

这里设置为0,就是不对TIMxCLK分频,例如:已知AHB时钟频率为72MHz、TIMxCLK为72MHz,所以输出到脉冲计数器TIMx_CNT的时钟频率为 f CK_CNT =72MHz/1=72MHz。


TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 

时钟分频因子,这个TIM_ClockDivision和TIM_Prescaler分频是不一样的,TIM_Prescaler分频配置是对TIMx_CLK进行分频,分频后的时钟被输出到脉冲计数器TIMx_CNT,而TIM_ClockDivision虽然也是对TIMxCLK进行分频,但它分频后的时钟频率为f DTS,是被输出到定时器的ETRP数字滤波器部分,会影响滤波器的采样频率.TIM_ClockDivision可以被配置为1分频(f DTS = f TIMxCLK),2分频和四分频,ETRP数字滤波器的作用是对外部时钟TIMxETR进行滤波. 

这里只使用了内部时钟 TIMxCLK作为定时器时钟源,所以配置 TIM_ClockDivision为任何值都无影响.


TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 

脉冲计数器 TIMx_CNT的计数模式,分别有向上计数,向下计数,中央对齐模式. 

向上计数:TIMx_CNT从0向上累加到TIM_Period中的值(重载寄存器TIMx_ARR的值),产生上溢事件; 

向下计数:TIMxCNT 从TIM_Period的值累减至0,产生下溢事件; 

中央对齐模式:向上,向下计数的合体,TIMxCNT从0累加到TIM_Period的值减1时,产生一个上溢事件,然后向下计数到1时,产生一个计数器下溢事件,再从0开始重新计数,一直循环. 

这里是配置成 TIM_CounterMode_Up(向上计数模式)


填充完配置参数后,调用库函数TIM_TimeBaseInit()把这些控制参数写到寄存器中,定时器的时基配置就完成了。


输出模式配置: 

通用定时器的输出模式由 TIM_OCInitTypeDef类型结构体来配置.


TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; 

输出模式配置,主要使用的为PWM1和PWM2模式。 

PW1模式:在向上计数时,当TIMx_CNT小于(不知道为什么要用中文小于才能显示下面其他内容)TIMx_CCRn(比较寄存器,其数值等于TIM_Pulse成员的内容)时,通道n输出为有效电平,否则为无效电平,向下计数时,当TIMx_CNT>TIMx_CCRn时通道n为无效电平,否则为有效电平.PWM2模式和PWM1模式相反. 

(其中的有效电平好无效电平并不是固定对应高电平和低电平,也是需要配置的) 

这里使用了PWM1模式.


TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 

配置输出模式的状态或关闭输出. 

这里配置成TIM_OutputState_Enable(使能输出)


TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 

有效电平的极性,把PWM模式中的有效电平设置为高电平或低电平. 

这里是配置成TIM_OCPolarity_High(有效电平为高电平),因为在上面把输出模式配置为PWM1模式,向上计数,所以在TIMx_CNT小于TIMx_CCRn时,通过到n输出为高电平,否则为低电平.


TIM_OCInitStructure. = CCR1_Val; 

跳动,即为比较寄存器 TIMx_CCR的数值,当脉冲计数器 TIMx_CNT与 TIMx_CCR的比较结果发生变化时,输出脉冲将发生变化.


这里向1,2,3,4通道的TIM_Pulse分别赋值为500,375,250,125,定时器向上计数,PWM1模式,有效高电平为高,定时周期为1000(TIM_Period=999),所以当TIMx_CNT计数值小于 TIM_Pulse值时,输出高电平,否则为低电平,即各通道输出PWM的占空比为D=TIM_Pulse/(TIM_Period+1),即分别为 50%、37.5%、25%、12.5%。 

填充完输出模式初始化结构体后,要调用输出模式初始化函数TIM_OCxInit()对各个通道进行初始化(x表示定时器的通道).如TIM_OC1Init()是用来初始化定时器的通道1的,TIM_OC2Init()是用来初始化定时器的通道2的.


PS: 

调用各个通道初始化函数前,需要对初始化结构体的 TIM_Pulse重新赋值,因为这里的成员配置都一样,而占空比是不同的. 

最后使用了TIM_OCxPreloadConfig()配置了各通道的比较寄存器TIM_CCR 预装载使能,使用 TIM_ARRPreloadConfig()把重载寄存器 TIMx_ARR使能,最后用 TIM_Cmd()使能定时器 TIM3,定时器外设就开始工作了.


PS: 

总结以下定时器的配置: 

1,设定TIM信号周期; 

2,设定TIM预分频值(TIM_Prescaler); 

3,设定TIM分频系数(TIM_ClockDivision); 

4,设定TIM计数模式; 

5,根据TIM_TimeBaseInitStruct这个结构体里面的值初始化TIM; 

6,设定TIM的OC模式; 

7,TIM的输出使能; 

8,设定电平跳变值; 

9,设定PWM信号的极性;

[1] [2]

关键字:STM32  定时器  实例

编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic467514.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32实现蓝牙HC-06通信
下一篇:单片机入门学习十三 STM32单片机学习十 通用定时器

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32解决:st-link连接下载程序的问题

STM32解决:Error: Flash Download failed - "Cortex-M3"本人由于使用普中科技的stm32 的开发板的 USB的下载的地方坏了,所以不得不使用arm仿真器 st-link 进行下载。鼓捣了半天下面总结一下几个问题:1、st-link的驱动下载首先你插上st-link的时候,电脑的设备管理器这个地方是有感叹号的,说明还没有装好驱动,所以我就在网上找啊找。终于根据:win8【笔者没这个系统,无法测试,请大家测试后报告】:http://pan.baidu.com/s/1sjJQxZn(转载来自:https://blog.csdn.net/imxiangzi/article
发表于 2019-07-19
STM32解决:st-link连接下载程序的问题

解决stm32f103通过stlink不能烧录程序问题

问题:   stm32(stm32f103c8T6)开发板只能通过串口烧录程序,而st—link居然不行描述:解决:st-link固件升级用stm32cubemx快速开发时没有配置好调试模式重新生成代码就可以了如果还是不行的话,就得升级一下stlink固件了,具体升级方法可百度
发表于 2019-07-19
解决stm32f103通过stlink不能烧录程序问题

STM32下载不成功问题汇总

在某宝上买了五个最小系统核心板是STM32F103C8T6的芯片,刚拿到手准备下载程序调试,上电后板子自带LED闪烁,这是商家自己下载的示例程序,说明芯片工作着,用KEIL4进行下载自己程序,把自己编译好的程序下载。用的JLINK的四线下载调试下载口,SW的调试接口,点击下载后发现擦除成功,下载失败,提示:Load "..\Output\STM32-DEMO.axf" Set JLink Project File to "F:文件RFID程序电机USERJLinkSettings.ini"* JLink Info: Device "STM32
发表于 2019-07-19
STM32下载不成功问题汇总

STM32高级开发(11)-使用GDB调试你的工程

/scripts/target/stm32f4x_stlink.cfg在执行完此条指令后该终端就会一直执行OpenOCD的程序了,不要关闭它,我们再打开一个终端界面,进入我们的工程目录,比如我这里进入的就是我的libopencm3样例工程下的blink子工程目录。$ cd '/home/yangliu/workspace/libopencm3-my-example/blink'然后我们使用指令输入调试文件并打开GDB程序。$ arm-none-eabi-gdb blink.elf 然后我们在GDB的指令界面中,输入连接指令,连接本地的3333端口。(gdb)target remote localhost:3333此时
发表于 2019-07-19
STM32高级开发(11)-使用GDB调试你的工程

STM32F4标准外设库模板工程建立与使用

SW4STM32安装其实固件库安装过程很简单,在第一次新建工程时会提示选择使用Stdperiph 驱动还是Cube HAL,由于Stm32官方大力推行Cube HAL固件库,所以Cube HAL的固件库直接可以从网上直接一键下载安装。然而对于老的StdPeriph固件库不能一键式下载安装,会提示出错。所以,我们需要自己下载一个.zip固件包,放在C:UsersLYAppDataRoamingAc6SW4STM32firmwares文件夹下,其中的LY就是计算机的用户名。然后新建工程时在选择Stdperiph固件时会自动解压缩,这样就能使用该库进行编译了。界面如下所示:工程配置器件与时钟或者,修改晶振与时钟,根据注释可以算得
发表于 2019-07-19
STM32F4标准外设库模板工程建立与使用

基于STM32的外设的GPIO外设设置总结

1、背景外设驱动的寄存器设置对于外设功能正常运行异常重要。现在对GPIO的配置进行总结。2、GPIO的配置总结复用GPIO配置GPIO设置为输出或者是复用模式时,需要设置输出速度;而无论设置为什么模式,都要对GPIO的内部上下拉进行设置。注意:在输入模式(普通输入/模拟输入)下,OTYPE和OSPEED参数无效!!
发表于 2019-07-19
基于STM32的外设的GPIO外设设置总结

小广播

何立民专栏

单片机及嵌入式宝典

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

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