打印
[其它应用]

中颖51芯片学习之定时器

[复制链接]
776|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2024-4-9 13:30 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
一、SH79F9476定时器简介
1. 简介
SH79F9476芯片具有多个定时器模块,包括定时器/计数器、PWM(脉冲宽度调制)定时器等,定时器可以配置为在计时达到特定值时触发中断,以便处理紧急事件或执行特定的任务。

2. 定时器运行模式
MODE0 16位捕捉模式;
MODE1 16位重载方式;
MODE2 可编程时钟输出模式
上升沿多次触发模式
具体地看,SH79F9476 有定时器 2,定时器 3,定时器 4 和定时器 5 四个定时器,其中:

定时器 2 可配置为 16 位捕捉功能、16 位重载方式或可编程时钟输出方式;
定时器 3 可配置为 16 位自动重载定时/计数器,且可以工作在掉电模式;
定时器 4 可配置为 16 位自动重载定时器或带边沿触发的 16 位自动重载定时器;两个数据寄存器TH4和TL4可作为一个16位寄存器来访问;
定时器 5 可配置为 16 位的自动重载定时器。
二、定时器2
1. 说明
定时器2有两个数据寄存器TH2和TL2,可以作为一个16位寄存器来使用,由寄存器T2CON和T2MOD控制;
定时器2的中断使能位是: IEN0寄存器中的ET2位。

(1)时钟
C/T2选择系统时钟(定时器)或外部引脚 T2 (计数器)作为定时器时钟输入。通过所选的引脚设置TR2允许定时器2/计数器2数据寄存器计数。
可配置寄存器T2MOD中的TCLKP2位选择系统时钟或系统时钟的1/12作为定时器2的时钟源。

(2)工作模式
定时器2支持3种工作方式:

捕获/重载
带递增或递减计数器的自动重载方式
可编程时钟输出
可以通过寄存器配置定时器2的工作方式:



2. 寄存器
(1)控制寄存器 T2CON



位功能:



(2)定时器2模式控制寄存器 T2MOD



位定义:



3. 工作方式0
(1)16位捕获说明
16位的捕获模式下,T2CON按制寄存器的EXEN2位有两个选项:

0:定时器2作为16位定时器或计数器,如果ET2被允许,定时器2能设置TF2溢出产生一个中断;
1:定时器操作与上相同,另外在外部输入T2EX上的下降沿也能引起在TH2和TL2中的当前值分别被捕获到RCAP2H和RCAP2L中;此外,在T2EX上的下降沿也能引起在T2CON中的EXF2被设置; 如果ET2被允许,EXF2位也像TF2一样产生一个中断。
流程框图:



(2)代码实现
下面的测试让TIMER2工作在16位捕获模式,系统时钟 Option 选择“内部 128kHz RC 振荡器作为振荡器 1,24MHz 内部 RC 作为振荡器 2”,如图所示:



测试代码:

#include "SH79F9476.h"
#include "cpu.h"
#include "intrins.h"
#include "api_ext.h"

void main()
{
  // 时钟设置高速模式
  CLKCON = 0x08;
  Delay();
  CLKCON |= 0x04;

  // P0.0,P0.1设置为输出
  P0CR = 0x03;
  P0 = 0x00;

  // TIMER2 16位捕获模式
  // 允许所有中断
  IEN0 |= 0x80;
  // 打开定时器2中断
  IEN1 |= 0x04;
  // 检测到T2EX 引脚上一个下降沿,产生一个捕获或重载
  T2CON = 0x08;
  // 设置定时器2工作在捕获模式
  T2CON |= 0x01;
  // 设置系统时钟12分频作为定时器时钟源
  T2MOD = 0x00;
  TL2 = 0x00;
  TH2 = 0x00;
  // BIT2 启动定时器
  T2CON |= 0x04;
  while(1);
}
// TIMER2的中断
void INT_TIMER2(void) interrupt 9{
        _push_(INSCON);
        Select_Bank0();

        // 定时器溢出
        if(T2CON & 0x80){
                // 溢出标志位清0
                T2CON &= 0x7F;
                // 翻转P0_0
                P0_0 = ~P0_0;
        }       
        // 检测到外部事件下降沿
        if(T2CON & 0x40){
                // 1011 1111, T2EX引脚外部事件被检测到的标志位清0
                T2CON &= 0xBF;
                // 翻转P0_1
                P0_1 = ~P0_1;
        }
        _pop_(INSCON);
}



测试代码中启动 T2EX(P1_1) 下降沿捕捉功能;全速运行后,T2EX(P1_1)口灌 1kHz 座号,观察:

P1_1 的下降沿 P0_1 状态会发生改变,频率为 500Hz。
P0_0 频率1000/0xFFFF(即65535),约为15.259Hz。
输入信号:



P0_1输出信号:



P0_0输出信号:



4. 工作方式1
(1)16位自动重载定时器说明
在16位自动重载方式下,定时器2可以被选为递增计数或递减计数。这个功能通过T2MOD中的DCEN位(递减计数允许)选择。

系统复位后,DCEN位复位值为0,定时器2默认递增计数。当设置DCEN时,定时器2递增计数或递减计数取决于T2EX引脚上的电平。

当DCEN = 0,通过在T2CON中的EXEN2位选择两个选项。
如果EXEN2 = 0,定时器2递增到0FFFFH,在溢出后置起TF2位,同时定时器自动将用户软件写好的寄存器RCAP2H和
RCAP2L的16位值装入TH2和TL2寄存器。
如果EXEN2 = 1,溢出或在外部输入T2EX上的下降沿都能触发一个16位重载,置起EXF2位。如果ET2被使能,TF2和EXF2
位都能产生一个中断。



设置DCEN位允许定时器2递增计数或递减计数。当DCEN = 1时,T2EX引脚控制计数的方向,而EXEN2控制无效。
T2EX置1可使定时器2递增计数。定时器向0FFFFH溢出,然后设置TF2位。溢出也能分别引起RCAP2H和RCAP2L上的16
位值重载入定时器寄存器。
T2EX清0可使定时器2递减计数。当TH2和TL2的值等于RCAP2H和RCAP2L的值时,定时器溢出。置起TF2位,同时0FFFFH
重载入定时器寄存器。
无论定时器2溢出,EXF2位都被用作结果的第17位。在此工作方式下,EXF2不作为中断标志。

(2)代码实现
下面代码示例中,系统时钟 Option 选择“内部 128kHz RC 振荡器作为振荡器 1,24MHz 内部 RC 作为振荡器 2”,启动自动重载功能;
程序启动后,在P0_0引脚输出1k频率方波。
P0 端口翻转一次的时间为:
t = (0xFFFF-TH2TL2)1/24 us。
计算频率为: 1/(t2) Hz

#include "SH79F9476.h"
#include "cpu.h"
#include "intrins.h"
#include "api_ext.h"

void main()
{
    // 时钟设置高速模式
    CLKCON = 0x08;
    Delay();
    CLKCON |= 0x04;

    // P0.0,P0.1设置为输出
    P0CR = 0x03;
    P0 = 0x00;

    // 允许所有中断
    IEN0 |= 0x80;
    // 打开定时器2中断
    IEN1 |= 0x04;
    // 设置定时器工作在重载模式,忽略T2EX引脚检测
    T2CON = 0;   
    // 选择定时器为递增定时器,时钟源为系统时钟(未使用1/12分频)
    T2MOD = 0x80;
    // 这里 0xD11F递增到0xFFFF溢出,差值12000,下面公式里24是频率24M
    // 定时12000*1/24=500us
    TL2 = 0x1F;   
    TH2 = 0xD1;
    // 重载计数器 Value
    RCAP2L = 0x1F;
    RCAP2H = 0xD1;
    // 启动定时器
    T2CON |= 0x04;

    while (1)
        ;
}
// TIMER2的中断
void INT_TIMER2(void) interrupt 9
{
    _push_(INSCON);
    Select_Bank0();

    // 定时器溢出
    if (T2CON & 0x80)
    {
        // 溢出标志位清0
        T2CON &= 0x7F;
        // 翻转P0_0
        P0_0 = ~P0_0;
    }
    // 检测到外部事件下降沿
    if (T2CON & 0x40)
    {
        // 1011 1111, T2EX引脚外部事件被检测到的标志位清0
        T2CON &= 0xBF;
        // 翻转P0_1
        P0_1 = ~P0_1;
    }
    _pop_(INSCON);
}





5. 工作方式2 可编程时钟输出
(1)功能介绍
T2端口可以编程输出50%的占空比时钟周期。清C/T2位和置T2OE位,使定时器2作为时钟发生器。TR2位启动和中止定时器。

时钟频率为:
F = 1 2 ∗ 2 ∗ f S Y S 65536 − [ R C A P 2 H , R C A P 2 L ] F = \frac{1}{2*2} * \frac{f_{SYS}}{65536-[RCAP2H,RCAP2L]}F=
2∗2
1


65536−[RCAP2H,RCAP2L]
f
SYS





定时器2溢出不产生中断,所以定时器2可以作时钟输出。

功能框图:




(2)软件实现
下面示例中,系统时钟 Option 选择“内部 128kHz RC 振荡器作为振荡器 1,24MHz 内部 RC 作为振荡器 2”。

#include "SH79F9476.h"
#include "cpu.h"
#include "intrins.h"
#include "api_ext.h"

void main()
{
    // 时钟设置高速模式
    CLKCON = 0x08;
    Delay();
    CLKCON |= 0x04;

    // P0.0,P0.1设置为输出
    P0CR = 0x03;
    P0 = 0x00;

    // 关闭定时器2中断
    IEN1 &= 0xFB;
    T2CON = 0;
    // P13作为T2输出
    T2MOD = 0x82;  
    // 系统时钟为24M,可产生100Hz的时钟      f=(1/4)*(Fsys/(65536-[RCAP2H,RCAP2L]))
    RCAP2L = 0xA0;
    RCAP2H = 0x15;
    TL2 = 0xA0;
    TH2 = 0x15;
    // 启动定时器
    T2CON |= 0x04;

    while (1)
        ;
}
// TIMER2的中断
void INT_TIMER2(void) interrupt 9
{
    _push_(INSCON);
    Select_Bank0();

    // 定时器溢出
    if (T2CON & 0x80)
    {
        // 溢出标志位清0
        T2CON &= 0x7F;
        // 翻转P0_0
        P0_0 = ~P0_0;
    }
    // 检测到外部事件下降沿
    if (T2CON & 0x40)
    {
        // 1011 1111, T2EX引脚外部事件被检测到的标志位清0
        T2CON &= 0xBF;
        // 翻转P0_1
        P0_1 = ~P0_1;
    }
    _pop_(INSCON);
}



程序运行后,T2 输出口(P1_3)输出 100Hz 频率时钟。
输出波形如下图所示:



三、其它定时器介绍
1. 定时器3
定时器3是16位自动重载定时器,通过两个数据寄存器TH3和TL3访问,由T3CON寄存器控制。IEN0寄存器的ET3位置1允许定时器3中断。

定时器3只有一种工作方式: 16位自动重载计数器/定时器。



代码示例:

  IEN0 |= 0xA0;     //打开定时器3中断

  _push_(INSCON);
  Select_Bank1();
  T3CON = 0x02;          //外部32.768kHz/128kHz为时钟源,1分频
  //配置定时器的初值为0xfffe,溢出时间为2个128kHz时钟
  TL3 = 0xfe;                 
  TH3 = 0xff;
  T3CON |=0x04;  //启动定时器3

  _pop_(INSCON);

void INT_TIMER3(void) interrupt 5
{
        _push_(INSCON);
        Select_Bank0();
        P0_0 = ~P0_0;
        _pop_(INSCON);   
}



系统时钟 Option 选择“内部 128kHz RC 振荡器作为振荡器 1,24MHz内部 RC 作为振荡器 2”,全速运行后,T3 时钟为低频 128k 时钟,P0_0 引脚输出 32k 频率方波。

2. 定时器4
定时器4是16位自动重载定时器。通过两个数据寄存器TH4和TL4访问,由T4CON寄存器控制。IEN1寄存器的ET4位置1允许定时器4中断。

定时器4有2种工作方式: 16位自动重载定时器和有T4边沿触发的16位自动重载定时器。

官方代码示例:

void init_timer4()
{
  IEN0 |= 0x84;     //EA,ET4,中断使能
  _push_(INSCON);
  Select_Bank1();
  #ifdef TIMER4_OUT
  T4CON = 0x40;          //T4引脚输出
  //配置定时器的初值为0x8000,T4引脚输出周期为2*0x8000个系统时钟的方波
  TL4 = 0x00;                 
  TH4 = 0x80;
  #endif
  #ifdef TIMER4_EDGETRIG
  T4CON = 0x48;        //T4上升沿触发,且可以多次触发
  TL4 = 0x00;
  TH4 = 0x00;
  #endif
  T4CON |=0x02;  //启动定时器4
  Select_Bank0();
  _pop_(INSCON);
}

void INT_TIMER4(void) interrupt 2
{
        _push_(INSCON);
           Select_Bank0();
        P0_0 = ~P0_0;
        _pop_(INSCON);      
}



启用 TIMER4_OUT
系统时钟 Option 选择“内部 128kHz RC振荡器作为振荡器1,24MHz内部RC作为振荡器2”,全速运行后,时钟为系统时钟,T4引脚(P1_1)输出周期为 2.7302ms 方波。

启用 TIMER4_EDGETRIG
系统时钟 Option 选择“内部 128kHzRC 振荡器作为振荡器 1,24MHz 内部 RC 作为振荡器 2”,全速运行后:
向 T4(P1_1)输入一个上升沿,P0.0状态翻转一次;向T4 (P1_1)输入周期性的上升沿,若周期小于T4定时时间(2.7302ms),
T4 将一直处于重新计时状态,P0.0 将无波形输出;若周期大于 T4 定时时间(2.7302ms),P0.0输出方波。

3. 定时器5
定时器5是16位自动重载定时器。通过两个数据寄存器TH5和TL5访问,由T5CON寄存器控制。IEN0寄存器的ET5位置1允许定时器5中断。

定时器5有一种工作方式:16位自动重载定时器。

官方代码示例:

void init_timer5()
{
  IEN0 |= 0x88;     //EA, ET5
  _push_(INSCON);
  Select_Bank1();
  //配置定时器的初值为0xD120,溢出时间为0x2EE0个系统时钟
  TL5 = 0x20;                 
  TH5 = 0xD1;
  T5CON |=0x02;  //启动定时器5
  _pop_(INSCON);
}


void INT_TIMER5(void) interrupt 3
{
        _push_(INSCON);
           Select_Bank0();
        P0_0 = ~P0_0;

        _pop_(INSCON);      
}



系统时钟 Option 选择“内部 128kHz RC 振荡器作为振荡器 1,24MHz
内部 RC 作为振荡器 2”,运行后时钟为系统时钟,P0_0 引脚输出 1kHz 频率方波。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/xundh/article/details/137490786

使用特权

评论回复
沙发
chenqianqian| | 2024-4-9 20:02 | 只看该作者
这个讲解详细,虽然是转载的。

使用特权

评论回复
板凳
黑心单片机| | 2024-4-10 13:24 | 只看该作者
很详细的介绍,实现效果真不错

使用特权

评论回复
地板
亚瑟| | 2024-4-23 14:40 | 只看该作者
这个可以直接烧录8051的程序吗

使用特权

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

本版积分规则

1360

主题

13974

帖子

8

粉丝