实验四    定时器实验

  • 实验目的

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文件是程序代码,还有一个仿真文件。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部