STM32自学笔记——定时器及PWM输出

发布者:Qingfang最新更新时间:2020-06-16 来源: eefocus关键字:STM32吗  定时器  PWM输出 手机看文章 扫描二维码
随时随地手机看文章

最基本的定时中断功能

1) TIM3 时钟使能。


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


2) 初始化定时器参数


voidTIM_TimeBaseInit(TIM_TypeDef*TIMx,

TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);


第一个参数是确定是哪个定时器,这个比较容易理解。 第二个参数是定时器初始化参数结构体指针,结构体类型为 TIM_TimeBaseInitTypeDef,下面我们看看这个结构体的定义:


typedef struct

{

uint16_t TIM_Prescaler;

uint16_t TIM_CounterMode;

uint16_t TIM_Period;

uint16_t TIM_ClockDivision;

} TIM_TimeBaseInitTypeDef;


①TIM_Period 设置了在下一个更新事件装入活动的自动重装载寄存器周期的值。它的取值必须在 0x0000 和0xFFFF 之间。


②TIM_Prescaler 设置了用来作为 TIMx 时钟频率除数的预分频值。它的取值必须在 0x0000 和 0xFFFF 之间。


③TIM_ClockDivision 设置了时钟分割。该参数取值见下表。

TIM_CKD_DIV1 TDTS = Tck_tim

TIM_CKD_DIV2 TDTS = 2Tck_tim

TIM_CKD_DIV4 TDTS = 4Tck_tim


④TIM_CounterMode 选择了计数器模式。该参数取值见下表。

TIM_CounterMode_Up TIM 向上计数模式

TIM_CounterMode_Down TIM 向下计数模式

TIM_CounterMode_CenterAligned1 TIM 中央对齐模式 1 计数模式

TIM_CounterMode_CenterAligned2 TIM 中央对齐模式 2 计数模式

TIM_CounterMode_CenterAligned3 TIM 中央对齐模式 3 计数模式


3) 设置 TIM3_DIER 允许更新中断。

因为我们要使用 TIM3 的更新中断, 寄存器的相应位便可使能更新中断。 在库函数里面定时器中断使能是通过 TIM_ITConfig 函数来实现的:


void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);


①选择定时器号 取值为TIM1-TIM7

②选择使能的定时器的中断类型

TIM_IT_Update TIM 中断源

TIM_IT_CC1 TIM 捕获/比较 1 中断源

TIM_IT_CC2 TIM 捕获/比较 2 中断源

TIM_IT_CC3 TIM 捕获/比较 3 中断源

TIM_IT_CC4 TIM 捕获/比较 4 中断源

TIM_IT_Trigger TIM 触发中断源

③使能指定的中断 ENABLE DISABLE


4) TIM3 中断优先级设置。

NVIC


5) 允许 TIM3 工作,也就是使能 TIM3。


void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)


这个函数非常简单,比如我们要使能定时器 3,方法为:


TIM_Cmd(TIM3, ENABLE); //使能 TIMx 外设


6) 编写中断服务函数。

在最后,还是要编写定时器中断服务函数,通过该函数来处理定时器产生的相关中断。在中断产生后,通过状态寄存器的值来判断此次产生的中断属于什么类型。然后执行相关的操作,我们这里使用的是更新(溢出)中断,所以在状态寄存器 SR 的最低位。在处理完中断之后应该向 TIM3_SR 的最低位写 0,来清除该中断标志。

固件库函数里面, 用来读取中断状态寄存器的值判断中断类型的函数是:


ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t)


该函数的作用是,判断定时器 TIMx 的中断类型 TIM_IT 是否发生中断。 比如,我们要判断定

时器 3 是否发生更新(溢出)中断,方法为:


if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)

{}


固件库中清除中断标志位的函数是:


void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)


该函数的作用是,清除定时器 TIMx 的中断 TIM_IT 标志位。 使用起来非常简单,比如我们在TIM3 的溢出中断发生后,我们要清除中断标志位,方法是:


TIM_ClearITPendingBit(TIM3, TIM_IT_Update );


例子:


void TIM3_Int_Init(u16 arr,u16 psc)

{

    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;//①

    NVIC_InitTypeDef NVIC_InitStructure;


    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); 


    TIM_TimeBaseStructure.TIM_Period = arr; //②

    TIM_TimeBaseStructure.TIM_Prescaler =psc; 

    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 

    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); 

    TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );//③


    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //④

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; 

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 

    NVIC_Init(&NVIC_InitStructure);  


    TIM_Cmd(TIM3, ENABLE);      //⑤          

}

void TIM3_IRQHandler(void)  //⑥

{

    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  

        {

        TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  

        LED1=!LED1;

        }

}


流程首先第一步就是使能相应的时钟,使其有能量的来源 第二步就是写定时器的参数函数其中有四点 第三部就是使能要用的中断 第四部设定中断的优先级 第五步使能定时器的中断 最后就是编写中断程序PWM的输出

1)


RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器 3 时钟


2) 初始化 TIM3,设置 TIM3 的 ARR 和 PSC。在开启了 TIM3 的时钟之后,我们要设置 ARR 和 PSC 两个寄存器的值来控制输出 PWM 的周期。当 PWM 周期太慢(低于 50Hz)的时候,我们就会明显感觉到闪烁了。因此, PWM 周期在这里不宜设置的太小。 这在库函数是通过 TIM_TimeBaseInit 函数实现的调用的格式为:


TIM_TimeBaseStructure.TIM_Period = arr; //设置自动重装载值

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

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

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

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化 TIMx 的


3) 设置 TIM3_CH2 的 PWM 模式,使能 TIM3 的 CH2 输出。接下来,我们要设置 TIM3_CH2 为 PWM 模式(默认是冻结的) 在库函数中, PWM 通道设置是通过函数 TIM_OC1Init()~TIM_OC4Init()来设置的我们直接来看看结构体的定义:


typedef struct

{

uint16_t TIM_OCMode;

uint16_t TIM_OutputState;

uint16_t TIM_Pulse;

uint16_t TIM_OCPolarity;

} TIM_OCInitTypeDef;


这一部分也是重点

参数 TIM_OCMode 设置模式是 PWM 还是输出比较,这里我们是 PWM 模式。

TIM_OCMode_Timing TIM 输出比较时间模式 比较成功后不在对应输出管脚上产生输出

TIM_OCMode_Active TIM 输出比较主动模式

TIM_OCMode_Inactive TIM 输出比较非主动模式

TIM_OCMode_Toggle TIM 输出比较触发模式 比较成功后反转电平

TIM_OCMode_PWM1 TIM 脉冲宽度调制模式 1

TIM_OCMode_PWM2 TIM 脉冲宽度调制模式 2


参数 TIM_OutputState 用来设置比较输出使能,也就是使能 PWM 输出到端口。

TIM_OutputState_Enable;

TIM_OutputState_Disable;


参数 TIM_OCPolarity 用来设置极性是高还是低。

TIM_OCPolarity_High TIM 输出比较极性高

TIM_OCPolarity_Low TIM 输出比较极性低


例子:


TIM_OCInitTypeDef TIM_OCInitStructure;

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择 PWM 模式 2

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

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性高 意味高电平为有效

TIM_OC2Init(TIM3, &TIM_OCInitStructure); //初始化 TIM3 OC2


关于为什么没有用TIM_Pulse 实际上在后面的TIM_SetCompare2(TIM3,led0pwmval);函数中后面一个参数的值就是TIM_Pulse的值 这么做的好处是这个值得修改可以在主函数中完成而不用修改源文件中的值 使操作更方便


4) 使能 TIM3。

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

6) 修改 TIM3_CCR2 来控制占空比。

最后,在经过以上设置之后, PWM 其实已经开始输出了,只是其占空比和频率都是固定的,而我们通过修改 TIM3_CCR2 则可以控制 CH2 的输出占空比。在库函数中,修改 TIM3_CCR2 占空比的函数是:


void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);

TIM_SetCompare2(TIM3,led0pwmval);

这里写图片描述

PWM1中若当前值小于CCR则为有效 有效可以根据输出极性来设定若为高则是高电平有效 此事duty=CCR/ARR 又CCR决定占空比 ARR决定周期

关键字:STM32吗  定时器  PWM输出 引用地址:STM32自学笔记——定时器及PWM输出

上一篇:STM32学习笔记(5):通用定时器PWM输出
下一篇:STM32 PWM波驱动模拟舵机(库函数版)

推荐阅读最新更新时间:2024-11-13 02:09

浅谈AVR中定时器几种工作模式
AVR有三个定时计数器,其中定时计数器0和定时计数器2是8位的,定时计数器1是16位。 在学习AVR定时计数器时,刚开始被一大堆的寄存器搞的有点晕了,后来认真的把Datasheet中的有关寄存器先看了一遍,再重新看定时计数器的内容才理清了。这里做个总结吧,加深自己的印象。 定时计数器0和定时计数器2基本上是相同的。以定时计数器0来总结它的几种工作模式的不同。 普通模式:不做介绍,和51里面是一模一样的。 CTC模式:当寄存器TCNT0与OCR0相等时(即匹配),OC0按照COM0[1:0]的值相应的改变(置位,清零或取反)。同时TCNT0清零,TCNT0从0x00重新开始计数,当计数结果和下一个OCR0寄存器中值相等时又
[单片机]
浅谈AVR中<font color='red'>定时器</font>几种工作模式
STM32】CubeMX+HAL 输出PWM
1. 配置STM32CubeMX 前面的一些基础步骤可参见:【STM32】CubeMX+HAL 点亮LED 的【1.1】~【1.6】步骤。 核心配置: 这里我使用的是 TIM2 定时器,当然使用其他的也可以,但要注意相关配置。 1.1 TIM2 的 Mode 配置 1.2 TIM2 的 Configuration 配置 1.3 其余 GPIO 配置 PA2 的 PWM 输出作为 PA6 的输入,PA6 连接的是一个 LED ,观察是否出现呼吸灯现象。 余下步骤可参见:【STM32】CubeMX+HAL 点亮LED 的【1.10】~【1.13】步骤。 2. 添加代码 下面贴出主要代码: 2.1
[单片机]
【<font color='red'>STM32</font>】CubeMX+HAL <font color='red'>输出</font><font color='red'>PWM</font>
esp32能取代stm32?哪个好?
在学生群体或许能替代,因为超高性价比。 站在产品的角度替代不了,产品选型考虑的因素很多。 ESP32和STM32都是广泛使用的微控制器,它们都有自己的优缺点。 如果简单地说一个完全可以取代另一个,其实并不现实。 下面列举几个ESP32无法完全取代STM32的理由: 1. 应用场景 STM32的应用场景更加广阔,能做的产品更多。 ESP32通常用于物联网设备,家庭自动化,Wi-Fi控制,而STM32更适合用于消费类、工业控制、机器人、医疗设备、汽车等应用程序。 通常情况,ESP32更多是作为一个蓝牙、WiFi的中继功能。 如果考虑到产品后续的功能升级,比较好的方式是STM32或者其它MCU+ESP32,这样后面扩展更加灵活。 如
[单片机]
STM32学习笔记(4) 高级定时器-两路互补的PWM输出(带死区和刹车控制)
1.实验目的 使用高级定时器,输出两路互补的PWM输出,需要有带死区和不带死区两种情况 2.实验效果 图1:不带死区的两路互补的PWM输出 图2 :带死区的两路互补的PWM输出 3.理论部分 3.1时钟源 内部时钟(基本定时器,通用定时器时钟源来自PCLK1,但高级定时器的时钟源来自PCLK2(72M)) 实践中几乎无需使用:外部时钟模式1、外部时钟模式2 3.2时基单元 组成: 16bit预分频PSC 16bit计数器CNT 8bit重复计数器RCR(高级定时器独有) 16bit自动重装载寄存器ARR 3.3输入捕获 作用:对输入信号的上升沿/下降沿/双边沿进行捕获,测量输入信号的脉宽,和
[单片机]
<font color='red'>STM32</font>学习笔记(4) 高级<font color='red'>定时器</font>-两路互补的<font color='red'>PWM</font><font color='red'>输出</font>(带死区和刹车控制)
AVR ATmega1280定时器PWM输出程序
#include kernel.h unsigned int PWM_Buf ;//6路PWM频率 unsigned long timer0_ticks; unsigned long timer0_tickssec; unsigned long timer1_ticks; unsigned long timer1_ticksmin; unsigned long timer2_ticks; unsigned long timer2_tickssec; unsigned long timer3_ticks; unsigned long timer3_ticksmin; unsigned long timer4_ticks; uns
[单片机]
PIC16F877A 看门狗定时器(WDT)
//PIC.H中定义了宏 #define CLRWDT() asm( clrwdt )因此在PICC的c语言中可以直接使用CLRWDT()对WDT清0 //若单片机WDT使能,在适当位置加入CLRWDT(),程序进入正常运行时,每隔一定时间均会执行CLRWDT()语句对WDT清0,芯片不会复位 //如果程序陷入死循环,不会执行到CLRWDT()语句,则超出所设定的时间后,WDT溢出使芯片复位,从头(000H)开始执行,单片机恢复正常运行 //PIC16F单片机,看门狗定时器的启用只能在芯片的烧写时确定,即无法用软件来开启或关闭WDT,但在PIC16f88X中可以。 //PIC16单片机的WDT基本溢出时间为18MS,由RC充放电
[单片机]
如何进行多个定时器主从级联同步输出详细配置示例说明
有些应用场合,我们需要使用多个定时器主从级联,然后让各个定时器同时启动并做同频同相的PWM波形输出。要完成这个功能,有时发现实现起来似乎并没有那么顺畅,这里基于STM32F1系列芯片做个配置示例。之所以选择STM32F1芯片主要是考虑到有部分人使用STM32F1芯片并基于标准库做开发,那么,我这里就Cube库和标准库给出两套相关主从配置的示例代码,供有需要的人参考。 在调试验证过程中我选择STM32F103 Nucleo板,主芯片为STM32F103RB.将片内定时器TIM1/TIM2/TIM3/TIM4四个定时器主从首尾相连,同时启动并要求四个定时器输出同频同相信号。 先查看STM32F1参考手册相关章节【这个环节是必不
[单片机]
如何进行多个<font color='red'>定时器</font>主从级联同步<font color='red'>输出</font>详细配置示例说明
51单片机 定时器及其应用
89c51单片机内部有两个16位的定时/计数器,即定时器T0和定时器T1,单片机的定时功能其实就是通过计数来实现的,当单片机每一个机器周期产生一个脉冲时,计数器就加一。定时器的应用涉及到中断方面的知识,可以先了解中断的概念再来看定时器 如,一个16位的定时器,它所能计数的范围是0~65535,如果单片机采用的是12M的晶振,那么定时器单次最长的时间为65535*((1/12)*12),因为一个一个机器周期等于12个振荡周期,那么定时器加一所用的时间是1/12M*12是1us,也就是一个12MHz晶振的51单片机单次最长时间约为65ms. 定时器的控制 89c51的定时器由两个寄存器控制,分别是工作模式寄存器TMOD和控
[单片机]
51单片机 <font color='red'>定时器</font>及其应用
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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