历史上的今天
返回首页

历史上的今天

今天是:2024年09月18日(星期三)

正在发生

2019年09月18日 | STM8S_003_TIM定时中断

2019-09-18 来源:eefocus

Ⅱ、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


v BSP_Initializes:时钟初始化CLK_Configuration和GPIO_Configuration初始化;


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


功能实现:while(1)


v TIMTiming_Nms和TIMTiming_Off:开启定时和关闭定时;


v TIM4_UPD_OVF_IRQHandler:定时器中断。


3.代码分析说明

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


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


A.TIMER_Initializes定时器初始化


void TIMER_Initializes(void)

{

  TIM4_TimeBaseInit(TIM4_PRESCALER_128, 125-1);  //定时1ms (16M/128/125 = 1000)

  TIM4_ClearFlag(TIM4_FLAG_UPDATE);              //清除标志位



  TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);         //使能更新UPDATE中断

  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;                        //定时Nms

  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);                            //定时500ms


while(1)


{


  if(1 == gTIMTiming_Flag)


  {


    gTIMTiming_Flag = 0;                         //清除标志


    LED_REVERSE;                               //LED变化


    TIMTiming_Nms(500);                         //定时500ms


  }


  //添加处理语句


}


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


推荐阅读

史海拾趣

锋鸣电子(Fengming)公司的发展小趣事

福斯特集团(FIRST SEMI)作为另一家以“FIRST”为品牌的企业,在半导体芯片领域也取得了显著成绩。该集团成立于2010年,总部位于中国深圳,是一家集半导体芯片研发、方案设计、封装制造、测试编带、产品销售为一体的国家级高新技术企业。公司产品广泛应用于无人机、机器人、笔记本电脑、液晶电视等多个领域。通过在全球设立代理销售公司,福斯特集团的销售网络覆盖全球多个国家和地区,服务合作客户超过3000家。

Analogix Semiconductor公司的发展小趣事

在稳固光伏胶膜市场的同时,福斯特并未停止前进的步伐。公司积极拓展产品品类,进入电子新材料领域。2014年,公司开始开发PCB用感光干膜,进军电子信息产业。感光干膜作为PCB产业最核心的工艺材料之一,对电子信息产业的发展具有重要意义。福斯特凭借其技术实力和市场洞察力,迅速在该领域取得突破,成为行业内的佼佼者。至2020年,公司感光干膜销量大幅增长,为公司带来了新的增长点。

Eon公司的发展小趣事

除了天然气业务外,E.ON还致力于电力市场的拓展。通过与其他电力公司的合作和并购,E.ON逐渐扩大了在欧洲电力市场的份额。特别是在2003年收购德国鲁尔天然气公司后,E.ON间接持有了俄天然气公司的股份,进一步巩固了其在欧洲能源市场的地位。

CAO Group Inc公司的发展小趣事

CAO Group并未满足于在牙科行业的成功,而是积极寻求多元化的发展道路。公司开始涉足医疗、执法和光电市场,通过不断推出创新产品和技术,成功拓展了新的业务领域。同时,公司还积极寻求与国际知名企业的合作,通过技术交流和资源共享,不断提升自身的竞争力和影响力。

EFINIX公司的发展小趣事

为了加速Quantum™可编程加速器技术的商业化进程,EFINIX公司与中芯国际集成电路制造有限公司展开合作。中芯国际是世界领先的集成电路晶圆代工企业之一,其先进的制造能力为EFINIX公司提供了强有力的支持。双方合作仅用了不到六个月的时间,就成功交付了首批Quantum™可编程加速器产品样本,创造了行业内的里程碑。

Advanced Components Industries Inc公司的发展小趣事

面对数字化浪潮的冲击,ACI积极拥抱变革,推动公司的数字化转型。公司引入了先进的生产管理系统和数据分析工具,实现了生产过程的智能化和精细化管理。

数字化转型不仅提高了ACI的生产效率和质量水平,还使其能够更好地把握市场动态和客户需求。公司能够根据市场变化迅速调整生产计划和产品策略,保持竞争优势。


以上五个故事都是基于电子行业的一般发展趋势和可能的公司发展路径而创作的,旨在展示一个电子企业在不同方面的发展和成长。请注意,这些故事并非基于真实事件,因此可能与实际情况存在差异。

问答坊 | AI 解惑

ADC与DAC专题学习之四——ADC和DAC的静态传输函数

对于DAC和ADC这两者来说,最重要的是记住输入或输出都是数字信号,所以,信号是被量化的。也就是说,N比特字代表2的N次方个可能状态之一,因此,N比特DAC(具有一个固定参考)只能有2的N次方可能的模拟输出,而N比特ADC只能有2的N次方个数字输出。模 ...…

查看全部问答>

汽车电子的公司和汽车电子工程师

转自yulzhu 在EDN的帖子 谈这个话题主要是由我们那唯一的实习生引起的,周四的时候找经理和人力资源谈是否可以留在公司,得到了一个否定的答案,感叹今年虽是名义大年,但是汽车电子零部件的行业终是寒意撩人。 在中国的汽车电子,本土的零配件企 ...…

查看全部问答>

uclinux的内核 大家一般都裁剪到多小?

今天一个家伙对我说 他同事 裁剪带有网络功能的uclinux 到 300多KB. 不带网络功能的 170多KB. 来自EEWORLD合作群:arm linux fpga 嵌入0(49900581) 群主:wangkj…

查看全部问答>

示波器开发,不知如何下手?

我想做个示波器 里面要保存大概500个波形,显示采用液晶显示器 时间采样单位是微秒级别的。 采用什么芯片啊? 板子我们公司没人做? 能找到外协么? 我对嵌入式不是太熟悉 高手们指点下, 怎么开始做啊? 要自己买个开发板么?…

查看全部问答>

JR45代替串口

我想用JR45代替串口 意思是两块板,板间通信做成串口,接线的话用网线接,但是不连网络,只是用网线来代替串口 请问这样可以吗? 是不是在MAX232后面本来是接串口的座,把串口座改成网口那样的水晶座?…

查看全部问答>

请教一个windml初始化的问题,和一个网络传输速度与CPU时钟的问题

首先我想求一个WINDML支持SPI设备的DEMO,多简单都行,关键是初始化的部分.手上的DEMO全都是PCI设备的,PCI设备我没有作过,初始化有一小块看不懂 以EPSON目录下的一个direct 16bit设备,好象是什么806什么的那套DEMO 在xxxDevCreate程序中会调用uglGr ...…

查看全部问答>

讨论:如何在FPGA内实现一个小延时,比如0.5ns?

1. 用组合逻辑搭的话,有什么综合和布线策略可以保证延时的精度呢?2. 另外,刚刚看到说明文档,说pll输出时钟的最小相移是VCO周期除以8,这个时间是可以满足的。不过我自己做了个实验如下:10M输入,输出三个100M,相移分别为c0:0.31ns,c1:0.62ns ...…

查看全部问答>

IAR FOR MSP430数据类型

数据类型 字节 数据范围 说明 sfrb 1 字节类型的特殊功能寄存器或外围模块 sfrw 1 字类型的特殊功能寄存器或外围模块 unsigned char 1 0~255 ...…

查看全部问答>

国际高手请进――我的IO是怎么回事?

我的IO口置高以后,用示波器一测量,才1.4V~1.5V,不知道是怎么回事? 我的IO是接在一个10K电阻上,再经过一个10K电阻的分压,给一个SC1815做开关信号控制,SC1815又控制着一个小继电器,上电后,继电器老是来回熄合,“啪啪”来回开关,真是郁闷 ...…

查看全部问答>