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

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

3天内不再提示

STM8S_002_TIM精确延时 (阻塞式)

黄工的嵌入式技术圈 来源:黄工的嵌入式技术圈 2020-03-20 10:51 次阅读

建议下载PDF和Demo软件工程学习

写在前面 Ⅰ

在某些特定场合,需要精确的延时(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

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

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

功能实现:while(1)

3.代码分析说明

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

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

A.TIMER_Initializes定时器初始化

voidTIMER_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)

voidTIMDelay_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

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

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

    关注

    1

    文章

    167

    浏览量

    33689
  • Tim
    Tim
    +关注

    关注

    0

    文章

    81

    浏览量

    17892
  • STM8S
    +关注

    关注

    16

    文章

    149

    浏览量

    31406
收藏 人收藏

    评论

    相关推荐

    socket阻塞和非阻塞的区别是什么

    在计算机编程中,socket 是一种通信端点,用于在网络中进行数据传输。Socket 可以是阻塞的或非阻塞的,这两种模式在处理数据传输时有不同的行为。 阻塞模式(Blocking Mode) 在
    的头像 发表于 08-16 11:13 651次阅读

    为什么STM8STIM4一直进不了中断?

    TIM4->SR中的中断标志位UIF=1后,就一直没有被清楚,说明一直没有进中断。。。麻烦各位大侠帮忙解答一下,STM8S的资料实在是太少了。。。手册都写的很模糊。。。
    发表于 05-15 06:18

    stm8s105s4 TIM1的CH4输出进行同时采样,为什么不能同步?

    MCU:stm8s105s4 准备实现功能:TIM1,PWM中央对齐模式,CH1~3用于产生PWM; CH4用于产生同步信号触发ADC采样; 思路描述:CH4的CCiF进入中断,在中断里查询如果是
    发表于 05-13 07:01

    请问STM8S105k4的TIM2_CH2通道可以配置出触发TIM1定时器吗?

    各位大神: 请问STM8S105k4的TIM2_CH2通道可以配置出触发TIM1定时器吗? 求救··· 操作寄存器配置···
    发表于 05-13 06:43

    STM8S003 TIM1没PWM输出的原因?

    用的是STM8S003的IC,然后配置TIM1没PWM输出,TIM2就可以输出,请教各位这是什么原因 TIM1_EGR |= 0x01;//重新初始化
    发表于 05-10 07:45

    stm8s003的tim1一直发不了脉冲的原因?

    各个大哥好,stm8s003的tim1一直发不了脉冲,程序如下: void TIM1_init(void) { TIM1_DeInit(); TIM
    发表于 05-10 06:10

    STM8STIM1 PWM输出不了是什么原因导致的?

    1、我参考了 STM8S_StdPeriph_LibProjectSTM8S_StdPeriph_ExamplesTIM1TIM1_7PWM_Output的例程 2、照着库函数提供的去写,并没有
    发表于 05-08 06:10

    STM8S延时问题怎么解决?

    我的延时函数,本来很精准,100us的时候示波器测试没问题,但是在STLink设置中,勾选 擦除 命令后,延时函数就不准了,100us示波器中大概有133us的样子,有没有大神解释下是什么原因导致的?
    发表于 05-07 08:20

    stm8S105进不了TIM2中断的原因?怎么解决?

    测试一个stm8s105的tim2延时函数,但总是进不了中断。麻烦大家帮我看看问题出在哪里。多谢了!代码简化了,方便大家查看。之前试过是可以的,但后来不小心改动程序,一下子晕头了,怎么搞都不对
    发表于 05-07 06:02

    STM8S TIM4中断一开,程序异常怎么解决?

    使用内部时钟16M ,1分频,TIM4定时8us,初始化程序如下: CLK->PCKENR1 = (uint8_t)(0x1C);//使能定时器和串口 TIM4->
    发表于 04-28 06:52

    STM8S007C8TIM2如何配置才能输出单脉冲?

    各位大神,请问你STM8S007C8TIM2如何配置才能输出单脉冲?因为TIM2没有SMCR寄存器,怎样才能和TIM1一样设置MSM、TS和SMS呢?正在郁闷中,请各位赐教。谢谢!
    发表于 04-19 07:35

    STM8S003F3用TIM2可以输出PWM,用TIM1就没用是怎么回事?

    求救!STM8S003F3用TIM2可以输出PWM,用TIM1就没用,本来打算输出互补的PWM,结果连PWM 都输出不了,用的软件是STVD的,在网上看到说要配置字,如果要的话又怎么
    发表于 04-19 07:20

    为什么STM8S003F3进不了TIM1中断?

    ); TIM1_ITConfig(TIM1_IT_UPDATE , ENABLE); TIM1_Cmd(ENABLE); } stm8s_it.c 的中断入口: INTERRU
    发表于 04-12 08:20

    什么是阻塞和非阻塞

    什么是阻塞和非阻塞?我们就用管道的读写来举例子。
    的头像 发表于 03-25 10:04 495次阅读

    STM8S tim1__ch3 trg触发不了adc中断怎么解决?

    STM8S tim1__ch3 trg触发不了adc中断,请求讲解
    发表于 03-07 06:16