最新STM8教程第十三章 STM8S207 定时器模块及其应用实例Word文件下载.docx
《最新STM8教程第十三章 STM8S207 定时器模块及其应用实例Word文件下载.docx》由会员分享,可在线阅读,更多相关《最新STM8教程第十三章 STM8S207 定时器模块及其应用实例Word文件下载.docx(11页珍藏版)》请在冰豆网上搜索。
对应与不同事件(捕获,比较,溢出,刹车,触发)的中断
与TIM5/TIM6或者外部信号(外部时钟,复位信号,触发和使能信号)同步
高级控制定时器广泛的适用于各种控制应用中,包括那些需要中间对齐模式
PWM的应用,该模式支持互补输出和死区时间控制。
高级控制定时器的时钟源可以是内部时钟,也可以是外部的信号,可以通过配置寄存器来进行选择。
这一节我们实现的功能是基本的定时,关于PWM的编程留下以后的章节中。
还有建议大家研究更为深入的功能
TIM1的时基单元包括,如下图所示:
●16位向上/向下计数器
●16位自动重载寄存器
●重复计数器
●预分频器
16位计数器,预分频器,自动重载寄存器和重复计数器寄存器都可以通过软件
进行读写操作。
自动重载寄存器由预装载寄存器和影子寄存器组成。
可在在两种模式下写自动重载寄存器:
●自动预装载已使能(TIM1_CR1寄存器的ARPE位置位)。
在此模式下,写入
自动重载寄存器的数据将被保存在预装载寄存器中,并在下一个更新事件(UEV)时传送到影子寄存器。
●自动预装载已禁止(TIM1_CR1寄存器的ARPE位清除)。
在此模式下,写入自动重载寄存器的数据将立即写入影子寄存器。
更新事件的产生条件:
●计数器向上或向下溢出。
●软件置位了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
然后可以通过PSCR这个寄存器设置CK_CNT,PSCR是2个8位寄存器组成的16位寄存器,可以在0~65535之间任务分频,分频后的频率提供给CK_CNT
我们的实验为了方便计算,CK_CNT为1K的频率,所以PSCR=16M/1K=16000,换成16进制为0x3E80
我们使用了默认的向上溢出,所以为了500ms溢出中断一次,需要设置ARPE
这个定时器,而且设置为自动预装功能,这样就可以一直提供2Hz的频率中断
最后允许中断和计数器使能就可以实现我们的功能
有了以上的基础就可以进入到TIM1的基本定时器编程了,为了验证效果,我们采用了LED0作为判断依据。
在TIM1的溢出中断服务程序中闪耀LED0
程序代码如下:
#include"
iostm8s207rb.h"
#defineLED1_FLASHPD_ODR_ODR0=!
PD_ODR_ODR0
voidCLK_Init(void);
voidGPIO_Init(void);
voidTIM1_Init(void);
voidmain(void)
{
CLK_Init();
GPIO_Init();
TIM1_Init();
asm("
rim"
);
//主循环里没有程序需要执行
while
(1);
}
voidCLK_Init(void)
CLK_CKDIVR=0x00;
//16M内部RC直接输出
voidGPIO_Init(void)
PD_DDR=0x01;
//配置PD端口的方向寄存器PD0输出
PD_CR1=0x01;
//设置PD0为推挽输出
PD_ODR=0xFF;
voidTIM1_Init(void)
TIM1_PSCRH=0x3E;
//16M系统时钟经预分频f=fck/(PSCR+1)
TIM1_PSCRL=0x7F;
//PSCR=0x3E7F,f=16M/(0x3E7F+1)=1000Hz
//每个计数周期1ms
TIM1_ARRH=0x01;
//自动重载寄存器ARR=0x01F4=500
TIM1_ARRL=0xF4;
//每记数500次产生一次中断,即500ms
TIM1_IER=0x01;
//允许更新中断
TIM1_CR1=0x01;
//计数器使能,开始计数
#pragmavector=TIM1_OVR_UIF_vector//0x0D
__interruptvoidTIM1_OVR_UIF(void)
LED1_FLASH;
TIM1_SR1=0;
//清除中断标记,这步不能漏掉,否则会连续进入中断程序
编译下载后就可以看到LED1一闪一闪的,闪耀的频率我们设置是2Hz,大家也可以设置不一样的定时时间,我们只是简单介绍如何使用TIM1的基本定时功能
例程2、16位通用定时器TIM2、TIM3
TIM2/TIM3的功能包括:
●16位向上计数和自动装载计数器
●4位可编程(可以实时修改的)预分频器,计数器时钟频率的分频系数为1~32768之间的2的幂
●3个独立通道:
输入捕获
输出比较
PWM生成(边缘对齐模式)
单脉冲模式输出
●如下事件发生时产生中断:
更新:
计数器向上溢出,计数器初始化(通过软件)
输出比较
和TIM1介绍一样,下面介绍时基单元
时基单元包含:
16位向上计数器
预分频器
16位自动装载寄存器
没有重复寄存器。
计数器使用内部时钟(fMASTER),它由CK_PSC提供,并经过预分频器分频产生计数器时钟CK_CNT。
预分频器的实现:
预分频器基于4位寄存器控制的16位计数器,由于寄存器带有缓冲器因此可以随时修改预分频的数值。
计数器可以取值为1到32768之间的2的幂进行分频。
计数器时钟频率的计算公式:
fCK_CNT=fCK_PSC/2(PSCR[3:
0])]
预分频器的值由预装载寄存器写入。
一旦写入预装载寄存器的LS字节时,带有当前使用值的影子寄存器就被写入了新的值。
新的预分频值在下一个周期时生效(在下一个更新事件之后)。
对TIMx_PSCR寄存器的读操作通过预装载寄存器实现,因此可以随时读取不受限制。
TIM2、TIM3与TIM1不同之处是预分频器并非在0~65535之间的认为分频系数,而是1到32768之间2的幂进行分频。
关于TIM2和TIM3的预分频寄存器如下:
这次实验是TIM2、TIM3同时工作,因为预分频系数不能随意设置,所以为了计算方便,我们设置为1024分频,也就是PSC=0x0A,经过分频后的频率是15.625K,也就是0.064ms
因此500ms/0.064=7813转为16进制是1E84,所以1S的定时是3D08,有了这些参数就可以开始我们例程二的软件代码编写了
#defineLED2_FLASHPD_ODR_ODR1=!
PD_ODR_ODR1
#defineLED3_FLASHPD_ODR_ODR2=!
PD_ODR_ODR2
voidTIM2_Init(void);
voidTIM3_Init(void);
TIM2_Init();
TIM3_Init();
CLK_CKDIVR=0x00;
PD_DDR=0x07;
PD_CR1=0x07;
//PSCR=0x3E7F
TIM1_ARRH=0x00;
//自动重载寄存器ARR=0x00FA=250
TIM1_ARRL=0xFA;
//每记数250次产生一次中断,即250ms
voidTIM2_Init(void)
{
TIM2_PSCR=0x0A;
//16M系统时钟经预分频f=16M/1024=15.625k
TIM2_ARRH=0x1E;
//15.625k*7813=500ms
TIM2_ARRL=0x84;
TIM2_IER=0x01;
//运行更新中断
TIM2_CR1=0x01;
//使能计数器
voidTIM3_Init(void)
TIM3_PSCR=0x0A;
TIM3_ARRH=0x3D;
//15.625k*15626=1s
TIM3_ARRL=0x08;
TIM3_IER=0x01;
//允许更新中断
TIM3_CR1=0x01;
//这步不能漏掉,否则会连续进入中断程序
#