前面我们用的延时都是非精确延时,我们可以用一种比较精确的方法,单片机自带的定时器中断模块,89C52RC带2个定时器中断,ET0和ET1,中断的工作模式有4种,

定时器0为例,定时器0和定时器1是一样的都在TMOD中,

TMOD中有8位00000000前4位是定时器1的控制选择后4位是定时器0的控制选择,

4位中的后2位是模式选择

(1)模式0后两位是0013位计数模式不需要了解,平时都是用定时器1.

(2)模式1后两位是0116位计数模式最大65535分位高8位TH0,低八位TL0

(3)模式2后两位是10自动装填模式主要用在串行通讯时计算波特率

(4)模式3后两位是11变成2个最大255的计数器

我们先用模式1怎么计算定时值呢?

我们用12M举例单片机有个12分频,也就是晶振动作12次,就是单片机执行一条程序所用的时间12M=12000000除以12=1000000这是单片机1秒所能执行的程序条数

那1秒执行1000000次,一条程序需要1秒除以1000000=0.000001秒=1us

我们模式1计数最大65535,再加就是满溢为0,6553365534655350123

65535按照1us一条最大定时65毫秒=65000微秒如果我们定时1秒怎么定时呢?

我们可以先定时10毫秒就是65536-10000=55536转成16进制等于D8EF

将D8送入TH0(T在应用中时间的首字母,H是高的首字母,0是定时器0的意思)

将EF送入TL0(T在应用中时间的首字母,L是低级的首字母,0是定时器0的意思)

EA是所有中断的总开关的意思

ET0是定时器0的开关(不开这个开关,定时器0可以工作,我们就需要时时观察TR0为1还是为0)

TR0是定时器0开始运行的开关(TR0=1开始工作,=0停止工作,当满溢时自动变0)

我们试试让一个小灯1秒一亮,一秒一熄灭。

#

sbitLED=P2^0;

voidmain()

{

EA=1;//开总开关

TMOD=0x01;//让定时器0工作在模式116位计数方式

TH0=0xD8;//高8位

TL0=0xEF;//低8位

ET0=1;//开定时器0的开关

TR0=1;//开始运行定时器0

LED=0;小灯亮

while(1);//这里我们让循环在这里一直等待,

让定时器0去控制小灯的亮灭

}

voiddingshiqi0()interrupt1这里后面的interrupt1时定时器0的固定写法

下面解释一下

{

staticunsignedchari=0;//static时静态变量的意思只在这个子程序中运行

TH0=0xD8;//重新给高字节赋值

TL0=0xEF;//重新给低字节赋值

i++;//i中数每次加1

if(i=100)//如果i加到100就是100个10毫秒就是1秒

{

i=0;//让i从0开始

LED=~LED//每经过1秒LED转换一次状态,亮灭

}

}

我们用的变量分为全局变量和静态变量,局部变量,

全局变量是说在所有的子程序都可以用这个变量。公用的物品

局部变量是只有这个函数或者称子程序才可以用,你自己家的洗衣机

不过局部变量执行完这个程序跳到别的程序的时候,再进这个程序局部变量变成初始值,

静态变量=静态局部变量,就是和局部变量一样只有这个程序能用,但是可以保留上一次运行完的值。

咱们的中断是有顺序的,

外部中断0是第0个中断优先级最高

定时器0是第1个中断

外部中断1是第2个中断

定时器1是第3个中断

串行通讯中断是第4个中断

我们用的是定时器0,所以就写成interrupt1