STM32菜鸟成长记录---普通定时器应用

yx_l128125 2012-08-17 23:14:52  59040  收藏 8

分类专栏: 嵌入式 ARM 文章标签: timer function 编程 cmd output input

版权

一、STM32通用定时器原理

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

下图是STM32参考手册上时钟分配图中,有关定时器时钟部分的截图:

从图中可以看出,定时器的时钟不是直接来自APB1或APB2,而是来自于输入为APB1或APB2的一个倍频器,图中的蓝色部分。

下面以通用定时器2的时钟说明这个倍频器的作用:当APB1的预分频系数为1时,这个倍频器不起作用,定时器的时钟频率等于APB1的频率;当APB1的预分频系数为其它数值(即预分频系数为2、4、8或16)时,这个倍频器起作用,定时器的时钟频率等于APB1的频率两倍。

可能有同学还是有点不理解,OK,我们举一个例子说明。假定AHB=36MHz,因为APB1允许的最大频率为36MHz,所以APB1的预分频系数可以取任意数值;

当预分频系数=1时,APB1=36MHz,TIM2~7的时钟频率=36MHz(倍频器不起作用);

当预分频系数=2时,APB1=18MHz,在倍频器的作用下,TIM2~7的时钟频率=36MHz。

有人会问,既然需要TIM2~7的时钟频率=36MHz,为什么不直接取APB1的预分频系数=1?答案是:APB1不但要为TIM2~7提供时钟,而且还要为其它外设提供时钟;设置这个倍频器可以在保证其它外设使用较低时钟频率时。

Stm32外设用户手册,如图:

再举个例子:当AHB=72MHz时,APB1的预分频系数必须大于2,因为APB1的最大频率只能为36MHz。如果APB1的预分频系数=2,则因为这个倍频器,TIM2~7仍然能够得到72MHz的时钟频率。能够使用更高的时钟频率,无疑提高了定时器的分辨率,这也正是设计这个倍频器的初衷。

二、STM32通用定时器编程

定时器编程,就是中断的编程。因为使用定时器必定要使用到中断。

步骤一:RCC_Configuration();//设置系统时钟,包括时钟RCC的配置,倍频到72MHZ。

步骤二: GPIO的配置,使用函数为GPIO_cfg();,该函数的实现如下:

void GPIO_cfg(){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 |RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD , ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;                 //选择引脚6GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出频率最大50MHzGPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //带上拉电阻输出GPIO_Init(GPIOC,&GPIO_InitStructure);}

实际上定时器的讲解,不需要配置GPIO的引脚,只是我们在定时器实验中,

使用每隔一秒点亮一次LED灯来做实验,所以需要配置对应GPIO的引脚。

步骤三:嵌套中断控制器的配置,我们照样使用函数NVIC_Config();只是初始化的过程略有不同。这里我们也把函数实现列出来:

从以上函数实现来看,实际上只是改动了结构体成员NVIC_IRQChannel的值,现在需要的通道是TIM2的通道,因此初始化值为TIM2_IRQChannel。从这里也可以看出,这个函数实际上可以看做一个模型,可以拿去别的程序中改动后直接使用。

void NVIC_cfg(){NVIC_InitTypeDef NVIC_InitStructure;//选择中断分组1NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//选择TIM2的中断通道NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;     //抢占式中断优先级设置为0NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//响应式中断优先级设置为0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//使能中断NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}

步骤四:定时器的初始化配置,使用Timer_Config();。OK,关键部分出来了。

我们来看下实现过程:

TIMER_cfg(); //定时器的配置//开启定时器2TIM_Cmd(TIM2,ENABLE);voidTimer_Config(void)
{ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); TIM_DeInit(TIM2);TIM_TimeBaseStructure.TIM_Period=2000-1;  //自动重装载寄存器的值TIM_TimeBaseStructure.TIM_Prescaler=(36000-1);         //时钟预分频数TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;  //采样分频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);                              /开启时钟} 

我们每个语句都来解释一下。首先我们想使用定时器,就必须使能定时器的时钟,这就是函数 RCC_APB1PeriphClockCmd();,通过它开启 RCC_APB1Periph_TIM2。

TIM_DeInit(TIM2);该函数主要用于复位TIM2定时器,使之进入初始状态。

然后我们对自动重装载寄存器赋值,TIM_Period的大小实际上表示的是需要经过TIM_Period次计数后才会发生一次更新或中断。接下来需要设置时钟预分频数TIM_Prescaler,这里有一个公式,我们举例来说明:例如时钟频率=72MHZ/(时钟预分频+1)。说明当前设置的这个TIM_Prescaler,直接决定定时器的时钟频率。通俗点说,就是一秒钟能计数多少次。比如算出来的时钟频率是2000,也就是

一秒钟会计数2000次,而此时如果TIM_Period设置为4000,即4000次计数后就会中断一次。由于时钟频率是一秒钟计数2000次,因此只要2秒钟,就会中断一次。

再往后的代码,还有一个需要注意的,TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;就是我们一般采用向上计数模式,即每次计数就会加1,直到寄存器溢出发生中断为止。最后别忘了,需要使能定时器!!

发生中断时间=(TIM_Prescaler+1)* (TIM_Period+1)/FLK

用上述公式可算出:发生中断时间 (2000-1+1)*(36000-1+1)/72000000=1 秒

步骤五:编写中断服务程序。同样需要注意的,一进入中断服务程序,第一步要做的,就是清除掉中断标志位。由于我们使用的是向上溢出模式,因此使用

的函数应该是:TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);。

STM32开发板实现的中断服务程序如下:

每隔一秒,发生中断时,进入此中断函数执行程序,让LED闪一下,此中断程序所在文件stm32f10x_it.c

/******************************************************************************** Function Name  : TIM2_IRQHandler* Description    : This function handles TIM2 global interrupt request.* Input          : None* Output         : None* Return         : None******************************************************************************/void TIM2_IRQHandler(void){u8 ReadValue;if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)    //检测是否发生溢出更新事件{<span style="color:#ff0000;">TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);//清除TIM2的中断待处理位</span>              //UART2_TX485_Puts("123450");/*调试定时器测试*/ReadValue = GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_6);if(ReadValue == 0)                   //若该端口当前为低电平,{GPIO_SetBits(GPIOC,GPIO_Pin_6);//将其改为高电平输出 ;}    else                            //若该端口当前为高电平,{GPIO_ResetBits(GPIOC,GPIO_Pin_6);   //将其改为低电平输出;}}        }

普通定时器工作原理图

编译完成的代码下载在我的资源:http://download.csdn.net/detail/yx_l128125/4508425

https://blog.csdn.net/yx_l128125/article/details/7879506

STM32通定时器时间设置步骤和计算公式方法寄存器值相关推荐

  1. 域控服务器里没有internet时间,server2008r2域控时间设置internet时间同步的方法

    windows server 2008 r2成为域控后,时间设置里的,internet时间就没有了,为了解决这个问题,用以下CMD命令可解决: w32tm /config /manualpeerlis ...

  2. Spring定时器--时间设置规则

    单纯针对时间的设置规则 org.springframework.scheduling.quartz.CronTriggerBean允许你更精确地控制任务的运行时间,只需要设置其cronExpressi ...

  3. quartz定时器时间设置规则

    单纯针对时间的设置规则 org.springframework.scheduling.quartz.CronTriggerBean允许你更精确地控制任务的运行时间,只需要设置其cronExpressi ...

  4. java 定时器时间设置_如何在Java中设置定时器?

    所以答案的第一部分是如何做主题要求的事情,因为这是我最初对它的解释,有几个人似乎觉得很有帮助.这个问题后来被澄清了,我已经扩展了答案来解决这个问题. 设置计时器 首先,您需要创建一个计时器(我使用的是 ...

  5. Windows将时间设置到秒的方法

    使用win10系统的用户应该都发现了,Win10系统右下角时间只显示到分,不会显示到秒,如果想要看到秒的话,需要点击一下时间才会弹出.那么,Win10系统时间怎么显示到秒? 默认情况下,需要点击后方可 ...

  6. JavaScript循环定时器的设置和取消

    启动循环定时器-setInterval() 循环定时器,调用一次就会创建并循环执行一个定时器. 格式: setInterval(调用方法,毫秒值); //毫秒值:  循环周期 示例: 效果:(每隔一秒 ...

  7. stm32关于通用定时器的周期、频率计算公式

    以下内容针对正点原子的定时器中断实验 定时器时基单元包含: ● 计数器寄存器(TIMx_CNT) ● 预分频器寄存器 (TIMx_PSC)--该寄存器用设置对时钟进行分频,然后提供给计数器,作为计数器 ...

  8. stm32关定时器_STM32定时器中断设置方法

    今天调试了STM32的定时器功能,STM32定时器比较多,但调试都是一样的,寄存器都是一一对应的.就拿TIM2举例说明.在网上搜了好多关于定时器的设置,但大多数都是一个版本,而且都是针对库函数操作的, ...

  9. 广告牌定时器怎么设置时间_招牌定时器怎么设置时间?简单吗?

    夜晚,会有很多闪烁的广告招牌,其实很多招牌都是有灯光控制的,合理设置好时间也是可以节约开支的.想要拥有发光招牌的商家,确实是有必要了解一下招牌定时器的设置,那么,广告招牌定时器怎么设置时间呢?步骤繁琐 ...

最新文章

  1. 前端学习记录 JS DOM
  2. SpringBoot使用Redis和MyBatis完成缓存数据的增删改查
  3. matlab中fir1中的边界频率,FIR滤波器的MATLAB设计与实现.pdf
  4. Mac os 10.15配置Java14和Eclipse环境
  5. sql简介_SQL简介
  6. 关于Access数据库安全
  7. 数据资产管理:大数据时代的新风口
  8. java读取串口设备信息_Java--串口之间的通信及扫描枪的读取
  9. java组件名词解释_简述Java EE三类组件的构成及运行环境。
  10. 箭头函数写法_初探ES6:箭头函数
  11. 【数据分析能力是指什么?】
  12. IDEA整合SSM框架 applicationcontext in module file is included in 5 contexts
  13. C/C++实现贪吃蛇游戏
  14. 微信QQ在线客服基本功能介绍
  15. 通信科技人员职业道德
  16. 模板:求图的强连通分量(SCC)
  17. 学习笔记——OFDM仿真课设
  18. 京东到家订单派发的技术实战
  19. 杰理之VM 概述【篇】
  20. 苹果手机圆圈在哪里设置_不知道苹果手机录音在哪里?那你就落伍了

热门文章

  1. 期末复习----习题
  2. JS中[].slice.call的理解
  3. 什么是响应式布局设计?
  4. PS动作一键设计数字科技未来海报效果
  5. C语言:二维数组:求平均数
  6. 机柜风扇 的组成及如何正确安装 机柜散热风扇
  7. Bladed 时序风况配置方法
  8. 如何用python抓取文献_浅谈Python爬虫技术的网页数据抓取与分析
  9. Java网页数据抓取实例
  10. 一款安全好用的SSH客户端工具