收藏 分享(赏)

STM8教程-第十三章 STM8S207 定时器模块及其应用实例.doc

上传人:精品资料 文档编号:8962374 上传时间:2019-07-18 格式:DOC 页数:8 大小:203.45KB
下载 相关 举报
STM8教程-第十三章 STM8S207 定时器模块及其应用实例.doc_第1页
第1页 / 共8页
STM8教程-第十三章 STM8S207 定时器模块及其应用实例.doc_第2页
第2页 / 共8页
STM8教程-第十三章 STM8S207 定时器模块及其应用实例.doc_第3页
第3页 / 共8页
STM8教程-第十三章 STM8S207 定时器模块及其应用实例.doc_第4页
第4页 / 共8页
STM8教程-第十三章 STM8S207 定时器模块及其应用实例.doc_第5页
第5页 / 共8页
点击查看更多>>
资源描述

1、第十三章 STM8S207 定时器模块及其应用实例这一节,我们将向大家介绍如何使用 STM8 的定时器中的基本定时功能,STM8 的定时器功能十分强大,有 TIM1 高级定时器,也有 TIM2、 TIM3 等通用定时器,还有 TIM4 基本定时器。在 STM8S 参考手册里面,定时器的介绍占了 1/3 的篇幅,足见其重要性。这一节,我们分别介绍 TIM1 到 TIM4 定时器中的基本定时功能。例程一、16 位高级控制定时器(TIM1) 简介: TIM1 由一个 16 位的自动装载计数器组成,它由一个可编程的预分频器驱动。 TIM1 有 4 个通道,分别是 1 到 4。分别对应于四个不同的捕获/

2、比较通道。 高级控制定时器适用于许多不同的用途: 基本的定时 测量输入信号的脉冲宽度(输入捕获 ) 产生输出波形(输出比较,PWM 和单脉冲模式) 对应与不同事件(捕获,比较,溢出,刹车,触发 )的中断 与 TIM5/TIM6 或者外部信号 (外部时钟,复位信号,触发和使能信号)同步 高级控制定时器广泛的适用于各种控制应用中,包括那些需要中间对齐模式PWM 的应用,该模式支持互补输出和死区时间控制。 高级控制定时器的时钟源可以是内部时钟,也可以是外部的信号,可以通过配置寄存器来进行选择。 这一节我们实现的功能是基本的定时,关于 PWM 的编程留下以后的章节中。还有建议大家研究更为深入的功能 T

3、IM1 的时基单元包括,如下图所示: 16 位向上 /向下计数器 16 位自动重载寄存器 重复计数器 预分频器16 位计数器,预分频器,自动重载寄存器和重复计数器寄存器都可以通过软件进行读写操作。 自动重载寄存器由预装载寄存器和影子寄存器组成。 可在在两种模式下写自动重载寄存器: 自动预装载已使能(TIM1_CR1 寄存器的 ARPE 位置位)。在此模式下,写入自动重载寄存器的数据将被保存在预装载寄存器中,并在下一个更新事件(UEV)时传送到影子寄存器。 自动预装载已禁止 (TIM1_CR1 寄存器的 ARPE 位清除)。在此模式下,写入自动重载寄存器的数据将立即写入影子寄存器。 更新事件的产

4、生条件: 计数器向上或向下溢出。 软件置位了 TIM1_EGR 寄存器的 UG 位。 时钟/触发控制器产生了触发事件。 在预装载使能时(ARPE=1),如果发生了更新事件,预装载寄存器中的数值(TIM1_ARR)将写入影子寄存器中,并且 TIM1_PSCR 寄存器中的值将写入预分频器中。 置位 TIM1_CR1 寄存器的 UDIS 位将禁止更新事件(UEV)。 计数器由预分频器的输出 CK_CNT 驱动,而 CK_CNT 仅在 IM1_CR1 寄存器的计数器使能位(CEN) 被置位时才有效。简要说明: CK_PSC 的时钟来源于 f_master,我们使用 16M 内部时钟源 HIS 然后可以

5、通过 PSCR 这个寄存器设置 CK_CNT,PSCR 是 2 个 8 位寄存器组成的 16 位寄存器,可以在 065535 之间任务分频,分频后的频率提供给 CK_CNT 我们的实验为了方便计算,CK_CNT 为 1K 的频率,所以 PSCR = 16M/1K = 16000,换成 16 进制为 0x3E80 我们使用了默认的向上溢出,所以为了 500ms 溢出中断一次,需要设置 ARPE这个定时器,而且设置为自动预装功能,这样就可以一直提供 2Hz 的频率中断 最后允许中断和计数器使能就可以实现我们的功能 有了以上的基础就可以进入到 TIM1 的基本定时器编程了,为了验证效果,我们采用了

6、LED0 作为判断依据。在 TIM1 的溢出中断服务程序中闪耀 LED0 程序代码如下: #include “iostm8s207rb.h“ #define LED1_FLASH PD_ODR_ODR0 = !PD_ODR_ODR0 void CLK_Init(void); void GPIO_Init(void); void TIM1_Init(void); void main( void ) CLK_Init(); GPIO_Init(); TIM1_Init();asm(“rim“); / 主循环里没有程序需要执行 while(1); void CLK_Init(void) CLK_CK

7、DIVR = 0x00; / 16M 内部 RC 直接输出 void GPIO_Init(void) PD_DDR = 0x01; / 配置 PD 端口的方向寄存器 PD0 输出 PD_CR1 = 0x01; / 设置 PD0 为推挽输出 PD_ODR = 0xFF; void TIM1_Init(void) TIM1_PSCRH = 0x3E; / 16M 系统时钟经预分频 f=fck/(PSCR+1) TIM1_PSCRL = 0x7F; / PSCR=0x3E7F, f=16M/(0x3E7F+1)=1000Hz /每个计数周期 1ms TIM1_ARRH = 0x01; / 自动重载寄

8、存器 ARR=0x01F4=500 TIM1_ARRL = 0xF4; / 每记数 500 次产生一次中断,即 500ms TIM1_IER = 0x01; / 允许更新中断 TIM1_CR1 = 0x01; / 计数器使能,开始计数 #pragma vector=TIM1_OVR_UIF_vector /0x0D _interrupt void TIM1_OVR_UIF(void) LED1_FLASH; TIM1_SR1 = 0; /清除中断标记,这步不能漏掉,否则会连续进入中断程序 编译下载后就可以看到 LED1 一闪一闪的,闪耀的频率我们设置是 2Hz,大家也可以设置不一样的定时时间,

9、我们只是简单介绍如何使用 TIM1 的基本定时功能例程 2、16 位通用定时器 TIM2、TIM3 TIM2/TIM3 的功能包括: 16 位向上计数和自动装载计数器 4 位可编程(可以实时修改的)预分频器,计数器时钟频率的分频系数为 132768 之间的2 的幂 3 个独立通道: 输入捕获 输出比较PWM 生成( 边缘对齐模式) 单脉冲模式输出 如下事件发生时产生中断: 更新:计数器向上溢出,计数器初始化(通过软件) 输入捕获 输出比较 和 TIM1 介绍一样,下面介绍时基单元 时基单元包含: 16 位向上计数器 预分频器 16 位自动装载寄存器 没有重复寄存器。 计数器使用内部时钟(fMA

10、STER) ,它由 CK_PSC 提供,并经过预分频器分频产生计数器时钟 CK_CNT。 预分频器 预分频器的实现: 预分频器基于 4 位寄存器控制的 16 位计数器,由于寄存器带有缓冲器因此可以随时修改预分频的数值。计数器可以取值为 1 到 32768 之间的 2 的幂进行分频。 计数器时钟频率的计算公式: fCK_CNT = fCK_PSC/2(PSCR3:0) 预分频器的值由预装载寄存器写入。一旦写入预装载寄存器的 LS 字节时,带有当前使用值的影子寄存器就被写入了新的值。 新的预分频值在下一个周期时生效(在下一个更新事件之后 )。 对 TIMx_PSCR 寄存器的读操作通过预装载寄存器

11、实现,因此可以随时读取不受限制。 TIM2、TIM3 与 TIM1 不同之处是预分频器并非在 065535 之间的认为分频系数,而是 1 到32768 之间 2 的幂进行分频。关于 TIM2 和 TIM3 的预分频寄存器如下:这次实验是 TIM2、TIM3 同时工作,因为预分频系数不能随意设置,所以为了计算方便,我们设置为 1024 分频,也就是 PSC = 0x0A,经过分频后的频率是 15.625K,也就是 0.064ms 因此 500ms/0.064 = 7813 转为 16 进制是 1E84,所以 1S 的定时是 3D08,有了这些参数就可以开始我们例程二的软件代码编写了#includ

12、e “iostm8s207rb.h“ #define LED1_FLASH PD_ODR_ODR0 = !PD_ODR_ODR0 #define LED2_FLASH PD_ODR_ODR1 = !PD_ODR_ODR1 #define LED3_FLASH PD_ODR_ODR2 = !PD_ODR_ODR2 void CLK_Init(void); void GPIO_Init(void); void TIM1_Init(void); void TIM2_Init(void); void TIM3_Init(void); void main( void ) CLK_Init(); GPIO

13、_Init(); TIM1_Init(); TIM2_Init(); TIM3_Init(); asm(“rim“); / 主循环里没有程序需要执行 while(1); void CLK_Init(void) CLK_CKDIVR = 0x00; / 16M 内部 RC 直接输出 void GPIO_Init(void) PD_DDR = 0x07; / 配置 PD 端口的方向寄存器 PD0 输出 PD_CR1 = 0x07; / 设置 PD0 为推挽输出 PD_ODR = 0xFF; void TIM1_Init(void) TIM1_PSCRH = 0x3E; / 16M 系统时钟经预分频

14、 f=fck/(PSCR+1) TIM1_PSCRL = 0x7F; / PSCR=0x3E7F TIM1_ARRH = 0x00; / 自动重载寄存器 ARR=0x00FA=250 TIM1_ARRL = 0xFA; / 每记数 250 次产生一次中断,即 250ms TIM1_IER = 0x01; / 允许更新中断 TIM1_CR1 = 0x01; / 计数器使能,开始计数 void TIM2_Init(void) TIM2_PSCR = 0x0A; /16M 系统时钟经预分频 f=16M/1024=15.625k TIM2_ARRH = 0x1E; /15.625k * 7813 =

15、500ms TIM2_ARRL = 0x84; TIM2_IER = 0x01; /运行更新中断 TIM2_CR1 = 0x01; /使能计数器 void TIM3_Init(void) TIM3_PSCR = 0x0A; /16M 系统时钟经预分频 f=16M/1024=15.625k TIM3_ARRH = 0x3D; /15.625k * 15626 = 1s TIM3_ARRL = 0x08; TIM3_IER = 0x01; /允许更新中断 TIM3_CR1 = 0x01; /使能计数器 #pragma vector=TIM1_OVR_UIF_vector /0x0D _interr

16、upt void TIM1_OVR_UIF(void) LED1_FLASH; TIM1_SR1 = 0; /这步不能漏掉,否则会连续进入中断程序 #pragma vector=TIM2_OVR_UIF_vector /0x0F _interrupt void TIM2_OVR_UIF(void) LED2_FLASH; TIM2_SR1 = 0; /这步不能漏掉,否则会连续进入中断程序 #pragma vector=TIM3_OVR_UIF_vector /0x11 _interrupt void TIM3_OVR_UIF(void) LED3_FLASH; TIM3_SR1 = 0; /这

17、步不能漏掉,否则会连续进入中断程序 编译下载后就可以看到 LED1、LED2、LED3 在不停闪耀,而且是 LED1 闪耀两次 LED2 才闪耀一次,LED2 闪耀两次 LED3 才闪耀一次。验证了我们的定时器正常工作了例程三、8 位基本定时器 TIM4 TIM4 简介 该定时器由一个带可编程预分频器的 8 位可自定重载的向上计数器组成,它可以用来作为时基发生器,具有溢出中断功能。本例程也是利用到这个功能。 TIM4 的主要功能 8 位向上计数的自动重载计数器 3 位可编程的预分频器(可在运行中修改) 中断产生 TIM4 的框图TIM4 的时钟选择 该定时器的时钟源是内部时钟 f_master

18、。该时钟源直接连接到 CK_PSC 时钟,CK_PSC时钟通过预分频器分频后给定时器提供 CK_CNT 时钟 预分频器 预分频器是基于由一个 3 位寄存器来控制的一个 7 位计数器。由于该控制寄存器是带缓冲的所以它可以再系统运行中被修改。可以分频计数器的时钟频率为 1 到 128 之间的 2的任意次幂。 简要说明: 因为这个定时器的最大分频系数才只有 128,就算分频 128 后还是相当高的频率,不善于我们观察 LED 的状态,所以我们通过设置 CLK_CKDIVR 的寄存器设置 HIS输出为 2M 的 f_master 我们采用的是 2M 内部时钟,所以 CK_PSC = 2M,经过 128

19、 分频后为 CK_CNT 为15.625k,也就是 0.064ms,所以就算 ARR 最大时,定时的时间也才 10 几个 ms,不便于我们观察。所有我们在中断服务程序中记录一定的次数才让 LED 改变状态一次 相比之下这个定时器的功能和操作都比较简单,我们的例程就是实现之前的功能,在定时器中断服务程序中改变 LED0 的状态,详细软件代码如下: 需要注意的时,IAR 编译器把 TIM4_SR1 修改成 TIM4_SR,在编写代码时希望记住 程序代码如下: #include “iostm8s207rb.h“ #define LED1_FLASH PD_ODR_ODR0 = !PD_ODR_ODR

20、0 void CLK_Init(void); void GPIO_Init(void); void TIM4_Init(void); void main( void ) CLK_Init(); GPIO_Init(); TIM4_Init(); asm(“rim“); / 主循环里没有程序需要执行 while(1); void CLK_Init(void) CLK_CKDIVR = 0x18; / 2M 内部 RC 直接输出 void GPIO_Init(void) PD_DDR = 0x01; / 配置 PD 端口的方向寄存器 PD0 输出 PD_CR1 = 0x01; / 设置 PD0 为

21、推挽输出 PD_ODR = 0xFF; void TIM4_Init(void) TIM4_PSCR = 0x07; / 2M 的 128 分频TIM4_ARR = 0x64; /6.4ms TIM4_IER = 0x01; / 允许更新中断 TIM4_CR1 = 0x01; / 计数器使能,开始计数 #pragma vector=TIM4_OVR_UIF_vector /0x19 _interrupt void TIM4_OVR_UIF(void) static unsigned char value = 0; if(value = 78) LED1_FLASH; value = 0; value+; TIM4_SR = 0; / 这步不能漏掉,否则会连续进入中断程序 编译下载后发现和 TIM1 的效果相当,但是同样的效果,TIM4 占用了更多的 CPU 使用时间,因为 TIM1 一次的中断, TIM4 要经过 78 次中断,所以效率不高。当然 TIM4 可以用在更短时间的编程,而我们只是一个例子说明 TIM4 的使用方法。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报