【STC库函数】Timer定时器的使用

今天我们来看看STC的定时器。

定时器同时也可以是计数器,其实是差不多的。

对于STC8G1K08A来说,有仨16位的定时器,但是如果是SOP8的话,那就只有两个定时器,是定时器0和定时器1。

定时器有四种工作模式,模式0为16位自动重装载(也是最常用的),模式1为16位不自动重装载,模式2为8位自动装载,模式3为16位不可屏蔽中断自动重装载。

定时器0的话是四种工作模式都可以使用,而定时器1不能用模式3。

而对于STC32G12K来说,定时器是有五个。

定时器0和1的工作模式和STC8的一模一样。

剩下的定时器234的工作模式固定为模式0也就是16位自动重装载。

了解了定时器资源和工作模式之后,我们简单看看手册里对于定时器物理结构的描述,因为手册里列出了7种(定时器0的0123工作模式和定时器1的012工作模式)有点多,所以我们这边就只看看定时器0的模式0意思意思。

下图是STC32G的定时器框图,STC8和下面的几乎一模一样,就是少了TM0PS。

我们从左往右一个个看,首先是SYSclk,也就是系统时钟,不管是STC8还是STC32都是24MHz,记得在烧录的时候,在烧录软件里选择24MHz。

然后经过TM0PS,它是定时器0的预分频器,一共有8个bit,也就是说最多可以是2^8 - 1 + 1= 256分频(减一是因为8个bit的范围是0~255,加一是预分频器的值加一之后才会拿去分频)

接下来是÷12或÷1,也就是可以选择要不要接着分频一下,不过只能是要么不再分要么就是固定12分频。

再往下就是一个分叉路口了,C/T等于0的时候,那就是我们刚刚推算过来的系统时钟来的脉冲作为计数来源;C/T等于1的时候定时器的计数来源就是外部引脚了,T0的外部脉冲引脚是P34。

过了分岔路口有个方框,这个不用管,可以当成是定时器的使能部位。

再往下就是存放计数的寄存器(TH0、TL0)和重装载寄存器(RL_TH0、RL_TL0)

当我们计数器的值溢出就会置位TF0从而引发中断,然后重装载寄存器的值就会写入计数的寄存器里进入新一轮的计数。

上面看不懂没关系,我们只要有下面这样一个公式就够了。如果是STC8的话没有TM0PS那部分。

接下来讲解一下库函数。

我们需要把三个文件包含进工程里。STC32G_Timer.c、STC32G_Timer_Isr.c、STC32G_NVIC.c

关于NVIC我们就用一个函数用于配置中断优先级以及打开中断。

如果是定时器1的话就把上面函数名里的0改成1即可。

然后除了这个函数之外,我们还需要手动把EA置1,关于这个EA,昨天的外部中断那篇有提到。

接着是定时器的配置函数,也是只有一个函数。

参数一指定定时器通道,参数二结构体变量的指针来配置参数。

结构体的成员从上到下依次是工作模式,一般使用TIM_16BitAutoReload16位自动重装载模式也就是模式0。

时钟源,可以选择的是下面三种。

可以参考前面的频率计算公式,一般我们就选择TIM_CLOCK_1T

第三个是可编程时钟输出设置,可以选择ENABLE或者是DISABLE,也就是使能和失能,一般就是DISABLE

第四个就是定时器的初值,记得最多是16个bit,也就是最大值为2^16 - 1= 65535,超过这个值就会溢出中断。

最后一个就是使能,给个ENABLE

其实还有一个成员,在库函数手册里没有标出来,那就是预分频器的值。

下面的代码里我将定时器触发的周期设为了5ms。

#include "STC32G_GPIO.h"
#include "STC32G_NVIC.h"
#include "STC32G_Timer.h"

void NVIC_Init(void) {
    NVIC_Timer0_Init(ENABLE, Priority_1);
}

void GPIO_Init(void) {
    P2_MODE_OUT_PP(GPIO_Pin_7);
}

void Timer_Init(void) {
    TIM_InitTypeDef initer;
    initer.TIM_Mode = TIM_16BitAutoReload;          // 模式0,16位自动重装载寄存器.
    initer.TIM_ClkOut = DISABLE;                    // 失能可编程时钟输出
    initer.TIM_ClkSource = TIM_CLOCK_1T;            // 1T工作模式
    initer.TIM_Value = 55536;                       // 计数寄存器和重装载寄存器的值设为55536
    initer.TIM_PS = 11;                             // 预分频器的值设为11,实际上是12分频
    initer.TIM_Run = ENABLE;                        // 定时器,启动!

    Timer_Inilize(Timer0, &initer);
}

void main(void) {
    WTST = 0;  // 设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXSFR();  // 扩展SFR(XFR)访问使能
    CKCON = 0;  // 提高访问XRAM速度

    GPIO_Init();
    Timer_Init();
    NVIC_Init();
    EA = 1;

    while (1) {
    }
    return;
}

STC32G_Timer_Isr.c的定时器0中断触发函数里我的代码逻辑是每溢出20次,就切换一下P27的电平,接个LED就可以看到效果了。

定时器里唯一的问题就是如何设置定时器溢出的周期。

这个我们可以参考手册里的公式。

公式里周期的单位是秒。

如果我们不需要定时器的周期比较大的话,可以把PS(预分频器)置0,这样计算起来就很方便了。

当PS为0的时候,公式就变成了计数寄存器的初始值 = 65536 - T*F,其中T是周期,F是时钟频率。

T周期是我们自己定的,F是24MHz,所以我们就可以很轻松地算出应该给计数寄存器赋的值是多少了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值