打印
[KungFu8位 MCU]

基于 KF8TS2716 实现 T0 定时器的 125us 中断定时功能

[复制链接]
1252|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xujunyi3611|  楼主 | 2018-1-18 10:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<KF8TS2716.h> 
void Init_MCU()
{
OSCCTL = 0X70; //选择主频为 16M,即系统时钟运行 16M
TR0 = 0X04; //P02 口为芯片的 MODE 脚,需要设置为输入。
TR1 = 0XFF;
TR2 = 0XFF;
TR3 = 0XFF;
}
void Init_T0_Fun() //初始化 T0 模块子函数
{
OPTR = 0X81; //OPTR 选择寄存器,T0 分频比为 1:4;每计数 1 个数的时间为 1us
T0 = 131; //计数到 256 后溢出并产生中断,所以初始值设置为 256-125
T0IE = 1; //开启 T0 中断使能位,
T0IF = 0; //人为清除 T0 中断标志位
AIE = 1;        //开启总中断使能位
}
//主函数
void main()
{
Init_MCU();
Init_T0_Fun();
while(1);
}
//中断函数 0:0X04 入口地址


沙发
xujunyi3611|  楼主 | 2018-1-18 10:32 | 只看该作者
        很显然,在上述的程序中,重点是初始化定时器 T0 的子函数。首先需要明白的是定时器 T0 的时钟源是什么?T0 在作为定时器的时候,它的时钟源为机器时钟,即 SCLK/4;其中 SCLK 为系统时钟,即我们通常所说的、需要设定的主频,本例程中 MCU 运行的系统时钟为 16M,这在初始化 MCU 函数内的第一句话便已经明确的。如果我们设定 MCU 的主频运行 8M,那么 T0 定时器的时钟源便成了 8M/4 = 2M。大家应该徆清楚时钟源的问题吧。

使用特权

评论回复
板凳
xujunyi3611|  楼主 | 2018-1-18 10:33 | 只看该作者
        明白了 T0 的时钟源,接下来需要设定的是 T0 的分频比。OPTR 寄存器中的 PS<2:0>位便是设定分频比的,这里不得不提一下,T0 和看门狗共用了 PSA 预分频器,PSA 位的状态决定这个分频器是负责哪一个模块,为 1 则是分配给看门狗,为 0 则是分配给 T0。这一点需要清楚。例程中,我们设定T0 的分频为1:4分频,意思就是说T0的时钟变成了SCLK/4/4;这样 T0 定时器每计数 1 个数所占用的时间为 1/16M/4/4 = 1us;那么我们需要的 125us 的定时则需要T0 计数125 个数,也就是T0计数125 个数后产生中断便可以实现我们的需求。而定时器 T0 叧具备溢出中断的功能,这样理解就徆简单了,也就是 8 位的定时器 T0,在计数到 256 的时候会溢出产生中断,那么 T0 的初始值就应该设定为 256-25 = 131;即从 131 开始计数,计数 125 次后到达 256,每计数 1 次所用的时间为 1us,产生溢出中断时正好 125us。打开 T0IE,则是使能 T0 中断,计数溢出后会使能 T0IF 标志位,打开 AIE,则是使能总中断,这样才会产生中断。如果丌打开 AIE,则叧会置位 T0IF 标志位,而不会进入中断。

使用特权

评论回复
地板
xujunyi3611|  楼主 | 2018-1-18 10:35 | 只看该作者
本帖最后由 xujunyi3611 于 2018-1-18 10:36 编辑

        最后便是进入中断处理了,KF8TS2716 具备高低中断优先级功能,共有两个中断入口,一个是 0x04 入口,我们称呼为中断入口 0,另外一个是 0x14 入口,我们称为中断入口1;其中,中断入口 0 即是默认的中断入口也是高优先级中断的入口。意思就是如果系统不设置高低优先级中断,选择常规模式,那么所有中断自动迚入 0x04 这个中断入口。如果系统设置了高低优先级中断,那么叧有被设定为高优先级的中断才能迚入 0x04 入口,那些没有被设定成高优先级的中断则自动进入低优先级入口。

使用特权

评论回复
5
xujunyi3611|  楼主 | 2018-1-18 10:37 | 只看该作者
         本例程中采用的是常规模式(下面将讲解到高低优先级的使用方法),所以我们在中断入口 0 的中断函数内操作 T0 定时器中断程序。如下所示:
//中断函数 0:0X04 入口地址 
void int_fun0() __interrupt (0)
{
if(T0IF)
{
  T0IF = 0;
  T0 = 131+T0;   //减掉入栈时间,让时间更加接近理论值。
P0LR1 = !P0LR1; //取反一个 IO 口。
}
}

使用特权

评论回复
6
xujunyi3611|  楼主 | 2018-1-18 10:38 | 只看该作者
        由于 T0 定时器没有自动重载功能,所以在进入T0中断后,除了需要清零 T0 IF 标志位,还需要重新置位 T0 初始值,让下一次的中断时间也是 125us。这里赋值 T0 的时候会在初始值的基础上再加上 T0 自身,是为了减掉入栈所占用的时间让中断定时更加精确。当然,如果有自动重载的功能,便不需要这样的操作了。

使用特权

评论回复
7
飞翔的控制器| | 2018-1-22 11:09 | 只看该作者
精确定时如何计算的呢?

使用特权

评论回复
8
xujunyi3611|  楼主 | 2018-2-25 11:22 | 只看该作者
飞翔的控制器 发表于 2018-1-22 11:09
精确定时如何计算的呢?

一次中断溢出时间*溢出次数就是精准的时间了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

60

主题

376

帖子

2

粉丝