定时器中断实验
实验指导书:定时器中断实验(T0/T1功能验证)
一、实验目的
- 掌握STC8H8K64U单片机定时器/计数器(Timer0和Timer1)的工作原理;
- 掌握定时器相关寄存器的配置方法,包括工作模式设置、初值计算、中断使能及启动控制;
- 学会使用定时器中断实现精确的定时控制;
- 巩固中断服务程序的编写及主程序结构设计;
- 掌握利用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(不可位寻址)
| 位 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
|---|---|---|---|---|---|---|---|---|
| 名称 | GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 |
| 定时器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(可位寻址)
| 位 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
|---|---|---|---|---|---|---|---|---|
| 名称 | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
- 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(可位寻址)
| 位 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
|---|---|---|---|---|---|---|---|---|
| 名称 | EA | — | ET2 | ES | ET1 | EX1 | ET0 | EX0 |
- 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 硬件连接
- 取出开天斧三开发板,确认板载LED(P2.0、P2.1)完好。
- 通过USB线将开发板连接至计算机。
- 本实验无外部接线需求。
5.2 软件编程
- 打开Keil C51,新建工程,器件选择STC8H8K64U。
- 添加头文件
#include <STC8H.H>。 - 初始化I/O口:设置P2口为准双向口模式(
P2M1=0x00; P2M0=0x00;)。 - 编写定时器T0初始化函数:设置16位自动重装载模式(TMOD=0x00),12T模式,定时10ms,计算初值,开启中断并启动计数。
- 编写定时器T1初始化函数:同样16位自动重装载模式,定时50ms,配合软件计数2次实现100ms。
- 编写中断服务程序:
- T0中断(interrupt 1):软件计数器+1,满20次时翻转P2.0并清空计数器。
- T1中断(interrupt 3):软件计数器+1,满2次时翻转P2.1并清空计数器。
- 主函数中调用初始化,然后进入
while(1);死循环。 - 编译生成HEX文件。
5.3 程序下载
- 打开STC-ISP软件,型号选STC8H8K64U。
- 设定IRC频率为24MHz。
- 加载HEX文件,点击“下载/编程”。
- 给开发板重新上电或按复位键,完成下载。
5.4 观察实验现象
- 任务一:观察P2.0 LED,应每隔1秒翻转一次(亮1秒、灭1秒)。
- 任务二:观察P2.1 LED,应以更快的频率闪烁(约每0.1秒翻转,周期0.2秒)。
- 任务三:两个LED独立闪烁,节奏不同,互不干扰。
- 记录实际闪烁周期(可用示波器或秒表粗略测量)。
六、参考程序
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)
{
}
}
七、实验现象及记录
| 操作内容 | 预期现象 | 实际现象 | 原因分析 |
|---|---|---|---|
| 程序下载后正常运行 | P2.0 LED以约1秒间隔交替亮灭;P2.1 LED快速闪烁(周期约0.1秒) | T0和T1各自按设定时间产生中断 | |
| 用示波器测量P2.0波形 | 方波周期约2秒,占空比50% | 定时器初值准确,累计计数无误 | |
| 修改T1累加阈值,增大间隔 | P2.1闪烁变慢 | 定时时间增长,翻转频率降低 | |
| 同时观察两个LED | 两个LED完全独立,互不影响 | 中断系统根据优先级和顺序正确响应 |
八、思考题
- 若将T0改为1T模式(AUXR |= 0x80),定时10ms的初值应如何计算?实际效果会有何变化?
- 什么是自动重装载?使用模式0与模式1编写定时器程序时,中断服务程序写法有何主要区别?
- 当T0和T1同时申请中断时,CPU会先响应哪一个?为什么?如何设置中断优先级让T1优先于T0?
- 如果需要生成一个周期为1秒、占空比可调的PWM信号控制LED亮度,仅用T0如何实现?(提示:可在中断中修改比较值)
- 如何用定时器实现一个简单的电子时钟(秒、分、时)?请画出程序流程图并尝试编写代码。
九、实验总结
通过本次实验,学生应掌握以下知识点:
- 定时器工作原理:理解加1计数器、溢出、自动重装载等概念,明确定时与计数功能的区别。
- 寄存器配置方法:熟练操作TMOD、TCON、IE等寄存器,能够根据实际需求计算定时初值。
- 中断服务程序编写:掌握定时器中断的向量号(T0:1,T1:3),学会在中断中加入软件累计变量以扩展定时长度。
- 多中断协同工作:体验两个定时器中断同时运行,理解中断优先级和中断嵌套的基本规则。
- 软硬件联调:结合开天斧三开发板和Keil/STC-ISP工具,完成从编程到下载、观察的全过程,提升实践能力。
- 精确定时应用:为后续学习串行通信、PWM输出、实时时钟等应用打下坚实基础。
本站所有文章、数据、图片来源于网络,仅供学习使用,如有侵权,联系删除!