一、定时器

1.     定义

设置等待时间,到达后则执行指定操作的硬件。

2.    STM32F407的定时器有以下特征

具有基本的定时功能,也有PWM输出(灯光控制、电机的转速)、脉冲捕获功能(红外捕捉)

2个高级控制定时器、10个通用定时器和2个基本定时器

高级控制定时器(TIM1和TIM8)

  具有16位定时器功能,也具有PWM输出高级控制功能

通用定时器(TIM2到TIM5)

  具有16位定时功能,也具有PWM输出控制功能

通用定时器(TIM9到TIM14)

  具有16位定时功能,也具有PWM输出控制功能

基本定时器(TIM6和TIM7)

  具有16位定时功能

二、定时器初始化

1.   选择时钟源,并初始化定时器分频值与定时时间

/* TIM3 clock enable ,定时器3时钟使能*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* Time base configuration ,定时器基本配置*/
TIM_TimeBaseStructure.TIM_Period = (/)-; //定时时间的设置[非常重要],中断频率为1000Hz,也就是定时时间为1ms
TIM_TimeBaseStructure.TIM_Prescaler = 8400-1; //预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频,也称之为二次分频,当前是1分频,说白了不分频,不降低频率
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数的方法
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //初始化

涉及部分寄存器参考如下

1.         中断的配置

/* TIM Interrupts enable,使能定时器3更新中断事件,也代表说定时已经到达的事件 */
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); /* TIM3 enable counter,使能定时器3工作 */
TIM_Cmd(TIM3, ENABLE);

2.         中断服务函数的编写

void TIM3_IRQHandler(void)
{
static uint32_t cnt=; //是否已经有更新中断事件
if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)
{
//添加用户代码
cnt++; if(cnt>=)
{
cnt =;
PFout()^=; }
//清空标志位,告诉CPU我已经完成中断处理
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
} }

TIM3

#include <stdio.h>
#include "stm32f4xx.h"
#include "sys.h" GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure; void tim3_init(void)
{
/* TIM3 clock enable ,定时器3时钟使能*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* Enable the TIM3 gloabal Interrupt ,使能定时器3全局中断*/
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); /* Time base configuration ,定时器基本配置*/
TIM_TimeBaseStructure.TIM_Period = (/)-; //定时时间的设置[非常重要],中断频率为1000Hz,也就是定时时间为1ms
TIM_TimeBaseStructure.TIM_Prescaler = -; //预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频,也称之为二次分频,当前是1分频,说白了不分频,不降低频率
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数的方法
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //初始化 /* TIM Interrupts enable,使能定时器3更新中断事件,也代表说定时已经到达的事件 */
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); /* TIM3 enable counter,使能定时器3工作 */
TIM_Cmd(TIM3, ENABLE); } int main(void)
{ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); /* 配置PF9引脚为输出模式 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //第9根引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //设置输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽模式,增加驱动电流
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //设置IO的速度为100MHz,频率越高性能越好,频率越低,功耗越低
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //不需要上拉电阻
GPIO_Init(GPIOF, &GPIO_InitStructure); PFout()=; //定时器3初始化
tim3_init(); while()
{ } } void TIM3_IRQHandler(void)
{
static uint32_t cnt=; //是否已经有更新中断事件
if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)
{
//添加用户代码
cnt++; if(cnt>=)
{
cnt =; PFout()^=; } //清空标志位,告诉CPU我已经完成中断处理
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
} }

tim1238_irq

#include "stm32f4xx.h"
#include "stdio.h"
#include "bitband.h" GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; void tim1_init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); //定时时间为100ms 168000000/16800=10000Hz
TIM_TimeBaseStructure.TIM_Period = (/)-;
TIM_TimeBaseStructure.TIM_Prescaler = -;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); TIM_Cmd(TIM1, ENABLE); } void tim2_init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); //定时时间为200ms 84000000/84000=10000Hz
TIM_TimeBaseStructure.TIM_Period = (/)-;
TIM_TimeBaseStructure.TIM_Prescaler = -;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); TIM_Cmd(TIM2, ENABLE); } void tim3_init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); //定时时间为500ms 84000000/84000=10000Hz
TIM_TimeBaseStructure.TIM_Period = (/)-;
TIM_TimeBaseStructure.TIM_Prescaler = -;
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); TIM_Cmd(TIM3, ENABLE); } void tim8_init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); //定时时间为2秒 168000000/168000=10000Hz
TIM_TimeBaseStructure.TIM_Period = (*)-;
TIM_TimeBaseStructure.TIM_Prescaler = -;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); TIM_ITConfig(TIM8, TIM_IT_Update, ENABLE); TIM_Cmd(TIM8, ENABLE); } int main(void)
{ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOE, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOF, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOE, &GPIO_InitStructure); PFout() = ;
PFout() = ;
PEout() = ;
PEout() = ; tim1_init();
tim2_init();
tim3_init();
tim8_init(); while()
{ }
} void TIM1_UP_TIM10_IRQHandler(void)
{
if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
{ PFout() ^= ; TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
}
} void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{ PFout() ^= ; TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
} void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
{ PEout() ^= ; TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
}
} void TIM8_UP_TIM13_IRQHandler(void)
{
if (TIM_GetITStatus(TIM8, TIM_IT_Update) != RESET)
{ PEout() ^= ; TIM_ClearITPendingBit(TIM8, TIM_IT_Update);
}
}

定时器TIM,pwm的更多相关文章

  1. 关于普通定时器与高级定时器的 PWM输出的初始化的区别

    不管是普通定时器还是高级定时器,你用哪个通道,就在程序里用OC多少.比如CH3对应OC3 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  TIM_ ...

  2. STM32F103定时器输出PWM波控制直流电机

    这个暑假没有回家,在学校准备九月份的电子设计竞赛.今天想给大家分享一下STM32高级定时器输出PWM波驱动直流电机的问题.. 要想用定时器输出的PWM控制直流电机,,首先要理解“通道”的概念..一个定 ...

  3. STM32定时器输出PWM频率和步进电机控制速度计算

    1.STM32F4系列定时器输出PWM频率计算 第一步,了解定时器的时钟多少: 我们知道AHP总线是168Mhz的频率,而APB1和APB2都是挂在AHP总线上的. (1)高级定时器timer1, t ...

  4. STM32 基于定时器的PWM发生器

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

  5. 定时器及PWM

    1 定时器 1.1 定时器分类 对于STM32来说,定时器可分为基本定时器.通用定时器.高级定时器三类,后者包括前者的全部功能.以stm32f1系列为例,TIM6和TIM7为基本定时器,TIM2~TI ...

  6. stm32cube--通用定时器--产生pwm波

    看了通用定时器的资料,发现内容挺多,挺难看懂,现在还是先掌握使用方法,以后再多看几遍吧. ① ② ③生成mdk工程后,在main.c的while(1)前面加上HAL_TIM_PWM_Start(&am ...

  7. stm32之通用定时器TIM

    STM32系列的CPU,有多达8个定时器: 1.其中TMI1和TIM8是能够产生三对PWM互补输出的高级定时器,常用于三相电机的驱动:它们的时钟有APB2的输出产生: 2.其它6个为普通定时器,时钟由 ...

  8. stm32 定时器TIM时钟步骤

    1)TIM3 时钟使能 . RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIMx, ENABLE); //时钟使能 2) 初始化定时器参数,设置自动重装值, 分频系数, ...

  9. STM32 HAL库学习系列第6篇---定时器TIM 级联配置

    应用情景 使用定时器配置编码器模式,发现STM32只有两个定时器是32位,16位的测量值不够用,发现是可以使用两个16位定时器级联为32位的. 我是在使用编码器计数电机转速时使用,但是最终实现的效果不 ...

随机推荐

  1. AtCoder Grand Contest 040 A - ><

    传送门 对于某个位置,只要知道这个位置往左最多的连续 $\text{<}$ 的数量 $x$ 和往右最多的连续 $\text{>}$ 的数量 $y$ 那么这个位置最小可能的数即为 $max( ...

  2. 工欲善其事必先利其器之Vagrant + VirtualBox

    Vagrant 可以管理 VirtualBox,实现快速配置创建虚拟机 1.下载软件 VirtualBox虚拟机下载地址:https://www.virtualbox.org/wiki/Downloa ...

  3. Unable to resolve service for type 'Microsoft.AspNetCore.Http.IHttpContextAccessor'

    An unhandled exception occurred while processing the request. InvalidOperationException: Unable to r ...

  4. 【Transact-SQL】计算整个表中所有值的出现的次数

    原文:[Transact-SQL]计算整个表中所有值的出现的次数 一个表有3列,5行,那么一共有15个值,现在要计算整个表中所有值在表中出现的次数,不过这里表的列数是不确定的,上面的例子是3列,实际上 ...

  5. vue.js入门语法

    1.入门 <div id="vue_det"> <h1>site : {{site}}</h1> //两个大括号显示参数 <h1>u ...

  6. C# 在运行中拖拽,改变控件大小位置类(转载)

    原文地址:https://blog.csdn.net/zgke/article/details/3718989 copy的code /// <summary> /// 移动改变控件大小 / ...

  7. 分布式事务(ACID特性、CAP定律)

    普通事务和分布式事务的区别: 普通事务就是一般所说的数据库事务,事务是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成.当事务被提交给了DBMS(数据库管理系统),则DBMS(数 ...

  8. js基本对象

    1.介绍js的基本数据类型 Undefined.Null.Boolean.Number.String 2.js有哪些内置对象? 数据封装类对象:Object.Array.Boolean.Number ...

  9. Ubuntu安装rpm

    # sudo apt-get install alien # sudo alien xxx.rpm # sudo dpkg -i xxx.deb

  10. redis集群安装2

      概要:本文主要介绍如何在Centos7中单机搭建redis集群三主三从,按照本文绝对可以实现该需求,至于先搭建单机版主要为了方便理解redis集群,为下一步开发或生产上redis集群做铺垫.同时本 ...