前面我们用的延时都是非精确延时,我们可以用一种比较精确的方法,单片机自带的定时器中断模块,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


