51单片机入门教程(5)——定时器中断

51单片机入门教程(5)——定时器中断51 单片机入门教程 5 定时器中断一 中断的概念二 定时器中断 2 1 软件延时的不足 2 2 中断寄存器 2 2 1 中断允许控制寄存器 IE2 2 2 定时器工作方式寄存器 TMOD2 2 3 定时器控制寄存器 TCON2 2 4 定时器初值寄存器 THx TLx2 3 定时器中断程序写法写在开头 中断是包括单片机在内的所有微处理器很重要的功能之一 初学单片机必须这一部分的知识 一 中断的概

写在开头: 中断是包括单片机在内的所有微处理器很 重要的功能之一,初学单片机必须这一部分的知识。

一、中断的概念

先看百度百科是怎么定义中断的:

那么怎么理解中断?看下面的例子。

关于中断
小A正在学习。这时,他的朋友小B叫他一块儿吃鸡,小A停止学习,转去玩吃鸡游戏。玩了几局后,关掉游戏,继续学习。
关于中断优先级
小A正在学习。这时,他的朋友小B叫他一块儿吃鸡,小A停止学习,转去玩吃鸡游戏,(吃鸡过程中,小A女朋友打来电话,于是挂机游戏,去接电话,接完电话,继续游戏。)玩了几局后,关掉游戏,继续学习。


  • 几个重要概念:

中断:小A学习被小B打断的过程就称为中断
中断源:小B被称为中断源
中断服务程序:小A执行的玩游戏操作称为中断服务程序
中断优先级:小A女朋友的电话比游戏优先级


在89c52单片机中,有3类中断源:

其优先级如下表:

中断源 优先级 中断服务号
INT0 – 外部中断0 最高 0
T0 – 定时器/计数器0中断 第2 1
INT1 – 外部中断1 第3 2
T1 – 定时器/计数器1中断 第4 3
串口中断 第5 4
T2 – 定时器/计数器2中断 最低 5

下面以定时器中断为例,讨论中断的编程方法。

二、定时器中断

2.1 软件延时的不足

//延时xms void delayms(uint xms){ 
     uint i,j; for(i = 0; i < xms; ++i) for(j = 0; j < 110; ++j) ; } 

但是,假设要实现以下功能:

//代码不完整,仅为举例说明 void main(){ 
     P2 = 0x01; //数码管从最低位开始扫描 while(1){ 
     //功能1:执行数码管动态扫描 //P2控制显示哪一个数码管,P0控制数码管显示什么内容 P2 = P2<<1; //扫描更高一位的数码管 P0 = xxxx; //输出段码 delayms(5); //延时5ms后显示下一位数码管 //功能2:执行LED灯闪烁 led = ~led; //LED灯状态取反 delayms(1000); //延时1000ms } } 

2.2 中断寄存器

要使用硬件定时,主要涉及到寄存器的操作。51单片机里的关于中断的寄存器如下:

2.2.1 中断允许控制寄存器 IE

该寄存器的主要功能是控制中断的开启与关闭,共7个有效位,包含一个全局中断控制位和6个中断源的控制位。
中断允许控制寄存器 IE各位的定义如下表:

序号 D7 D6 D5 D4 D3 D2 D1 D0
符号 EA ET2 ES ET1 EX1 ET0 EX0

2.2.2 定时器工作方式寄存器 TMOD

序号 D7 D6 D5 D4 D3 D2 D1 D0
符号 GATE C / T ˉ C/\bar{T} C/Tˉ M1 M0 GATE C / T ˉ C/\bar{T} C/Tˉ M1 M0
M1 M0 工作方式
0 0 模式0,13位计数
0 1 模式1,16位计数,常用此模式
1 0 模式2,8位初值自动重装
1 1 模式3,仅适用于T0,分为两个8位计数器,T1停止计数

2.2.3 定时器控制寄存器 TCON

序号 D7 D6 D5 D4 D3 D2 D1 D0
符号 TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0

2.2.4 定时器初值寄存器 THx/TLx

以定时器T0为例,其的工作原理是,每当晶振产生一次脉冲,就将该寄存器TL0加一,当TL0加满溢出后,将TL0清空,TH0加一,TH0计满后产生定时中断。即TH0与TL0组成了一个16位的计数器,这个计数器可以从0x0000(0)加到0xffff(65535)。
以12Mhz的晶振、定时10ms为例:
51单片机为12分频单片机,因此执行一条指令的时间是12×(1/12M) s,即计数器每1us加一。
若定时10ms,则共需要加10000次。
因此将TH0、TL0设置从(65536-10000)= 55536开始计数。55536 的16进制为0xD8F0。因此将TH0设置为0xD8,TL0 设置为0xF0



2.3 定时器中断程序写法

TMOD = 0x01; // 0000 0001 

然后设置定时器时长THx/TLx:

TH0 = 0xD8; TL0 = 0xF0; 

设置定时器允许寄存器IE,打开中断总开关和T0中断开关

EA = 1; ET0 = 1; 

最后设置定时器控制寄存器TCON,使定时器开始计数

TR0 = 1; 

因此,完整的定时器初始化代码如下

void initT0(){ 
     TMOD = 0x01; // 0000 0001. TH0 = 0xD8; //65536-10000 TL0 = 0xF0; //55536 EA = 1; ET0 = 1; TR0 = 1; } 

当定时器计数触发中断时,单片机会调用中断服务程序。中断服务程序的格式如下:

void 函数名() interrupt 中断号 using 工作组 { 
     //所要执行内容 } 
中断源 优先级 中断服务号
INT0 – 外部中断0 最高 0
T0 – 定时器/计数器0中断 第2 1
INT1 – 外部中断1 第3 2
T1 – 定时器/计数器1中断 第4 3
串口中断 第5 4
T2 – 定时器/计数器2中断 最低 5

因此T0中断服务程序如下:

void t0Intr() interrupt 0 { 
     //因为执行到此时,计数器已经清零,所以要重新赋值 TH0 = 0xD8; //65536-10000 TL0 = 0xF0; //55536 //下面写需要执行的操作 } 

代码如下

#include <reg51.h> #include <intrins.h> //num为计数器,每10ms将num加一,当num为100时为1s unsigned char num; sbit led = P1^0; //函数声明 void delay100ms(); //软件延时100ms void initT0(); //初始化定时器T0 void main() { 
     unsigned char k ; //初始化num值 num = 0; //初始化定时器 initT0(); //初始化led灯 led = 0; //初始化流水灯 P0 = 0xfe; k = 0xfe; while(1) { 
     //每100ms流水灯移位一次 k = _crol_(k, 1); P0 = k; delay100ms(); } } //t0定时器中断服务程序 //每隔10ms进入一次该程序 void t0Intr() interrupt 1 { 
     TH0 = 0xD8; TL0 = 0xF0; num++; //该变量加至100说明为1s if(num == 100) { 
     num = 0; led = ~led; //翻转led灯状态 } } void delay100ms() { 
     unsigned char a,b,c; for(c=19;c>0;c--) for(b=20;b>0;b--) for(a=130;a>0;a--); } void initT0() { 
     TMOD = 0x01; TH0 = 0xD8; TL0 = 0xF0; EA = 1; ET0 = 1; TR0 = 1; } 


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/231847.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Linux集群分发脚本xsync[通俗易懂]

    Linux集群分发脚本xsync[通俗易懂]Linux集群分发脚本xsync1.scp(securecopy)安全拷贝2.rsync远程同步工具3.xsync集群分发脚本4.免密登陆1.scp(securecopy)安全拷贝1)scp定义:scp可以实现服务器与服务器之间的数据拷贝(fromserver1toserver2)2)基本语法scp-r$pdir/$fname…

    2022年5月5日
    286
  • 操作系统概念(导论)

    操作系统概念(导论)SDU考试特别提醒:整无语了,遇到hmb老师出题就躺平了吧。八个论述两个计算(死锁检测、硬盘访问),论述题感觉像考研题,基本是结合xx谈谈xx这样。分数直接爆炸,心累了,呜呜。操作系统(概念)

    2022年7月1日
    27
  • 无线点餐系统服务器源代码,android 无线点餐系统,源码

    无线点餐系统服务器源代码,android 无线点餐系统,源码【实例简介】android无线点餐系统,源码,能直接运行。【实例截图】【核心代码】0jzexo└──无线点餐系统├──server│├──bin││├──clientServer.class││└──com││└──vista││└──Server││├──Selec…

    2022年6月19日
    26
  • CCAI 2017 | 中国工程院院士李德毅:L3的挑战与量产

    CCAI 2017 | 中国工程院院士李德毅:L3的挑战与量产

    2022年3月5日
    48
  • ubuntu 卸载apache

    ubuntu 卸载apache1.删除apache代码:$sudoapt-get–purgeremoveapache-common$sudoapt-get–purgeremoveapache2.找到没有删除掉的配置文件,一并删除代码:$sudofind/etc-name”*apache*”|xargsrm-rf$sudorm-rf/var/www$sudorm-rf/etc/libapache2-mod-jk3.删除关联,这样就可以再次用apt.

    2022年5月20日
    42
  • VRRP协议详解[通俗易懂]

    VRRP协议详解[通俗易懂]1  概述1.1  产生背景随着Internet的发展,人们对网络可靠性的要求越来越高。特别是对于终端用户来说,能够实时与网络其他部分保持联系是非常重要的。一般来说,主机通过设置默认网关来与外部网络联系,如图1所示: 图1 常用局域网组网方案主机将发送给外部网络的报文发送给网关,由网关传递给外部网络,从而实现主机与外部网络的通信。正常的情况下,主机可以完全信赖网关的工作,但…

    2025年8月22日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号