历史上的今天
返回首页

历史上的今天

今天是:2025年02月13日(星期四)

正在发生

2020年02月13日 | STM32学习笔记——利用通用定时器TIM2进行精确延时

2020-02-13 来源:eefocus

1. 通用定时器概述及性能


1.1 概述


在作者所使用的stm32芯片上,共有TIM1 1个高级定时器以及TIM2、TIM3、TIM4共3个通用定时器。其中各通用定时器均由一个通过可编程预分频器驱动的16位自动装载计数器构成。适用于多种场合,包括测量输入信号的脉冲长度(输入采集)或者产生输出波形(输出比较和PWM)。使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。定时器是完全独立的,而且没有互相共享任何资源。它们可以一起同步操作。


1.2 性能


通用TIMx定时器特性包括:


16 位向上,向下,向上/向下自动装载计数器

16 位可编程预分频器,计数器时钟频率的分频系数为1~65535 之间的任意数值

4个独立通道:

─ 输入捕获


─ 输出比较


─ PWM生成(边缘或中间对齐模式)


─ 单脉冲模式输出


使用外部信号控制定时器和定时器互连的同步电路

如下事件发生时产生中断/DMA:

─ 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)


─ 触发事件(计数器启动,停止,初始化或者由内部/外部触发计数)


─ 输入捕获


─ 输出比较


1.3 部分寄存器


由于通用定时器较为复杂,此处仅介绍如何利用TIM2进行精确延时。下面介绍是TIM中与本篇内容有关的寄存器。


1.3.1控制寄存器1(TIMx_CR1)

1.3.2 DMA/中断使能寄存器(TIMx_DIER)

本篇中只关心其第6位及第0位

由于需要TIM在更新时产生中断,因此这两位都必须置1。


1.3.3 预分频器(TIMx_PSC)

该分频器对时钟进行分频,并作为计数器时钟。


时钟来源有4种:


1)内部时钟(CK_INT) 


2)外部时钟模式1:外部输入脚(TIx) 


3)外部时钟模式2:外部触发输入(ETR) 


4)内部触发输入(ITRx):使用A定时器作为B定时器的预分频器(A为B提供时钟)。


具体选择可以通过TIMx_SMCR寄存器相关位来设置。


1.3.4 自动重装载寄存器(TIMx_ARR)

1.3.5 状态寄存器(TIMx_SR)

本篇中主要关心该寄存器第0位

当产生溢出时,该标记位被置1,执行更新事件后由软件清0。

其他众多关于TIM寄存器可查阅《STM32F10x参考手册》


1.4基本计数中断过程


按照自己的理解,使能中断及定时器后,根据时钟来源以及预分频器(TIMx_PSC)所设置的分频数开始计数,当计数达到自动重装载寄存器(TIMx_ARR)中所存储的值时,状态寄存器(TIMx_SR)中对应的标志位(第0位)置1,通过软件检查该位则可以更新事件。


例如:系统中APB1(TIM2被挂在APB下)时钟频率为36MHz,设置TIMx_PSC分频为36000,则作为定时器TIM2的时钟频率为36000000/36000=1000Hz,即1秒内内部开关计数1000次,每次1ms,设置TIMx_ARR重装值为1000,则计数达1000次时,TIMx_SR中第0位标志位被置1,此时为延迟1秒。


2 TIM固件库函数


2.1 函数TIM_DeInit

image.png?imageView2/2/w/550

例:重设TIM2


TIM_DeInit(TIM2);

 

2.2 函数TIM_TimeBaseInit

image.png?imageView2/2/w/550

TIM_TimeBaseInitTypeDef structure


TIM_TimeBaseInitTypeDef定义于文件“stm32f10x_tim.h”: 


typedef struct 

    u16 TIM_Period; 

    u16 TIM_Prescaler; 

    u8 TIM_ClockDivision; 

    u16 TIM_CounterMode; 

} TIM_TimeBaseInitTypeDef; 


TIM_Period 


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


TIM_Prescaler 


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


TIM_ClockDivision 


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

image.png?imageView2/2/w/550

TIM_CounterMode 


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

image.png?imageView2/2/w/550

例: 


TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 

TIM_TimeBaseStructure.TIM_Period = 0xFFFF; 

TIM_TimeBaseStructure.TIM_Prescaler = 0xF; 

TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; 

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 

TIM_TimeBaseInit(TIM2, & TIM_TimeBaseStructure);


2.3 函数TIM_ClearFlag

image.png?imageView2/2/w/550

TIM_FLAG值

image.png?imageView2/2/w/550

例:


TIM_ClearFlag(TIM2,TIME_FLAG_Update);



2.4 函数TIM_ITConfig

image.png?imageView2/2/w/550

TIM_IT值

image.png?imageView2/2/w/550

例:


TIM_ITConfig(TIM2,TIME_FLAG_Update,ENABLE);



2.5 函数TIM_Cmd

image.png?imageView2/2/w/550

例:


TIM_Cmd(TIM2,ENABLE);


3 例程程序


本例程主要使用TIM2进行精准延时并亮灭LED灯,其中NVIC部分暂做了解,后面再继续深入。另外,需要注意3.0以后版本的固件库相比2.0版有所更改,如删除旧版NVIC部分函数,或移动至misc.c文件中,通道名TIM2_IRQChannel更改为TIM2_IRQn等。完整构架:

 

完整代码:


#include "stm32f10x.h"

    void delay1ms(u32 nTimer);

    void GPIO_Configuration(void);

    void TIM2_IRQHandler(void);

    void Timer2_Configuration(void);

    void NVIC_Configuration(void);

 

int main(void)

{

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能GPIOC时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//使能TIM2时钟

GPIO_Configuration();

NVIC_Configuration();//配置中断

Timer2_Configuration();//配置定时器

  while(1)

  {

    GPIO_ResetBits(GPIOC,GPIO_Pin_7|GPIO_Pin_6);

    GPIO_SetBits(GPIOC,GPIO_Pin_9|GPIO_Pin_8);

    delay1ms(1000);

    GPIO_ResetBits(GPIOC,GPIO_Pin_9|GPIO_Pin_8);

    GPIO_SetBits(GPIOC,GPIO_Pin_7|GPIO_Pin_6);

    delay1ms(1000);

    GPIO_Write(GPIOC,0x0140);

    delay1ms(2000);

    GPIO_Write(GPIOC,0x0280);

    delay1ms(2000);

   }

}

 

void GPIO_Configuration(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;

  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;

  GPIO_Init(GPIOC,&GPIO_InitStructure);

}

 

void Timer2_Configuration(void)

{

  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

  TIM_DeInit(TIM2);//使用缺省值初始化TIM外设寄存器

  TIM_TimeBaseStructure.TIM_Period=1;//自动重装载寄存器值为1

  TIM_TimeBaseStructure.TIM_Prescaler=(36000-1);//时钟预分频数为36000

  TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//采样分频倍数1,未明该语句作用。

  TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//上升模式

  TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);

  TIM_ClearFlag(TIM2,TIM_FLAG_Update);//清除更新标志位

  TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能中断

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

}

 

void NVIC_Configuration(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_SetPriorityGrouping(NVIC_PriorityGroup_0);

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //3.0版以后的函数库将各通道TIM2_IRQChanel改名TIM2_IRQn

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);//NVIC_Init函数被包含在misc.c文件中。

}

 

volatile u32 gTimer;

void TIM2_IRQHandler(void)

{

  if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)//检查溢出信号

  {

    TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除溢出标志

    gTimer--;

  }

}

 

void delay1ms(u32 nTimer)

{

 gTimer=nTimer;

 while(gTimer);

}


完成编译并烧录后,开发板上四个LED灯先相邻两两亮灭,亮灭时间延迟1秒,然后交替两两亮灭,亮灭时间延迟2秒。


参考文献


[1] Sharkdo.STM32用定时器精确延时的方法  [EB/OL].http://www.cnblogs.com/sharkdo/archive/2011/03/23/1993036.html,2011-03-23/2012-10-14


[2] Cdzlllfe.stm32 通用定时器精确延时程序[EB/OL].


http://blog.sina.com.cn/s/blog_88534dff01010t1a.html,2011-12-17/2012-10-14


[3]福州芯达工作室.《STM32入门系列教程——定时器与蜂鸣器》[EB/OL]. http://ishare.iask.sina.com.cn/f/10918196.html,2010-10-20/2012-10-14.


[4]正点电子.《Stm32不完全手册》[EB/OL]. http://www.amobbs.com/forum.php?mod=viewthread&tid=4517523,2011-01-17/2012-10-15


[5]半壶水,《STM32 菜鸟学习手册-罗嗦版》,http://wenku.baidu.com/view/fc7c7d20ccbff121dd3683da.html, 2012-08-19.


[6] ST.《如何从STM32F10xxx固件库V2.0.3 升级为STM32F10xxx标准外设库V3.0.0》[EB/OL]. http://ishare.iask.sina.com.cn/f/18297257.html?from=like,2011-08-22/2012-09-09.

推荐阅读

史海拾趣

DIOTEC公司的发展小趣事

为了进一步完善全球产业布局,DIOTEC于2007年在印度普纳建立了新的生产基地。这座工厂紧邻印度的“门户城市”孟买,为DIOTEC在印度市场的拓展提供了有力支持。印度工厂的投产,不仅加强了DIOTEC在全球市场的竞争力,也进一步巩固了其在亚洲市场的地位。

FCI / Amphenol公司的发展小趣事

1997年,Amphenol公司经历了一次重要的转折点。当时,公司被KKR(一家具有传奇色彩的美国纽约的私人股权投资公司)以杠杆收购的方式收购。KKR的收购为Amphenol公司注入了新的活力,公司开始进行一系列的战略调整和业务转型。在KKR的助力下,Amphenol公司不仅保留了大部分现有的管理团队,还引入了更大的财务杠杆,使得公司能够更加灵活地应对市场变化和挑战。这一收购和转型不仅为Amphenol公司带来了新的发展机遇,也为其在全球连接器市场上的地位奠定了更加坚实的基础。

GWM Associates公司的发展小趣事
设计时需要保证增益的稳定性,以确保在不同工作条件下放大器的性能保持一致。
BENCENT公司的发展小趣事

为了扩大市场份额和提高品牌知名度,BENCENT公司开始积极参与国内外各类电子展会和论坛,与潜在客户和合作伙伴建立联系。同时,公司还加大了营销宣传力度,通过线上线下的方式提升品牌曝光度。这些努力不仅带来了更多的销售机会,也提升了公司在行业内的地位和影响力。

Glenair公司的发展小趣事
电路中的连接线可能松动、接触不良或断裂,导致信号无法正确传输。
Facon公司的发展小趣事

在2010年代初,随着科技的飞速发展,电子行业正迎来新一轮的创新浪潮。这时,一群充满激情和梦想的工程师在硅谷创立了Facon公司,他们怀揣着改变世界的愿景,立志在电子行业中留下自己的印记。初始阶段,Facon主要专注于研发高性能的半导体芯片,为智能手机、平板电脑等电子产品提供强大的计算能力。通过不懈努力和持续创新,Facon逐渐在市场中树立了良好的口碑。

问答坊 | AI 解惑

晒板子28335

28335电力电子与电力传动专用控制板 …

查看全部问答>

机电领域中伺服电机的选择原则

提出的选择原则是将电机特性与负载特性分离开 ,并用图解的形式表示 ,这种表示方法使得驱动 装置的可行性检查和不同系统间的比较更方便 ,另外 ,还提供了传动比的一个可能范围.…

查看全部问答>

获取芯币的另一个小诀窍

快速获得芯币的另一种方法,就是与博客紧密结合。规则如下,请大家详细阅读啊! 1、注册博客 + 20 芯币 2、在论坛签名中注明自己博客地址  +5 芯币    3、博客个人信息注册完全,其中上传电子相片  +5芯币 4、 ...…

查看全部问答>

一本dsp2812的好书

最近刚刚从图书馆借到一本新书《dsp控制技术实践》。中国电力出版社出版,2009.5出版的。专门讨论dsp2812的片子的使用,比ti的中文手册薄多了,看起来挺舒服的。推荐给大家。…

查看全部问答>

LED行业竞争白热化,各大厂商拿什么取胜呢?打扰了。

LED行业竞争白热化,各大厂商拿什么取胜呢?打扰了。…

查看全部问答>

请问这几句汇编具体的意思是什么?

GBLS        MainEntry MainEntry        SETS        \"Main\"         IMPORT        $MainEntry MainEntry不是已经在第一行就已经定 ...…

查看全部问答>

MC2833/MC3363如何编程

这是朋友的一个毕业设计题目。别的部分没什么特别。但是,这个课题使用了MC2822/MC3363这一对摩托罗拉的音频收发芯片来实现无线收发。我的毕业设计用的是nRF24L01,所以我很习惯性用这个去套它的思路。可是我在网上查了查,似乎没有找到关于它的编程 ...…

查看全部问答>

关于QEI的问题

最近正在学习luminary,用的是周立功的easyArm8962的板子,在qei的实验例程中有这么两句话:SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI);GPIODirModeSet(GPIO_PORTC_BASE, GPIO_PIN_4 | GPIO_PIN_6,   GPIO_DIR_MODE_HW);GPIODirModeSet( ...…

查看全部问答>

Smart Debug网络与串口调试工具(原创)

最新版本号: 1.0.1.111031        更新日期: 2011.10.26 下载地址1 http://stu.cidp.edu.cn/SmartDebug.rar 下载地址1 下载地址2 http://www.vdisk.cn/down/index/8990713A3710 下 ...…

查看全部问答>

希望大家帮帮忙

不好意思 有件事情麻烦大家 老师布置了一项作业之前设计原理图时没看要求 搞错了 现在时间有点急希望大家有能人帮我设计一个原理图 要求如下: 九、彩灯控制器一 要求:1.有八只LED,L0……L72.显示顺序如下表3.显示间隔为0.25S,0.5S,1S,2S ...…

查看全部问答>