定时器中断实验

实验指导书:定时器中断实验(T0/T1功能验证)

一、实验目的

  1. 掌握STC8H8K64U单片机定时器/计数器(Timer0和Timer1)的工作原理;
  2. 掌握定时器相关寄存器的配置方法,包括工作模式设置、初值计算、中断使能及启动控制;
  3. 学会使用定时器中断实现精确的定时控制;
  4. 巩固中断服务程序的编写及主程序结构设计;
  5. 掌握利用STC-ISP软件进行程序下载与调试的方法。

二、实验器材

  • 开天斧三开发板(主控芯片:STC8H8K64U,LQFP64封装) 1块
  • USB数据线 1根
  • 计算机 1台
  • STC-ISP下载软件
  • Keil C51集成开发环境

三、实验原理

3.1 定时器/计数器概述

定时器/计数器是单片机内部的重要外设,可对外部脉冲计数或对内部时钟脉冲计数,当计数值溢出时产生中断请求。STC8H8K64U单片机内部集成了5个16位定时器(T0~T4),本实验使用最基础的定时器T0和T1。

定时器T0和T1的核心是一个16位的加1计数器,由两个8位寄存器THx和TLx组成(x=0,1)。计数器每接收到一个脉冲就加1,当从全1(0xFFFF)变为0时,发生溢出,并置位中断请求标志位TFx,若中断允许且总中断开放,CPU将响应定时器中断。

脉冲来源可以是系统时钟分频(定时功能)或外部引脚T0/T1的输入信号(计数功能)。本实验使用定时功能,即对内部时钟脉冲计数。

3.2 定时器的工作模式与时钟源

STC8H8K64U的T0和T1支持多种工作模式,由TMOD寄存器选择。常用模式有:

  • 模式0(16位自动重装载):TLx和THx构成16位计数器,溢出后自动将重装载值装入计数器,适合产生固定周期的中断。
  • 模式1(16位非自动重装载):溢出后计数器从0开始计数,需要在中断服务程序中手动重装初值。
  • 模式2(8位自动重装载):仅TLx计数,THx保存重载值,适合产生快速、精确的定时。

此外,通过辅助寄存器AUXR可以设置定时器的时钟速度。T0和T1均可配置为12T模式(传统8051速度)1T模式(不分频,速度更快)。本实验采用12T模式,便于计算。系统时钟频率可通过STC-ISP设置为24MHz,则12T模式下的计数频率为24MHz / 12 = 2MHz,即每个计数脉冲周期为0.5μs。

3.3 定时器相关寄存器

3.3.1 定时器/计数器工作模式寄存器TMOD(不可位寻址)

D7D6D5D4D3D2D1D0
名称GATEC/TM1M0GATEC/TM1M0
定时器1定时器0
  • GATE:门控位。为0时仅由TRx控制启停;为1时需同时TRx=1且INTx引脚为高电平时才计数。
  • C/T:功能选择位。0为定时器(对内部时钟计数),1为计数器(对T0/T1引脚输入脉冲计数)。
  • M1、M0:工作模式选择。00为模式0(16位自动重装载),01为模式1(16位非自动重装载),10为模式2(8位自动重装载),11为模式3(仅T0适用,分成两个8位计数器)。

3.3.2 定时器/计数器控制寄存器TCON(可位寻址)

D7D6D5D4D3D2D1D0
名称TF1TR1TF0TR0IE1IT1IE0IT0
  • TF1(TCON.7):T1溢出中断请求标志。溢出时硬件置1,CPU响应中断后硬件自动清零。
  • TR1(TCON.6):T1运行控制位。置1启动T1计数,清0停止计数。
  • TF0(TCON.5):T0溢出中断请求标志。溢出时硬件置1,CPU响应中断后硬件自动清零。
  • TR0(TCON.4):T0运行控制位。置1启动T0计数,清0停止计数。
  • 低4位(IE1、IT1、IE0、IT0)与外部中断相关,定时器模式未用。

3.3.3 中断允许寄存器IE(可位寻址)

D7D6D5D4D3D2D1D0
名称EAET2ESET1EX1ET0EX0
  • EA(IE.7):总中断允许位,需置1。
  • ET1(IE.3):T1中断允许位,置1使能T1中断。
  • ET0(IE.1):T0中断允许位,置1使能T0中断。

3.3.4 初值计算

定时时间公式(12T模式):初值 = 65536 - (定时时间 / 机器周期) = 65536 - (定时时间 × 计数频率)

系统时钟24MHz,12T模式下计数频率 = 2MHz,机器周期 = 0.5μs。

例如,需要定时50ms(50000μs),计数值 = 50000μs / 0.5μs = 100000,因最大计数值为65536,无法一次完成。可将50ms拆分为更小的定时,如10ms:计数值 = 10000μs / 0.5μs = 20000,初值 = 65536 - 20000 = 45536,化为十六进制为0xB1E0。通过软件计数5次即可得到50ms。

3.4 开天斧三开发板电路说明

开天斧三开发板主控为STC8H8K64U(LQFP64封装),板载资源:

  • LED电路:P2端口连接多个LED指示灯(低电平点亮),P2.0为LED0,P2.1为LED1,将分别用于指示T0和T1的定时中断效果。
  • 电源与下载:USB供电,通过P3.0/P3.1下载程序。

本实验仅使用LED作观察对象,无需外部跳线。

四、实验内容

实验任务一:定时器T0控制LED闪烁

利用定时器T0产生50ms定时中断,在中断服务程序中软件计数20次(共1秒),翻转P2.0状态。LED0将按2秒周期(亮1秒、灭1秒)闪烁。

实验任务二:定时器T1控制LED闪烁

利用定时器T1产生100ms定时中断,在中断服务程序中直接翻转P2.1状态。LED1将按200ms周期(亮100ms、灭100ms)快速闪烁。

实验任务三:双定时器同时工作验证

同时启动T0和T1,两个LED各自独立闪烁,观察它们互不干扰,验证多中断源协同工作。

五、实验步骤

5.1 硬件连接

  1. 取出开天斧三开发板,确认板载LED(P2.0、P2.1)完好。
  2. 通过USB线将开发板连接至计算机。
  3. 本实验无外部接线需求。

5.2 软件编程

  1. 打开Keil C51,新建工程,器件选择STC8H8K64U
  2. 添加头文件#include <STC8H.H>
  3. 初始化I/O口:设置P2口为准双向口模式(P2M1=0x00; P2M0=0x00;)。
  4. 编写定时器T0初始化函数:设置16位自动重装载模式(TMOD=0x00),12T模式,定时10ms,计算初值,开启中断并启动计数。
  5. 编写定时器T1初始化函数:同样16位自动重装载模式,定时50ms,配合软件计数2次实现100ms。
  6. 编写中断服务程序:
    • T0中断(interrupt 1):软件计数器+1,满20次时翻转P2.0并清空计数器。
    • T1中断(interrupt 3):软件计数器+1,满2次时翻转P2.1并清空计数器。
  7. 主函数中调用初始化,然后进入while(1);死循环。
  8. 编译生成HEX文件。

5.3 程序下载

  1. 打开STC-ISP软件,型号选STC8H8K64U
  2. 设定IRC频率为24MHz
  3. 加载HEX文件,点击“下载/编程”。
  4. 给开发板重新上电或按复位键,完成下载。

5.4 观察实验现象

  1. 任务一:观察P2.0 LED,应每隔1秒翻转一次(亮1秒、灭1秒)。
  2. 任务二:观察P2.1 LED,应以更快的频率闪烁(约每0.1秒翻转,周期0.2秒)。
  3. 任务三:两个LED独立闪烁,节奏不同,互不干扰。
  4. 记录实际闪烁周期(可用示波器或秒表粗略测量)。

六、参考程序

6.1 包含文件及变量定义

#include <STC8H.H>

unsigned int t0_count = 0;
unsigned int t1_count = 0;

6.2 定时器T0初始化(10ms定时)

void Timer0_Init(void)
{
    TMOD &= 0xF0;       // 清T0控制位
    TMOD |= 0x00;       // 模式0,定时,GATE=0
    
    TL0 = 0xE0;         // 初值低8位
    TH0 = 0xB1;         // 初值高8位
    
    ET0 = 1;            // 使能T0中断
    TR0 = 1;            // 启动T0
}

6.3 定时器T1初始化(10ms定时,便于共用初值)

void Timer1_Init(void)
{
    TMOD &= 0x0F;
    TMOD |= 0x00;
    
    TL1 = 0xE0;
    TH1 = 0xB1;
    
    ET1 = 1;
    TR1 = 1;
}

6.4 中断服务程序

void T0_ISR(void) interrupt 1
{
    t0_count++;
    if(t0_count >= 50)      // 50×10ms = 500ms,亮灭各500ms即1秒周期
    {
        t0_count = 0;
        P20 = ~P20;
    }
}

void T1_ISR(void) interrupt 3
{
    t1_count++;
    if(t1_count >= 5)       // 5×10ms = 50ms,翻转一次周期100ms
    {
        t1_count = 0;
        P21 = ~P21;
    }
}

6.5 主程序

void main(void)
{
    P2M1 = 0x00;  P2M0 = 0x00;    // P2口准双向
    Timer0_Init();
    Timer1_Init();
    EA = 1;                        // 开放总中断
    
    while(1)
    {
    }
}
注意:上述代码中T0累计50次达到500ms中断翻转一次,实现亮1秒灭1秒;T1累计5次实现50ms翻转一次,周期100ms。实际可自行调整计数值。

七、实验现象及记录

操作内容预期现象实际现象原因分析
程序下载后正常运行P2.0 LED以约1秒间隔交替亮灭;P2.1 LED快速闪烁(周期约0.1秒)T0和T1各自按设定时间产生中断
用示波器测量P2.0波形方波周期约2秒,占空比50%定时器初值准确,累计计数无误
修改T1累加阈值,增大间隔P2.1闪烁变慢定时时间增长,翻转频率降低
同时观察两个LED两个LED完全独立,互不影响中断系统根据优先级和顺序正确响应
说明:由于内部RC振荡器存在微小偏差,实际定时时间可能与理论值略有差异,属于正常现象。若要获得更高精度,可外接晶振或使用STC-ISP软件进行频率微调。

八、思考题

  1. 若将T0改为1T模式(AUXR |= 0x80),定时10ms的初值应如何计算?实际效果会有何变化?
  2. 什么是自动重装载?使用模式0与模式1编写定时器程序时,中断服务程序写法有何主要区别?
  3. 当T0和T1同时申请中断时,CPU会先响应哪一个?为什么?如何设置中断优先级让T1优先于T0?
  4. 如果需要生成一个周期为1秒、占空比可调的PWM信号控制LED亮度,仅用T0如何实现?(提示:可在中断中修改比较值)
  5. 如何用定时器实现一个简单的电子时钟(秒、分、时)?请画出程序流程图并尝试编写代码。

九、实验总结

通过本次实验,学生应掌握以下知识点:

  1. 定时器工作原理:理解加1计数器、溢出、自动重装载等概念,明确定时与计数功能的区别。
  2. 寄存器配置方法:熟练操作TMOD、TCON、IE等寄存器,能够根据实际需求计算定时初值。
  3. 中断服务程序编写:掌握定时器中断的向量号(T0:1,T1:3),学会在中断中加入软件累计变量以扩展定时长度。
  4. 多中断协同工作:体验两个定时器中断同时运行,理解中断优先级和中断嵌套的基本规则。
  5. 软硬件联调:结合开天斧三开发板和Keil/STC-ISP工具,完成从编程到下载、观察的全过程,提升实践能力。
  6. 精确定时应用:为后续学习串行通信、PWM输出、实时时钟等应用打下坚实基础。

本站所有文章、数据、图片来源于网络,仅供学习使用,如有侵权,联系删除!