单片机 定时器实验 实验四
实验四 定时器实验
实验目的
1、理解单片机内部定时器的工作原理及使用方法;
2、了解单片机定时中断程序的编写和调试方法;
3、掌握定时器的基本使用方法;
实验任务
设计一个两位倒计时秒表,可通过按键启动和暂停,计时显示于数码管。
实验原理
定时/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器组成。TMOD是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制T0、T1的启动和停止及设置溢出标志。
M1、M0为工作方式选择位 ,用于对T0的四种工作方式,T1的三种工作方式进行选择,选择情况如下 :
M1 |
M0 |
工作方式 |
方式说明 |
0 |
0 |
0 |
13位定时/计数器 |
0 |
1 |
1 |
16位定时/计数器 |
1 |
0 |
2 |
8位自动重置定时/计数器 |
1 |
1 |
3 |
两个8位定时/计数器(只有T0有) |
TF0(1):定时/计数器T0(1)的溢出标志位,当定时/计数器T1计满时,由硬件使它置位,如中断允许则触发T1中断。进入中断处理后由内部硬件电路自动清除。
TR0(1):定时/计数器T0(1)的启动位,可由软件置位或清零,当TR0(1)=1时启动;TR0(1)=0时停止。
加1计数器输入的脉冲来源有两个:
一:时钟周期脉冲(晶振经12分频得到)(定时);
二:T0或T1引脚输入的外部脉冲源)(计数);
每来一个脉冲,计数器加1,当加到计数器为全1时,再输入一个脉冲计数器归零(称为溢出),使TCON中TF0或TF1置1,向CPU发出中断请求(定时/计数器中断允许的情况下)。
溢出时计数值(累计的脉冲数)N =最大计数值(满值)M -初值X;
满值由定时器工作方式决定,如工作方式1时,M= 216。
定时模式时,定时时间T=N* Tcy(机器周期) 。
1秒定时设计方法:
假设系统使用的晶振频率为12 MHz,即每个机器周期为1 μS。如使用方式1,则定时时间最长是216×1μS =65536us=65.536 mS<1 S。可设置定时器定时中断时间为50 mS,定时中断20次则可达到1 秒定时时间。
使定时器0方式1定时50 mS,溢出时计数值N=50 mS/1μS=50000,定时器0需要设置的初值为216-50000,即
TL0=(216-50000)%256;TH0=(216-50000)/256;
电路原理图如图4-1所示。
图4-1 实验电路图
注释:上面的原理是课程设计给的模板,不是我写的,仅供参考,如有相同就是参考的,参考书:单片机原理与接口技术实验指导书、单片机原理与接口技术
程序流程图
本次的实验流程图,将不同的函数进行划分来绘制程序流程图如图4-2所示。
图4-2 本实验程序流程图
实验结果及分析总结
图4-3 本实验绘制的电路图
本次实验,按照实验原理,结合之前的中断实验和数码管显示实验的内容,理解单片机内部定时器的工作原理及使用方法,了解单片机定时中断程序的编写和调试方法,掌握定时器的基本使用方法,在实验的过程中出现的问题是:将单片机的内部中断和外部中断混为一谈,之后将两者的中断原理再进行研究,之后分开进行调用,即实现实验任务的要求。
图 4-4本实验程序截图
程序附录
#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
#define DUANMA P0
#define WEI P2
sbit KEY = P3^2; // 按键连接到P3.2
uint addNum;
uchar secNum = 60;
uchar code table[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x00};
void delayms(uint num) {
uint i, j;
for (i = num; i > 0; i--)
for (j = 120; j > 0; j--);
}
void INIT() {
TMOD = 0x20; // T1工作在方式2(常用)
TL1 = TH1 = 256 - 250;
EA = 1;
ET1 = 1;
TR1 = 1;
}
void startTimer() {
TR1 = 1; // 启动计时器
}
void stopTimer() {
TR1 = 0; // 停止计时器
}
void checkKey() {
if (KEY == 0) { // 检测按键是否按下
delayms(10); // 延时去抖动
if (KEY == 0) { // 再次检测按键是否按下
if (TR1 == 0) {
startTimer(); // 如果计时器已停止,则启动计时器
} else {
stopTimer(); // 如果计时器正在运行,则停止计时器
}
while (KEY == 0); // 等待按键释放
}
}
}
void main() {
INIT();
while (1) {
checkKey(); // 检测按键
WEI = 0xfe;
DUANMA = table[secNum / 10 % 10];
delayms(10);
WEI = 0xfd;
DUANMA = table[secNum % 10];
delayms(10);
}
}
void Timer1() interrupt 3 {
addNum++;
if (addNum == 4000) {
secNum--;
addNum = 0;
}
}
学习过程中,参考资料网上的,如有侵权删。如有需要自行下载源文件,里面code文件是程序代码,还有一个仿真文件。
作者:RJSJS……