历史上的今天
返回首页

历史上的今天

今天是:2025年02月16日(星期日)

正在发生

2020年02月16日 | STM8S_002_TIM精确延时(阻塞式)

2020-02-16 来源:eefocus

Ⅰ、写在前面

在某些特定场合,需要精确的延时(us级),特别是底层驱动。如果使用软件延时,延时会随系统时钟改变及各种因素影响而改变。因此,就需要使用TIM精确延时。


阻塞式延时:从延时开始至结束,程序一直阻塞在那里,不会跳转到其他地方(除中断)执行程序。不理解的朋友可以自己网上搜索答案。


TIM的种类和功能很多,本文是基础的知识,讲的比较简单,关于定时器更加强大和实用的功能可以关注我后面的文章。


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


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


Ⅱ、TIM基础知识

STM8S的定时器(TIMER)类型有三类:基本定时器、通用定时器和高级定时器。基本定时器是8位计数的定时器,通用和高级定时器是16位计数的定时器。


定时器因类型不同,其功能和复杂程度不同,适用的场合也不同。本文以最基础、最简单的8位基础定时器来讲述TIM的延时。


强调一点:8位计数定时器,最大计数值为256。

TIM4基础定时器功能:


Ø 8位向上计数(UP-COUNTER)的自动重载计数器;


Ø 3位可编程的预分配器Prescaler(可在运行中修改),提供1, 2, 4, 8, 16, 32, 64 和128这8种分频比例。


Ø 中断产生:若使能了中断,在计数器更新时(计数器溢出)产生中断,本文未开启中断。


Ⅲ、软件工程源代码

1、关于工程

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


软件工程源代码实现功能:通过阻塞式延时(500ms)改变LED亮灭状态来观察延时的大小。若要测量延时的精确性,可以将TIMDelay_Nms(500)改为其他TIMDelay_N10us(10)(延时100us),通过示波器测量LED引脚的频率为5KHz(周期为200us)。


2.软件概要说明

本文提供软件工程中包含的内容比较简单:


系统初始化:System_Initializes


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


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


功能实现:while(1)


3.代码分析说明

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


本文重点讲述bsp_timer.c文件的内容:


A.TIMER_Initializes定时器初始化


void TIMER_Initializes(void)


{


  TIM4_TimeBaseInit(TIM4_PRESCALER_2, 79);


  TIM4_ClearFlag(TIM4_FLAG_UPDATE);


}


我们提供的软件工程是实现10us的延时,实现的公式为:16MHz / 2 / (79+1) = 0.1MHz(100KHz)。


第一个参数TIM4_PRESCALER_2:即2分频,这个参数具体为如下:


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;


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


很多人不理解为什么不是80,而是79呢?


原因是计数是从0开始的,0至79就是计数80个,因此这里是79。


语句TIM4_ClearFlag(TIM4_FLAG_UPDATE):


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


B.延时N个10us:void TIMDelay_N10us(uint16_t Times)


void TIMDelay_N10us(uint16_t Times)


{


  TIM4_SetCounter(0);                             //计数值归零


  TIM4_Cmd(ENABLE);                            //启动定时器


  while(Times--)


  {


    while(RESET == TIM4_GetFlagStatus(TIM4_FLAG_UPDATE));


    TIM4_ClearFlag(TIM4_FLAG_UPDATE);


  }


  TIM4_Cmd(ENABLE);                             //关闭定时器


}


为什么是N个10us?


从上面定时器初始化可以知道,一个计数的过程(延时)是10us,参数Times代表要执行延时10us的次数。


TIM4_SetCounter(0);


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


while(RESET == TIM4_GetFlagStatus(TIM4_FLAG_UPDATE));


这一条语句代表程序在这里不停地读取更新标志位TIM4_FLAG_UPDATE(阻塞),直到读取标志位有效(计数满),则跳出这个while循环。


TIM4_ClearFlag(TIM4_FLAG_UPDATE);


清除更新标志位TIM4_FLAG_UPDATE。在上面标志位有效之后,需要清除,清除之后有进行下一个计数过程。


这里的启动和关闭定时器相信都能理解,从执行TIMDelay_N10us这一个函数开始到结束操作过程的开关。这里提醒一点:计数的过程的一个循环的过程,过程中尽量避免重复开关定时器(会有一定的耗时),我提供的TIMDelay_Nms其实严格来说不是很准确,该函数就是重复了开关。


C.具体实现功能


在main函数中的while里面就是本文源代码实现的具体功能,将一个LED灯(IO)高低交替输出,中间使用定时器比较精确的延时500ms,达到LED亮灭的效果。


代码:


while(1)


{


  LED_ON;                                      //LED亮


  TIMDelay_Nms(500);


  LED_OFF;                                     //LED灭


  TIMDelay_Nms(500);


}


这里TIMDelay_Nms函数严格来说存在一定的偏差,从上面的讲述,相信都知道如何修改来避免这样的误差。


Ⅳ、下载

STM8S资料:


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


软件源代码工程(STM8S-A02_TIM精确延时(阻塞式)):


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

推荐阅读

史海拾趣

GE Oil & Gas Digital Solutions公司的发展小趣事
根据前述方法提高电路精度,同时检查测量环境是否稳定(如温度、湿度等)以避免外部因素干扰测量结果。
启攀微电子(Chiphomer)公司的发展小趣事

启攀微电子(Chiphomer)公司成立于2003年,当时正值中国集成电路产业快速发展的初期。创始人张杨带领着一支由英美归国的留学精英和国内资深管理与技术人员组成的团队,立志要在这一领域闯出一片天地。然而,初创时期的资金短缺、技术壁垒和市场认可度低等问题,让公司面临着巨大的挑战。然而,他们凭借着对技术的执着追求和对市场的敏锐洞察,成功推出了首款SDH通信芯片,为公司的后续发展奠定了坚实的基础。

Bce Sud公司的发展小趣事

Bce Sud公司成立之初,专注于研发高效能的半导体芯片。面对市场上激烈的竞争,公司创始人凭借其在微电子领域的深厚积累,带领团队成功研发出一款具有低能耗、高稳定性的新型芯片,这一技术突破为公司在市场上打开了局面。随着这款芯片的推出,Bce Sud逐渐在电子行业树立了技术领先的形象。

ELM Technology Corporation公司的发展小趣事

在电子行业竞争日益激烈的背景下,ELM Technology Corporation展现出了卓越的市场拓展能力。公司管理层准确把握市场趋势,及时调整产品策略,积极拓展国内外市场。通过与国际知名企业的合作,ELM成功打入国际市场,其产品在多个国家和地区得到了广泛应用。同时,公司还积极寻求与国内企业的合作机会,共同推动电子行业的发展。

HB公司的发展小趣事

核心:Hartmann Codier GmbH一直将技术创新视为企业发展的核心动力。公司拥有一支专业的研发团队,致力于开关技术的研发与创新。通过不断的技术突破和产品升级,公司成功推出了一系列具有自主知识产权的高性能开关产品。

影响:这些创新产品不仅满足了市场对高品质、高可靠性开关的需求,还推动了整个电子行业的技术进步和产业升级。Hartmann Codier GmbH因此成为了行业内的技术引领者之一。

Advantech公司的发展小趣事

核心:Hartmann Codier GmbH一直将技术创新视为企业发展的核心动力。公司拥有一支专业的研发团队,致力于开关技术的研发与创新。通过不断的技术突破和产品升级,公司成功推出了一系列具有自主知识产权的高性能开关产品。

影响:这些创新产品不仅满足了市场对高品质、高可靠性开关的需求,还推动了整个电子行业的技术进步和产业升级。Hartmann Codier GmbH因此成为了行业内的技术引领者之一。

问答坊 | AI 解惑

LED数码管知识简介

replyreload += \',\' + 374455;Timson,如果您要查看本帖隐藏内容请回复…

查看全部问答>

請問可以同時插兩只CSR的Bluetooth dongle么?

現正在學習BCHS Application Demo,通信時需要兩臺PC,各插一只dongle,很不方便。請問可以在同一臺PC上插兩只dongle么。理論上是完全可行的,而且從設備管理器中也可以找到兩個設備(dongle),但不知道如何與應用程序關聯起來,應用程序只能同時打 ...…

查看全部问答>

关于Flash结构的几个问题

几个弱智问题 1 FLASH是多少位的是跟据地址线的根数来确定吗?FOR EXAMPLE? 2 所有NAND FLASH的结构都一样么?都是8根I/O口?那它是几位的? 3 CPU的位数根据什么确定的?地址线?PXA270  32位的,是32根地址线吧? 谢谢。。。!! ...…

查看全部问答>

嵌入式,项目,求救!

各位朋友,本人有一些Windows平台的C++开发经验,现在想做嵌入式,自己也有一块ARM的板子,搞过linux的bootloader和内核移植,但是却没有项目可以去学习。本来想去参加培训,可是没有时间。不知哪位朋友现在是否在开发什么项目,能否带小弟一起学习 ...…

查看全部问答>

airmouse+pc 遥控器

本帖最后由 jameswangsynnex 于 2015-3-3 19:57 编辑      最近本人设计了一款AIR MOUSE+PC遥控器,功能如下:        1. 2.4G无线传输:该产品一发一收,采用2.4G跳频技术以免干扰.传输距离:25米 &n ...…

查看全部问答>

【已解决】【有附件】大家来帮忙看看我的程序哪里错了...弄了好久都

这是小弟的毕业设计,做好了之后,总是在数码管那里出问题,也就是有d,e段不亮,导致2,3,5,6,8,9的显示都看不到......   弄了好久,刷新频率什么的,数码管的电流什么的都改过也出不了结果,可能是小弟哪里没弄好还是什么,所以上来请 ...…

查看全部问答>

请教高手一个usb stall的问题

最近发现在uhci控制器(6212)与3G数据卡数据交互大流量时会产生TD stall 错误,之后再插拔设备,uhci(6212)发送IRP请求失败,无法再读取设备信息   请教这可能是什么原因,有方法复位uhci吗?   我用的vxworks usb2.0驱动,在线等 ...…

查看全部问答>

大家如何实现o3

最近调试一个算法,用的是SSD的6720开发板,想用o3优化的时候程序就停在init_pll上,网友说是强制类型转换的问题。 大家是如何实现o3的,有什么心得…

查看全部问答>