0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

STM8S_003_ TIM定时中断

黄工的嵌入式技术圈 来源:黄工的嵌入式技术圈 2020-03-20 10:46 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

写在前面 Ⅰ

上一篇文章讲述了TIM精确延时(阻塞式),它主要的特点是延时精确,而阻塞式延时在这一延时过程中不能做其它事情,只能等待延时结束。

在某些场合下,我们需要在延时的过程中也要进行其它操作,如在延时过程中需要检测某一个IO口的电平状态、检测某一按键是否处于按下状态等。这个时候我们简单的处理方法就是使用定时中断,一旦这个延时时间到就进行下一个操作。

本文将简单讲述如何实现TIM定时和中断,提供简单的例程源代码。

为方便大家阅读,本文内容已经整理成PDF文件:

http://pan.baidu.com/s/1i5uWhJR

TIM基础知识 Ⅱ

在上一篇文章中讲述了一些关于TIM的知识,本文说一下TIM中断相关知识。

TIM框图:

TIM4属于基本定时器,是8位计数的定时器,也就是说UP-COUNTER和Auto-reload register是8位的寄存器,最大值只能为255。

主系统时钟fMASTER进来,通过分频Prescaler给计数器UP-COUNTER计数,当计数器和Auto-reload register相等时,有一个事件更新(这就是上文的延时时间到),如果使能了事件更新中断,则会响应中断(UIF)。

这里再次强调一下,基本定时器的8位的定时器,最大值为255,如果不满足要求,可以使用16位的通用定时器。

软件工程源代码 Ⅲ

1、关于工程

本文提供的工程代码是基于前面软件工程“STM8S_Demo”增加TIM定时器修改而来。初学的朋友可以参看我前面对应的基础文章,那些文章讲的比较详细。

工程以简单、易理解为主,方便更多初学者快速理解,工程的大部分配置都是使用默认配置,具体配置可参看我的文章:IAR for STM8系列教程(一)_新建软件工程详细过程。

2.软件概要说明

坚持简单、基础、方便初学者理解为原则,本文提供软件工程中的源代码只添加了最简单的内容:

系统初始化:System_Initializes

vBSP_Initializes:时钟初始化CLK_Configuration和GPIO_Configuration初始化;

vTIMER_Initializes:定时器初始化,本文重点内容;

功能实现:while(1)

vTIMTiming_Nms和TIMTiming_Off:开启定时和关闭定时;

vTIM4_UPD_OVF_IRQHandler:定时器中断。

3.代码分析说明

关于BSP_Initializes中的内容这里不再详细说明,请见前面相关的文章:STM8S_001_GPIO基础知识

本文重点讲述关于TIM相关的内容:

A.TIMER_Initializes定时器初始化

void TIMER_Initializes(void)

{

TIM4_TimeBaseInit(TIM4_PRESCALER_128, 125-1);

TIM4_ClearFlag(TIM4_FLAG_UPDATE);

TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);

enableInterrupts();

}

我们提供的软件工程是实现1ms的延时,实现的公式为:16MHz /128/ 125 = 1KHz(1ms)。

第一个参数TIM4_PRESCALER_128:即128分频,这个参数为枚举类型,具体为如下:

typedef enum

{

TIM4_PRESCALER_1 = ((uint8_t)0x00),

TIM4_PRESCALER_2 = ((uint8_t)0x01),

TIM4_PRESCALER_4 = ((uint8_t)0x02),

TIM4_PRESCALER_8 = ((uint8_t)0x03),

TIM4_PRESCALER_16 = ((uint8_t)0x04),

TIM4_PRESCALER_32 = ((uint8_t)0x05),

TIM4_PRESCALER_64 = ((uint8_t)0x06),

TIM4_PRESCALER_128 = ((uint8_t)0x07)

} TIM4_Prescaler_TypeDef;

第二个参数125-1:这个参数的值,实际上的自动重载寄存器(Auto-reload register)的值,也是定时的周期值。从公式中可以看出,它是得出1ms延时的来源。

很多人不理解为什么125-1,而不是125呢?

原因很简单:计数是从0开始的,0至124就是计数125个,因此这里是124。

语句TIM4_ClearFlag(TIM4_FLAG_UPDATE):

这条语句的意思很简单,清除UPDATE更新标志位。

TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);

enableInterrupts();

如果我们需要在定时的时间到了之后响应中断,只需要配置这两条语句即可。(在中断函数里面添加需要的内容)

B.启动和关闭定时:TIMTiming_Nms / TIMTiming_Off

void TIMTiming_Nms(uint16_t Times)

{

gTIMTiming_Num = Times;

gTIMTiming_Flag = 0;

TIM4_SetCounter(0);

TIM4_Cmd(ENABLE);

}

void TIMTiming_Off(void)

{

gTIMTiming_Flag = 0;

TIM4_Cmd(DISABLE);

}

本文提供代码中定义了两个全局变量:

gTIMTiming_Num:定时计数(定时多少ms)

gTIMTiming_Flag:定时标志(0-无效 1-有效),也就是我们定时的时间到,有效的标志。

TIM4_SetCounter(0);

每次启动定时器之前,将计数值归零,这样才能保证第一次计数(延时)准确。

C.定时中断

INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)

{

TIM4_ClearITPendingBit(TIM4_IT_UPDATE);

gTIMTiming_Num--;

if(0 == gTIMTiming_Num)

{

TIM4_Cmd(DISABLE);

gTIMTiming_Flag = 1;

}

}

中断的入口INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23),位于stm8s_it.c文件下面,由系统决定,我们不用去修改。

每次进入中断,需要添加语句TIM4_ClearITPendingBit(TIM4_IT_UPDATE);清除中断标志位。后面的由我们自己添加,我这里为了方便测试,使用gTIMTiming_Num变量,这样可以使定时时间为1ms的倍数。

D.具体实现功能

TIMTiming_Nms(500);

while(1)

{

if(1 == gTIMTiming_Flag)

{

gTIMTiming_Flag = 0;

LED_REVERSE;

TIMTiming_Nms(500);

}

//添加处理语句

}

这里实现的功能比较简单,定时500ms改变LED的状态。在这里可以添加自己的处理语句(如检测某一IO状态···)。

下载 Ⅳ

STM8S资料:

http://pan.baidu.com/s/1o7Tb9Yq

软件源代码工程(STM8S-A03_TIM定时中断):

http://pan.baidu.com/s/1c2EcRo0

提示:如果网盘链接失效,可以微信公众号“底部菜单”查看更新链接。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Tim
    Tim
    +关注

    关注

    0

    文章

    84

    浏览量

    18892
  • 源代码
    +关注

    关注

    96

    文章

    2953

    浏览量

    69652
  • STM8S
    +关注

    关注

    16

    文章

    149

    浏览量

    32523
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    串口超时中断的原理与特点

    时中断 (Timeout Interrupt - RTO, Receiver Timeout) 触发条件: 当最后一次成功接收到一个字符后(RXNE 事件后),在预设的超时时间内没有接收
    发表于 11-17 07:42

    脉冲编码器TIM3中断不生效是怎么回事?

    的encoderdemo后获取的圈数一直为0 配置TIM3定时器来读取编码器圈数值,通过debug pluse encoder已经初始化成功,TIM3中断也设置成功,但运行后deb
    发表于 09-22 06:23

    请问如何使用 UART RX 超时中断

    如何使用 UART RX 超时中断
    发表于 08-27 06:07

    请问如何使用 UART RX 超时中断

    如何使用 UART RX 超时中断
    发表于 08-21 06:28

    第二十二章 TIM——高级定时

    本章介绍了W55MH32的高级定时器(TIM1和TIM8),其含时基单元等,具备输入捕获、输出比较、PWM生成等功能,还支持互补输出、死区插入等,适用于工业电机控制,也提及相关配置结构体。
    的头像 发表于 06-20 13:58 1398次阅读
    第二十二章 <b class='flag-5'>TIM</b>——高级<b class='flag-5'>定时</b>器

    第二十章 TIM——基本定时

    本章介绍了W55H32基本定时TIM6、TIM7,16位向上计数,含时钟源、预分频器等,讲解定时计算及初始化结构体。
    的头像 发表于 06-20 13:51 899次阅读
    第二十章 <b class='flag-5'>TIM</b>——基本<b class='flag-5'>定时</b>器

    STM8S003为什么无法检测到引脚电平?

    目前以STM8S003F芯片做作为主机MCU 控制从机Elmos524.09超声波雷达芯片,做一款汽车倒车雷达系统;在开发时遇到了一点问题:主机与从机之间通过特定的IO引脚进行通讯,通过引脚低电平
    发表于 06-09 07:51

    STM8S003为什么无法检测到引脚电平?

    目前以STM8S003F芯片做作为主机MCU 控制从机Elmos524.09超声波雷达芯片,做一款汽车倒车雷达系统;在开发时遇到了一点问题:主机与从机之间通过特定的IO引脚进行通讯,通过引脚低电平
    发表于 05-28 06:30

    极海APM32F003触发NMI中断的解决方案

    问题:APM32F003F6P6 PC3配置成外部中断口,下拉触发之后没有进入EINTC_IRQHandler外部中断函数,反而一直触发NMI中断
    的头像 发表于 05-24 14:44 702次阅读
    极海APM32F<b class='flag-5'>003</b>触发NMI<b class='flag-5'>中断</b>的解决方案

    STM8S003无法检测到引脚电平怎么解决?

    目前以STM8S003F芯片做作为主机MCU 控制从机Elmos524.09超声波雷达芯片,做一款汽车倒车雷达系统;在开发时遇到了一点问题:主机与从机之间通过特定的IO引脚进行通讯,通过引脚低电平
    发表于 04-27 08:09

    STM8S003为什么无法检测到引脚电平?

    目前以STM8S003F芯片做作为主机MCU 控制从机Elmos524.09超声波雷达芯片,做一款汽车倒车雷达系统;在开发时遇到了一点问题:主机与从机之间通过特定的IO引脚进行通讯,通过引脚低电平
    发表于 04-25 06:59

    求助,关于stm8s003 adc中断和通道切换的问题求解

    ();//获取adc3转换结果}INTERRUPT_HANDLER(TIM2_UPD_OVF_BRK_IRQHandler, 13)//定时器2(2ms){ADC3_read();/*逻辑控制
    发表于 03-14 15:25

    为什么Tim2自动装载定时的首次中断时间总是设定时间的2倍?

    为何Tim2自动装载定时的首次中断时间总是设定时间的2倍?而后续中断均正常。反复修改了Tim2-
    发表于 03-07 06:23

    TMS320C672x DSP实时中断参考指南

    电子发烧友网站提供《TMS320C672x DSP实时中断参考指南.pdf》资料免费下载
    发表于 12-17 15:59 0次下载
    TMS320C672x DSP实<b class='flag-5'>时中断</b>参考指南

    瑞纳捷RJM8L003入门使用指南

    一、开发板介绍1.开发板原理图详情,请查看《RJM8L003MSB-P20_V1.pdf》,存放路径为RJM8L003资料包RJM8L003\4-硬件评估板
    的头像 发表于 12-07 01:09 1099次阅读
    瑞纳捷RJM<b class='flag-5'>8L003</b>入门使用指南