STM32通用定时器(时钟选择,模式选择)

发布者:乡村乐园最新更新时间:2015-08-24 来源: eefocus关键字:STM32  通用定时器  时钟选择  模式选择 手机看文章 扫描二维码
随时随地手机看文章
  STM32的定时器功能很强大,学习起来也很费劲儿.

   其实手册讲的还是挺全面的,只是无奈TIMER的功能太复杂,所以显得手册很难懂,我就是通过这样看手册:while(!SUCCESS){看手册…}才搞明白的!所以接下来我以手册的顺序为主线,增加一些自己的理解,并通过11个例程对TIMER做个剖析。实验环境是STM103V100的实验板,MDK3.2 +Library2.东西都不怎么新,凑合用……

   TIMER主要是由三部分组成:

1、           时基单元。

2、           输入捕获。

3、           输出比较。

还有两种模式控制功能:从模式控制和主模式控制。

一、 框图

让我们看下手册,一开始是定时器的框图,这里面几乎包含了所有定时器的信息,您要是能看明白,那么接下来就不用再看别的了…

为了方便的看图,我对里面出现的名词和符号做个注解:

  TIMx_ETR:TIMER外部触发引脚 ETR:外部触发输入

ETRP:分频后的外部触发输入 ETRF:滤波后的外部触发输入

ITRx:内部触发x(由另外的定时器触发)

TI1F_ED:TI1的边沿检测器。

TI1FP1/2:滤波后定时器1/2的输入

TRGI:触发输入  TRGO:触发输出  

CK_PSC:应该叫分频器时钟输入

CK_CNT:定时器时钟。(定时周期的计算就靠它)

TIMx_CHx:TIMER的输入脚  TIx:应该叫做定时器输入信号x

ICx:输入比较x  ICxPS:分频后的ICx

OCx:输出捕获x  OCxREF:输出参考信号

关于框图还有以下几点要注意:

1、           影子寄存器。

有阴影的寄存器,表示在物理上这个寄存器对应2个寄存器,一个是程序员可以写入或读出的寄存器,称为preload register(预装载寄存器),另一个是程序员看不见的、但在操作中真正起作用的寄存器,称为shadow register(影子寄存器);(详细请参考版主博客http://blog.ednchina.com/STM32/401461/message.aspx

2、           输入滤波机制

在ETR何TIx输入端有个输入滤波器,它的作用是以采样频率Fdts来采样N次进行滤波的。(具体也请参考版主博客http://blog.ednchina.com/STM32/263170/message.aspx

3、           输入引脚和输出引脚是相同的。

   

 

 二、时基单元

       时基单元有三个部分:CNT、PSC、ARR。CNT的计数方式分三种:向上、向下、中央对齐。通俗的说就是0—ARR、ARR—0、0—(ARR-1)—ARR—1.

    

 三、时钟源的选择

       这个是难点之一。从手册上我们看到共有三种时钟源:

1、           内部时钟。

也就是选择CK_INT做时钟,这个简单,但是有一点要注意,定时器的时钟不是直接来自APB1或APB2,而是来自于输入为APB1或APB2的一个倍频器,当APB1的预分频系数为1时,这个倍频器不起作用,定时器的时钟频率等于APB1的频率;当 APB1的预分频系数为其它数值(即预分频系数为2、4、8或16)时,这个倍频器起作用,定时器的时钟频率等于APB1的频率两倍。

例如AHP 72M,APB12分频36M,那么TIMER就是APB1的2倍频,即72M。

怎么选择时钟模式1呢?只要将SMCR中SMS[2:0]弄成000就好了

SMCR

15    14      13   12       11 10  9  8      7    6    5   4   3    2   1  0

ETP 

ECE

ETPS[1:0]

ETF[3:0]

MSM

TS[2:0]

 

SMS[2:0]

 

2、           外部时钟模式1

这个比较麻烦,时钟源选择的其实就是TRGI(触发输入),但触发输入选择挺多的,共8个……。看框图,他们是:ITRx、TI1F_ED、

TI1FP1、TI2FP2、ETRF

ITRx的东西跟定时器的级联有关,暂时不管他。要进入这种时钟模式首先置SMS为111,当然这还没完,不像内部时钟那样,什么都配好了,这里你还得配置一下别的参数,比如选择TI1FP1,自然要对输入通道1的参数配置好,这样时钟才能按你需要的方式进来。就是配框图这块

相关寄存器

CCMR1(输入)

 IC2F[3:0]

IC2PSC[1:0]

CC2S[1:0]

IC1F[3:0]

IC1PSC[1:0]

CC1S[1:0]

 

CCER

15 14   13    12 11 10        8    7  6          3 2       0

 

 

CC4P

CC4E

 

 

CC3P

CC3E

 

 

CC2P

CC2E

 

 

CC1P

CC1E

SMCR

15    14      13   12       11 10  9  8      7    6    5   4   3    2   1  0

ETP 

ECE

ETPS[1:0]

ETF[3:0]

MSM

TS[2:0]

 

SMS[2:0]

在CCMR1寄存器里选择好相应的输入(CC1S)和滤波(IC1F)后再配置好输入极性(CCIP)然后在SMCR中选择触发源(TS[2:0])为TI1这样输入通道就配好了!最后选择SMS为111,开启时钟(CR1中的CEN)。现在时钟就是从TI1上的输入了,可以接个时钟源进行计数之类的。同理,如果要用ETR就把它相关通道配好就可以了。

3、           外部时钟模式2

  选择外部输入作为时钟,看框图:

从图上可以看出ETR可以直接作为时钟输入也可以通过触发输入(TRGI)来作为时钟输入即在时钟模式1中触发源选择为ETR,两个效果上是一样的,看起来好像这个外部时钟模式2没什么用处,实际上不是的,他可以跟一些从模式(复位、触发、门控)进行组合。比如当从模式选为触发时,我们不可能再通过触发源选择ETR了,因为从模式控制器被占了,好在有外部时钟模式2,我们选择这种模式后就可以把两者组合在一起完成一些功能了。

总结一下,STM32的时钟选择比较特别,在SFR中关于时钟选择配置位不再一块,不是说两个位在一起00、01、11就选择了而是由

SMCR中SMS和ECE 来控制,这样感觉可以吧内部时钟与外部模式2同时打开(SMS:000,ECE:1),也可以吧外部模式1和外部模式2同时打开(SMS:111,ECE:1),实际上上述两种方式用的都是外部时钟2.

 

四、捕获比较通道

               

这就是我说的定时器三个组成部分中的两个部分了。核心是那个捕获比较寄存器。

 看框图

 

 

   异或那块先不管他,好像跟编码器有关,输入有个特色就是可以把TI的输入搞到CC1上去,也可以把T2的输入搞到CC1上去,其实也可以把T1搞到CC1上去同时把T1搞到CC2上去,这样就有了后来的PWM输入。

输出上的特色是不直接输出,而是有个OC1REF,这样可以定义高有效还是低有效,输出自己需要的有效电平。

    五、做实验

      

 讲了这么多你一定烦了吧,那么让我们搞点实际的吧,通过做实验来熟悉定时器,用到新知识时再在其中加以介绍。

 实验一:

TIMER-1:定时器上溢,中断中取反LED.

现象:LED 周期2秒闪烁。

        主要代码如下:

         TIM_DeInit(TIM2);

 

 TIM_TimeBaseStructure.TIM_Period=2000;       //ARR的值

         TIM_TimeBaseStructure.TIM_Prescaler=0;

         TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //采样分频

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

         TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

 TIM_PrescalerConfig(TIM2,0x8C9F,TIM_PSCReloadMode_Immediate);//时钟分频系数36000,所以定时器时钟为2K

         TIM_ARRPreloadConfig(TIM2, DISABLE);//禁止ARR预装载缓冲器

 TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);

 

         TIM_Cmd(TIM2, ENABLE);      //开启时钟

         解释一下,首先得配好ARR,这是必须地。然后配置预分频,为什么我先配为0再用TIM_PrescalerConfig(TIM2,0x8C9F,TIM_PSCReloadMode_Immediate)配呢,原来PSC也有个预装载功能,却不像ARR和CRR那样有相关的位控制立即装载或更新事件装载。也就是说只能更新事件来装载。在上面函数中手工产生了一个更新事件,使PSC立刻生效。CK_DIV暂时没用到。计数模式配置为向上计数。然后在中断中做下LED取反就可以了。

        溢出周期怎么算?在这个实验里AHB为72M,APB1为36M,所以CK_INT为72M,36000分频变为2K.ARR=2000,所以1秒溢出1次。

相关寄存器:

 

         CR1                                                          

        9    8     7      6    5    4    3    2     1     0

 

 

 

 

 

 

CKD[1:0]

ARPE

CMS[1:0]

DIR

OPM

URS

UDIS

CEN

 

ARR

PSC

 

 

 

接下来的4个实验跟输出通道有关系

实验2

TIMER-2:强置输出

现象:LED 常亮

例子比较简单关键是配好输出通道

CCER

15 14   13    12 11 10        8    7  6          3 2       0

 

 

CC4P

CC4E

 

 

CC3P

CC3E

 

 

CC2P

CC2E

 

 

CC1P

CC1E

 

 

 

CCMR(输出)

OC2CE 

OC2M[2:0]

OC2PE

OC2FE

CC2S

OC1CE

OC1M[2:0]

OC1PE

OC1FE

CC1S

 

将通道1配为输出,输出使能,输出极性选择好,输出模式选择好就可以了。在V100实验板上PC6-9接了LED,刚好对应着TIMER3重映射后的输出,注意程序里的AFIO函数。

实验3

TIMER-3:输出比较

现象:LED 2秒的周期闪烁。

跟上个实验配置大致相同,只是把输出模式改为翻转功能,并且CRR要配好,当CRR=CNT时翻转输出。

实验4

TIMER-4:PWM输出

现象:输出4种不同占空比的PWM波,4个LED亮度不同。

实验5

TIMER-7:单脉冲方式

现象:LED 只闪烁一次。

将上个实验加一句话

TIM_SelectOnePulseMode(TIM3, TIM_OPMode_Single);     //设置单脉冲模式

就是这个实验。其实手册上关于此实验的本意是由一个外部触发使能计数器,然后产生一个脉冲的,这里还没涉及从模式所以简化处理。[page]

涉及寄存器

         CR1                                                         

        9    8     7      6    5    4    3    2     1     0

 

 

 

 

 

 

CKD[1:0]

ARPE

CMS[1:0]

DIR

OPM

URS

UDIS

CEN

 

 

 

 

 

接下来再做两个输入的实验

实验6

TIMER-5:输入捕获模式。

现象:通过V100 的JOYSTICK键的SELECT键进入捕获,硬件仿真看CRR的值。

首先是基本的配置:ARR的值、时钟PSC、采样CKD、计数方式。

然后配置输入通道。

选择输入捕获模式、输入极性、把T1配到CC1上、选好输入的滤波跟分频,就可以了。

讲下输入滤波功能,在此实验中Fdts=CK_INT/2,Fsample=Fdts/4,所以定时器时钟为2K,所以采样周期为4ms。才8次的话周期小于32ms的干扰会滤除。

相关寄存器

         CR1                                                         

        9    8     7      6    5    4    3    2     1     0

 

 

 

 

 

 

CKD[1:0]

ARPE

CMS[1:0]

DIR

OPM

URS

UDIS

CEN

PSC

ARR

CCMR1(输入)

 IC2F[3:0]

IC2PSC[1:0]

CC2S[1:0]

IC1F[3:0]

IC1PSC[1:0]

CC1S[1:0]

 

CCER

15 14   13    12 11 10        8    7  6          3 2       0

 

 

CC4P

CC4E

 

 

CC3P

CC3E

 

 

CC2P

CC2E

 

 

CC1P

CC1E

 

 实验7

TIMER-6:PWM输入

现象:由TIMER3输出通道1产生一路周期2秒占空比50%的PWM波,飞线到TIMER4的输入通道1,有TIMER4来测量该PWM得周期和占空比。

在做实验之前引入三种从模式控制:复位、触发、门控。通过SMCR选择后可以进入这三种从模式

 

 

SMCR

15    14      13   12       11 10  9  8      7    6    5   4   3    2   1  0

ETP 

ECE

ETPS[1:0]

ETF[3:0]

MSM

TS[2:0]

 

SMS[2:0]

 

 

SMS: 100      101      110

     复位     门控     触发

所谓从模式简单理解就是受控于别人了,包括何时启动、何时停止、何时复位。相关作用请看手册。提示一点就是进入这三种模式后时钟是谁的问题?肯定不是外部时钟1了,可以是内部时钟和外部时钟2.

接着看实验,PWM方式的原理是这样的,如前文提到过输入时可以把T1映射到CC1上去同时映射到CC2上,将CC1和CC2的捕获边沿搞成相反的,比如CC1捕获T1上升沿,CC2捕获T1下降沿,还要再设置T1为复位从模式,上升沿有效,这样T1上升沿后计数器开始计数。下降沿CC2捕获发生,此为PWM占空比,在来一个上升沿,CC1捕获发生此为PWM周期。注意CC1捕获的第一次无效。

这是从模式跟输入捕获的一种组合使用,从模式还可以跟输出比较组合使用。比如手册上的单脉冲实验。

 

接着做4个实验跟定时器的级联和定时器同步有关系,在实验前先得说说主模式的问题。在CR2寄存器中的MMS位决定了定时器的主模式方式,即决定TRGO.几种方式可以参看手册。要说明一点就是一个定期器既可以是主模式同时它也是从模式,这就好像你是一个中层干部一样,既可以领导别人同时又被别人领导,这个不冲突的。

简单介绍下4个实验。

实验8

TIMER-8: TIMER2作为TIMER3的分频器.

现象:LED以10秒周期闪烁。

TIMER3配置为PWM输出,但是始终有TIMER2的溢出时间频率来提供,其溢出频率为100Hz所以TIMER3 PWM的周期为10S.

实验9

TIMER-9:TIMER2来使能TIMER3.

现象:LD1前15秒以1秒的周期闪烁,后15秒熄掉,然后下个15秒再闪烁如此循环。

在这个实验里TIEMR3输出一个周期1秒的PWM波,仍然驱动LD1闪烁。同时从模式配成门控模式,TIEMR2将OC1作为TRGO,OC1是一个周期30S占空比50%的PWM波。

实验10

TIMER-10: IMER2启动TIMER3

现象:上电后延迟15秒LD1以1秒的周期闪烁。

此实验跟上个实验配置差不多只要把TIMER3有门控改为触发方式即可。

实验11

TIMER-11: TIMER4的通道1同时出发TIMER4和TIMER3两个定时器

现象:按下JOYSTICK 的“选择”键同时出发两个定时器开始。同时TIMER3驱动LD1以1秒周期闪烁。

 

以上4个实验实际上是主模式和从模式的组合以及主模式和外部时钟1的组合。其实根据自己的需要还可以做出多种组合,这就是STM32定时器强大的地方。

 

 

  最后多熟悉下库函数,关于TIM的库(2.0版本),本人认为有两点错误:

1、           TIM.C中CR1_CounterMode_Mask 的值为0x039F应该改为0x038F这样才能覆盖CR1的DIR位。

2、           TIM.C中TIM_PrescalerConfig函数原文

      if (TIM_PSCReloadMode == TIM_PSCReloadMode_Immediate)

  {

    TIMx->EGR |= TIM_EventSource_Update;

  }

  else

  {

TIMx->EGR &= TIM_EventSource_Update;

  }

  红色的这句好像不对吧?应该TIMx->EGR &=~ TIM_EventSource_Update;才对吧。

关键字:STM32  通用定时器  时钟选择  模式选择 引用地址:STM32通用定时器(时钟选择,模式选择)

上一篇:STM32中断管理函数
下一篇:STM32中断优先级(默认和不默认情况)

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

STM32睡眠模式低功耗(停止模式
目前stm32已经非常流行了,那么本文讨论下stm32低功耗模式,不多说先上手册内容! 这是英文文档 不好看懂是吧,下面看中文文档! 我对比了 STM32F0 和 STM32F1 两者进入低功耗是一样的,STM32F4的类似目前没有研究。 低功耗模式有三种, 1.睡眠模式,( CM3 内核停止,外设仍然运行)此功耗是最高的。 2.停止模式,(所有时钟都停止)此功耗较低,典型大概在20uA左右。 3.待机模式,( 1.8V 内核电源关闭)此功耗最低,典型大概在2uA左右。 如果不行那就看手册,上图 一般我们做开发大多都是选择停机模式,因为停机模式功耗较低。而且任一中断或事件都能唤醒,待机模式虽然功耗最低,也就
[单片机]
<font color='red'>STM32</font>睡眠<font color='red'>模式</font>低功耗(停止<font color='red'>模式</font>)
利用STM32高精度定时器实现PWM输出的实现原理
很多STM32系列的MCU内置高精度定时器,比方STM32F334、STM32G4、STM32H7等系列。利用高精度定时器实现PWM输出应该说是最基本的功能了。不过,在实际应用中,常有人觉得无法实现duty=0或duty=100%的PWM输出情形。这里以STM32F334的HRTIM为例,简单介绍下利用它实现PWM输出的实现原理。 STM32F334的HRTIM的功能框图如下,由一个MASTER定时器和ABCDE五个定时器单元组成。其中ABCDE五个定时器单元各可以产生2路输出信号,并支持互补输出。 先看看跟HRTIM有关的时钟。别的系列有支持向上、向下计数模式的。 在利用HRTIM中的定时器单元实现PWM输出时,基于不同
[单片机]
利用<font color='red'>STM32</font>高精度<font color='red'>定时器</font>实现PWM输出的实现原理
STM32的存储器映射
存储器映射是指把芯片中或芯片外的FLASH,RAM,外设,BOOT,BLOCK等进行统一编址。即用地址来表示对象。这个地址绝大多数是由厂家规定好的,用户只能用而不能改。用户只能在挂外部RAM或FLASH的情况下可进行自定义。 Cortex-M3支持4GB的存储空间,它的存储系统采用统一编址的方式; 程序存储器、数据存储器、寄存器被组织在4GB的线性地址空间内,以小端格式(little-endian)存放。由于Cortex-M3是32位的内核,因此其PC指针可以指向2^32=4G的地址空间,也就是0x0000_0000——0xFFFF_FFFF这一大块空间。见图1: 图1 Cortex-M3的存储器映射
[单片机]
<font color='red'>STM32</font>的存储器映射
STM32HAL库使用DAC输出任意指定电压
1-uart.c实现重定向,记得包含stdio.h int fputc(int ch,FILE* f) { uint8_t temp ={ch}; { HAL_UART_Transmit(&huart1,temp,1,2); } return HAL_OK; } 2-启动DAC转换 HAL_DAC_Start(&hdac1,DAC1_CHANNEL_2);//启动DAC转换 3-编写测试函数 //如果按键1按下 if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==GPIO_PIN_RESET) { HAL_Delay(100); i
[单片机]
STM32->EXTI
CM3最多240个中断,每个中断有自己的可编程的中断优先级(唯一对应的中断优先级寄存器)。由于CM3支持硬件中断嵌套,所以可以有256级的可编程优先级和256级中断嵌套。 STM32 目前支持的中断共为 84 个(16个内核+68个外部),16 级可编程中断优先级的设置(仅使用中断优先级设置 8bit 中的高 4 位)和16个抢占优先级(因为抢占优先级最多可以有四位数)。 __set_FAULTMASK(1); //关所有中断 NVIC_SystemReset(); //复位,在core_cm3.h里定义 上述代码通过__set_FAULTMASK(1)关闭所有中断,避免在执行NVIC_Sy
[单片机]
使用Keil MDK运行第一个STM32程序
1.1.1 使用Keil MDK运行第一个STM32F10X程序 在上一小节中已经详细介绍了使用Keil MDK和标准外设库创建一个工程的过程,下面将介绍基于这个工程来编写一个小程序,通过这个程序我们可以初步了解: l STM32标准外设库的简单使用过程 l STM32外设的使用方法和大致流程 l 程序的编译、链接、下载步骤 l 利用Keil MDK的在线仿真功能进行软件仿真的简要步骤 1. 程序的编写 (1)程序实现的功能 为了方便各位读者的入门和理解,这个小程序的功能非常简单,作为本书功能实践的第一个程序,其功能当然也是最为经典的“Hello World!”了,只不过不是简单的屏幕输出,而是利用硬件的串口进行输出,同时作为单片
[单片机]
使用Keil MDK运行第一个<font color='red'>STM32</font>程序
STM32 串口采用DMA方式接收数据
环境: 主机:WINXP 开发环境:MDK4.23 MCU:STM32F103CBT6 说明: 串口可以配置成用DMA的方式接收数据,不过DMA需要定长才能产生接收中断,如何接收可变长度的数据呢? 方法有以下3种: 1.将RX脚与一路时钟外部引脚相连,当串口一帧发完,即可利用此定时器产生超时中断.这个实时性较高,可以做到1个字节实时监测. 2.不改变硬件,开启一个定时器监控DMA接收,如果超时则产生中断.这个实时性不高,因为超时时间必须要大于需要接收帧的时间,精度不好控制. 3.STM32单片机有的串口可以监测总线是否处于空闲,如果空闲则产生中断.可以用它来监测DMA接收是否完毕.这种方式实时性很高. 本文采用第3种方式.在波
[单片机]
<font color='red'>STM32</font> 串口采用DMA方式接收数据
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