你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F030 Nucleo64开发板测评之:定时器中断

[复制链接]
黑夜之狼 发布时间:2016-11-22 16:00
本帖最后由 黑夜之狼 于 2016-11-22 16:00 编辑

在前面的两个帖子当中,我们介绍了GPIO和UART通信,这次,我们来介绍单片机里面很普遍也很重要的一个外设——定时器。

为什么说很普遍?现在的单片机最多的共同点就是:串口和定时器。串口未必每款单片机有,但是定时器基本上都有。
为什么说很重要?定时器的应用范围太广了,不说别的,单纯看STM32的参考手册,大家应该可以发现讲定时器的内容已经占了1/3(P220~467),可见其重要性!

STM32的定时器功能十分强大,F0系列的定时器分了高级定时器(TIM1)、通用定时器(TIM3/14/15/16/17)、基本定时器(TIM6/TIM7)三种。本次实验当中,我们将利用通用定时器TIM3中断来实现闪烁灯这个实验。

STM32F0的通用定时器是一个通过可编程预分频器(PSC)驱动的 16 位自动装载计数器(CNT)构成。可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM)等。 使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。每个通用定时器都是完全独立的,没有互相共享的任何资源。


主要功能如下图:(参考手册P294)
通用定时器TIM3主要功能.png

定时器TIM3中断的配置可以总结为以下几点:
(1)TIM3时钟使能
         TIM3是挂载在APB1上的,所以我们通过APB1总线下的使能时钟函数来使能TIM3,调用的库函数是:
  1. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);    //使能TIM3时钟
复制代码


(2)初始化定时器参数,设置自动重装值,分频系数,计数方式等
         初始化定时器参数是由库函数 TIM_TimeBaseInit 来实现的:
  1. void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)
复制代码
        第一个形参是选择用哪个定时器,第二个形参是定时器初始化参数的结构体指针,结构体类型为 TIM_TimeBaseInitTypeDef,我们可以打开 stm32f0xx_tim.h 这个文件看看这个结构体的定义:
  1. typedef struct
  2. {
  3. uint16_t TIM_Prescaler;
  4. uint16_t TIM_CounterMode;
  5. uint16_t TIM_Period;
  6. uint16_t TIM_ClockDivision;
  7. uint8_t TIM_RepetitionCounter;
  8. } TIM_TimeBaseInitTypeDef;
复制代码
         从上面代码可见,这个结构体有5个成员变量,但是,对于通用定时器来说,只有前面4个成员才有用,最后一个成员Tim_TimeBaseInitTypeDef只对高级定时器才有用的,这里就不多解释了,等到用高级定时器的时候才来分析吧。

针对TIM3初始化,具体配置代码如下:
  1. TIM_TimeBaseStructure.TIM_Period = arr;//设置在下一个更新事件装入活动的自动重装载寄存器周期的值
  2.         TIM_TimeBaseStructure.TIM_Prescaler = psc; //设置用来作为TIMx时钟频率除数的预分频值
  3.         TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
  4.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
  5.         TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);//根据指定的参数初始化TIMx的时间基数单位
复制代码
这里有arr和psc这两个形参,可以通过在main函数调用的时候作为输入形参使用。
中断时间的计算公式如下:
      Tout = ( (arr + 1) * (psc + 1) ) / Tclk
      Tclk:TIM3的输入时钟频率(单位:MHz)
      Tout:TIM3溢出时间(单位:us)
我们这里定时500ms,可以令arr = 4999,psc = 4799,Tclk = 48MHz
即:Tout = ( (4999 + 1) * (4799 + 1) ) / 48 = 500000us = 500ms



(3)设置TIM3允许更新中断
         因为这里我们需要利用TIM3的中断来实现闪烁灯,所以要允许TIM3产生中断更新,库函数如下:

  1. TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);        //使能指定的TIM3中断,允许更新中断
复制代码

(4)TIM3中断优先级设置
         既然使能了TIM3中断,那肯定要配置它的中断优先级了,具体代码如下:

  1. //中断优先级NVIC设置
  2.     NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;          
  3.         NVIC_InitStructure.NVIC_IRQChannelPriority = 3;
  4.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  5.         NVIC_Init(&NVIC_InitStructure);
复制代码


(5)使能TIM3
         这一点最简单,库函数如下:

  1. TIM_Cmd(TIM3, ENABLE);        //使能TIM3   
复制代码


(6)编写中断服务函数
         最后一步,千万不要忘了写中断服务函数(当然,你可以用查询方式,不用中断)!我们这里是更新(溢出)中断,在中断服务函数开头,首先要判断是否溢出,然后执行相关操作(这里是翻转GPIO输出状态),最后清除中断标志。具体代码如下:

  1. void TIM3_IRQHandler(void)
  2. {
  3.         if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
  4.         {       
  5.                 TIM_ClearITPendingBit(TIM3, TIM_IT_Update);  
  6.         LED2_Toggle();
  7.         }                        
  8. }
复制代码

通过以上几个步骤,我们就可以利用TIM3定时器中断功能实现对LED的状态翻转


上传工程代码:
STM32F030_TIM3.rar (2.04 MB, 下载次数: 198)

评分

参与人数 1 ST金币 +10 收起 理由
zero99 + 10

查看全部评分

收藏 3 评论4 发布时间:2016-11-22 16:00

举报

4个回答
assssdz 回答时间:2016-11-22 23:41:18
zero99 回答时间:2016-11-28 14:14:41
下来看看
花落莫相离 回答时间:2019-7-25 16:24:00
大神,你这个定时器可以用吗?为什么我这STM32F030CCT6这样设置不行啊?我看还有人需要设置TIM_PrescalerConfig(TIM3, TM3_PrescalerValue, TIM_PSCReloadMode_Immediate);这句话,不知道怎么回事啊。
黑夜之狼 回答时间:2019-7-26 08:58:00
花落莫相离 发表于 2019-7-25 16:24
大神,你这个定时器可以用吗?为什么我这STM32F030CCT6这样设置不行啊?我看还有人需要设置TIM_PrescalerCo ...

可以用,可以参考库函数里面的例程

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版