后来知道了中断的含义,但对于第一个接触单片机的人来说,很难解释清楚。
所以我在这里打个比方。假设当你在房间里看书时,你客厅里的电话响起并闪烁。电话来了,你听到铃声,然后放下书,用书签记录你的书页,然后出去听电话。听完之后,回到你的房间,从书签标记的位置继续阅读你的书。
好了,分析一下上面的动作。当电话铃响,你听到它,它打扰了。你用书签标记位置,那现场保护;听电话,就是执行中断;打完电话后,要从刚才标记的地方继续读,也就是中断后,回到原来中断的地方,继续执行程序。这就是中断的过程。
假设没有中断,你会怎么做?可以用扫描的方式:手机赢了环,只有闪光,但你必须在你的房间里阅读。然后你只能每隔几段就跑出去看看有没有电话。如果没有,就跑回去读。如果有,那你可以听听电话。很明显,扫描的方式效率非常低,因为每看一本书,你都要花时间看手机的闪光灯,以确定是否有来电,这大大降低了你的阅读效率。而且扫描方式有一个最大的缺点,就是中断丢失。试想一下,如果扫描间隔太大(也就是看了很久的书才检查手机),你很可能会丢失几个重要的来电。
其实上面的比喻很能说明打断的作用。其实中断是为了应对突发事件。
对于MCU来说,有太多意想不到的事情,比如用户给MCU输入数据,按键,这些都是MCU本身可以做到的事情估计。外来数据的突然输入也是突发事件。这些外部突发信号一般由单片机的外部中断来处理。外部中断其实就是一个管脚的状态变化引起的中断,后面会讲到。
下面是定时器和定时器中断:
在测控系统中,经常需要实时时钟来实现定时控制、定时测量或定时中断。通常需要一个计数器来计数外部事件。MCS-51单片机有两个(增强型三个)十六位定时计数器T0和T1,简称定时器0和定时器1,都是可编程定时计数器。
3354以上的p字抄袭94页第一段《单片微型计算机与接口技术》-_-#!
其实,你问什么是计时器,但我真的不我不知道该用什么词。当我第一次学习它的时候,我听到这样一句话定时器是单片机上的宝贵资源。我没有那时我不知道。为什么这种资源很珍贵?后来我才知道定时器的伟大。当然,理解这一点需要一段时间。在这里,你d最好往下看:)
就像我开头说的,看这本教材的时候,至少需要一本单片机基础的书,随便买一本就行。反正现在的单片机书都是你我抄的,都是一样的。最重要的是实例。拿起你的书,看看单片机的中断寄存器和定时器寄存器。让让我们开始写程序吧。时间不等人D~~~~ ~
MCU模式0为13位,从未使用过。有16位你不不需要使用13位?太浪费了~ ~ ~
然后计算加载值,16位,也就是16位二进制,2的16次方,也就是65536。16位定时器从一个所谓的加载值开始,加到65536就满了。如果你允许定时器中断,就会有一个中断。所以16位加载值的计算很简单:
6536-想要计算的脉冲数=加载值
但是我们通常要对脉冲进行计时,而不仅仅是数脉冲的个数,所以你要数的脉冲个数要换算成时间。我我告诉你,一个脉冲的时间是一个机器周期,51的机器周期是12/晶振值。如果你的晶振是12M,那么这个除法就是1US。美国整数,什么都好算,所以现在你知道为什么买了那么多12M,24M的晶振了吧,都是51的。
#i包括reg51.h
void initTimer(void)
{
TMOD=0x 1;
TH0=0xd8
TL0=0xf0
}
无效定时器0(无效)中断1
{
TH0=0xd8
TL0=0xf0
//在此添加您的代码。
}
无效总管(无效)
{
init timer();
TR0=1;
ET0=1;
EA=1;
while(1);
}
上面的代码是一个12M晶振下10000US定时的程序,也就是10MS发生一次中断。InitTimer()是初始化函数,用于设置计时值和中断。
10000US是12M晶振下的100000个机器周期,65536-100000=55536=D8F0(十六进制),所以上面是TH0=0xd8TL0=0xf0
无效定时器0(void)中断1是定时器0的中断功能。我们不不需要注意汇编的中断。我们只需要知道,当中断来临时,程序会自动跳转到定时器0(void)运行。运行后,我们将返回到原来的中断,继续执行原来的程序。
中断是C51中的关键字,所有跟在中断后面的函数都是中断函数。那么它对应的是哪个中断呢?请参考:开头给大家介绍的《Keil软件-Cx51编译器用户手册》完整中文版,(名字太长,后面就叫KEIL手册了),第125页。
中断号中断地址
0 0003H
1 000BH
2 0013H
3 001BH
4 0023H
5 002BH
6 0033H
7 003BH
8 0043H
9 004BH
10 0053H
11 005BH
12 0063H
13 006BH
14 0073H
15 007BH
16 0083H
17 008BH
18 0093H
19 009BH
20 00A3H
21 00ABH
22 00B3H
23 00BBH
24 00C3H
25 00CBH
26 00D3H
27 00DBH
28 00E3H
29 00EBH
30 00F3H
31 000英尺/小时
看,中断号对应于中断入口地址。中断入口地址是什么?这是发生中断时MCU自动跳转到的地址段。
对于定时器0,它是000BH,因此它对应于中断号1。其他中断地址可以看书找。从上表可以看出,KEILC支持32个中断,但是到目前为止,我还没有没见过51单片机32中断:)
好吧,让进入调试练习。输入上面的代码,或者直接下载我编译的项目:
定时器0
进入项目后,需要设置一些东西:
调试信息是调试信息。选择这个东西只能用C语言模拟(不管是软的还是硬的),否则你的模拟环境是编译的!
软模拟设置:
Go till MAIN()是模拟时直接跳转到主函数。如果未选中,将从0地址开始。这里这是一个概念。在C51中,mian()函数不代表0地址。要知道,keilc在开始的时候需要进行大量的初始化工作,比如清除RAM的内容,设置堆栈等。你不你的用户程序不需要这样做。不包括。在这些初始化之后,KEIL会自动跳转到您的mian进行处理。
仿真软件可以选择晶振,我们选择12M。你可以根据图片选择以下的东西,细节稍后再谈。
如果编译成功,那么我们将开始第一次软件模拟:
上面已经进入模拟状态,因为我们选择了调试信息,所以可以在C下调试,而且因为我们选择了Go till main(),所以可以看到开头有一个箭头指向main()的第一句话。而程序旁边深色的东西,也就是我圈出来的,就是有效代码段。程序只会在那里运行,也就是黄色箭头只会在那个区域运行。现在可以模拟了,单步全速运行。KEIL的具体模拟将在下一章说明。
标签:定时器单片程序