STM32之通用定时器

      广大的互联网的你们早上中午晚上、、又好、、没错了、、我又来了、、写博客不是定时的、、为何我要提写博客不是定时的呢??聪明的人又猜到我要说什么了吧、有前途、其实我仍是第一次听到定时器有通用和高级之分的、、原来定时器也有分等级的呀、、STM32果然不简单呀、、编程

     好了、、为啥名为通用呢?、恕小弟不才、目前只理解为:由于能够通用,因此名为通用定时器、那能够通用在哪些方面呢?那通用的原理又是什么呢?咦,不急不急、、待我慢慢翻开“葵花宝典”第STM32篇之通用定时器:葵花兄,近来可好?我们又见面了、能告诉我定时器能够通用在哪些方面吗?只见葵花兄不慌不忙的说:通用定时器能够用来:函数

一、测量输入信号的脉冲长度,也就是输入捕获(请对此四字短语养成良好的形象哈)编码

二、产生输出波形,也就是输出比较或者PWM(同上)
spa

     那葵花兄,通用的原理呢?又见葵花兄坦然自若的说:通用定时器是一个经过可编程预分频器(PSC)(注:这三个字母要有印象哈)驱动的16位自动装载计数器(CNT)(注:同上)构成。code

    好了,你们撇开葵花兄,把焦点从新聚焦在我身上、那通用定时器有什么功能呢?我想确定有人立刻反应:有定时的功能、、额、、我也不能说你错是吧、、那我来具体点吧,其实也不是我具体,多亏了“葵花宝典”第STM32篇中文参考手册  :blog

1) 16 位向上 、向下 、向上/向下自动装载计数器 (TIMx_CNT)。
2) 16 位可编程( 能够实时修改 )预分频器(TIMx_PSC)(TIMx_PSC)(TIMx_PSC),计数器时钟频率的分系为 1~ 65535 之间的任意数值。
3)4个独立通道( TIMx_CH1~4 TIMx_CH1~4 TIMx_CH1~4 TIMx_CH1~4)
A.输入捕获 
B.输出比较 
C.PWM 生成 (边缘或中间对齐模式 )
D.单脉冲模式输出
4)可以使用外部信号( TIMx_ETR )控制定时器和互连(能够用1个定时器控制另一个定时器)的同步电路。
5)以下事件发生时产生中断/DMA:
A.更新:计数器向上溢出/向下溢出,计数器初始化 ( 经过软件或者内部 /外部触发 )
B.触发事件  (计数器启动、中止初始化或者由内部/外部触发计数  )
C.输入捕获 
D.输出比较
E.支持针对定位的增量  (正交 )编码器和霍尔传感电路 
F.触发输入做为外部时钟或者按周期的电流管理事件

   固然啦,在此博客中不考虑那么多功能先哈、、先淡定、、如果被吓到了、、先去喝杯茶压压惊哈、、那咱们怎么来实现定时的功能呢?ip

只要定时、当达到必定容量时,就会发生溢出、、聪明的人又知道我要说什么了吧?世上太多聪明的人了、、没错了、、把中断这位兄弟叫上、让溢出兄和中断兄合身、、(省略合身等待的时间)、对了、诞生了溢出中断、咱们给取个好听的名字:更新中断在这里,咱们是利用中断来定时的、、同步

   接下来,容小弟介绍下与此博客有关系的寄存器(具体的位是什么功能我就不讲了哈,由于咱们是采用库而不是操做寄存器,想知道的能够参考中文参考手册哈),你们掌声响起:欢迎控制兄(TIMx_CR1)博客

 

 

欢迎中断/DMA使能兄(TIMx_DIER):

欢迎预分频器兄(TIMx_PSC):

欢迎自动重装载寄存器兄(TIMx_ARR):

好了、、这四位能够在旁边休息了(咱们就不介绍了)、、由于咱们的重点:库兄要出现了,接下来,用最热烈的掌声欢迎:

首先:有请挂载时钟大神ABP1(为何要请这位大神呢?由于咱们的通用定时器是挂载在这位ABP1的,证据以下)

再者,咱们有请第二大神:初始化大神:TIM_TimeBaseInit(为何是他呢?为何?到底是为何?啊哈、、请看)

看到了吧、、因此请不要怀疑大神的地位哈、、至于参数具体是哪些,你们能够打开#include "stm32f10x_tim.h"哈,在这里就很少说了、、相信你们都是聪明人、

前两位大神出来了,咱们还有大神、、哎、、大神无处不在、、来、有请类型中断使能大神

void TIM_ITConfig(TIM_TypeDef* TIMx, u16 TIM_IT, FunctionalState  NewState)

 

     看到中断、、你们又有想到什么猫腻没??条件发射就是这样炼成的、、没错了、、就是中断优先级设置大神啦、、这个你们应该有印象、我就不细说了哈,没印象的话这位大神可就要躲到某个角落伤心了,

     看到以上大神、、其实还有一位大神没出现、、此大神没出现、、其余大神啥都不是、、对了、就是定时器启动大神

      void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)

      好了、、最后,编写中断服务函数,在中断函数里检查中断标志位中断标志位,还有你想要作的事,相信你们也是比较熟悉的了、、

   在这里,咱们来谈谈时钟的问题、、你们能够看到系统时钟树图里:

    看到我美丽销魂的涂鸦没、、因为个人系统时钟初始化是36MHZ的、并且设置APB1的预分频系数为2,因此定时器的时钟就为72MHZ,你们能够根据本身的系统时钟设置选择哈、、

到此,咱们来总结下使用中断的定时器:

1.开启挂载在ABP1上的TIM3的时钟

2.对定时器进行初始化

3.设置中断类型

4.设置中断优先级

5.开启定时器3

6.编写中断服务函数 看一下参考代码:

 1 void Timer_3_Init(u16 arr,u16 psc)
 2 {
 3    
 4       //Tout = (arr + 1) * (psc + 1) / 72;    
 5     
 6       TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
 7       NVIC_InitTypeDef NVIC_InitStructure;
 8      
 9       RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);                           //1  此数字对应上面的步骤
10        
11       TIM_TimeBaseStructure.TIM_Period = arr;    //这个值在0~65535之间 为16位计数值   //2
12       TIM_TimeBaseStructure.TIM_Prescaler = psc;  
13       TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
14       TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
15       TIM_TimeBaseInit(TIM3, & TIM_TimeBaseStructure);
16       
17       TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE );                                    //3
18     
19       NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;                                //4
20       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
21       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
22       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;    
23       NVIC_Init(&NVIC_InitStructure); 
24       
25     TIM_Cmd(TIM3, ENABLE);                                                         //5
26 }
27 
28 void TIM3_IRQHandler(void)                                                         //6 
29 {
30     if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)
31         {            
32         TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
33         LED1 = !LED1;
34         }   
35 }

好了、、说到这里、、通用果真是通用的、、对于全部的通用定时器都是一样的原理、、在这里咱们只是实现了简单的定时(值加到某个程度就更新产生中断,经过LED灯显示)、、但愿你们多多指教、、本博客比较滑稽、、望你们莫怪哈、、有什么说错的地方请像抓腐败那样提出来哈、、我虚心向您请教、、谢谢你们、、

相关文章
相关标签/搜索