首页 > 编程知识 正文

c51单片机定时器的工作原理(32单片机)

时间:2023-05-04 13:17:19 阅读:76943 作者:3875

说明

单片机定时器中断是我们常用的,下面以51单片机为例说明单片机的定时器中断原理。

80C51定时/计数器的结构

时序/计数器的本质是将1计数器(16位)相加而成,由高位8位和低位8位两个寄存器构成。 TMOD是定时器/计数器的工作模式寄存器,决定工作模式和功能; TCON是控制寄存器,控制T0、T1的启动停止和溢出标志的设定。

中断系统介绍

中断系统是一组硬件电路,可以在每个机器周期中查询所有外围设备的标志位。 与前面的软件查询(if(xx==1) )相比,中断系统也称为硬件查询。 51个中断系统可以查到以下6个标志位。

ie0(TCON.1 )、外部中断0中断请求标志位。

it1(TCON.2 )、外部中断1触发方式控制位。

ie1(TCON.3 )、外部中断1中断请求标志位。

TF0(TCON.5 )、定时器/计数器T0溢出中断请求标志位。

TF1(TCON.7 )、定时器/计数器T1溢出中断请求标志位。

ri(Scon.0 )或ri(Scon.0 )、串行端口中断请求标志。 在串行端口接收完一帧串行数据时设置RI,或者在串行端口发送完一帧串行数据时设置TI,向CPU申请中断。

如果中断系统向外围设备查询的标志位变为1,则中断系统可以暂停当前的主循环,将程序跳转到用户事先指定的函数并执行。 要启动中断系统,必须首先进行中断初始化。 其步骤如下。

a、是否检查外围设备标志(EA=0或EA=1,EA也称为CPU中断允许)位() ) ) ) ) ) ) ) ) )。

b、查询标志1,是否跳过程序

c、跳转的目标函数,即中断服务子函数

因此,使用计时器中断时,首先初始化中断系统,接通总中断(相当于总开关),接通与计时器对应的控制位(相当于旁路开关),然后初始化计时器即可。 中断系统作为单片机的外围设备,只有在发生某个中断时才中断主循环,从对应的中断号引入对应的中断服务子函数。 下图显示了六个中断标志位的信息。

80C51单片机的定时器中断原理

在这里,我将谈谈单片机中断的应用,在cpu按照指令运行的时候,可能还有其他更紧急的事情要做。 中断服务程序需要在cpu暂停当前程序并完成后继续运行前面的程序。 就像吃饭的时候一边往水桶里倒水一边吃,水满了,赶紧关水龙头或者换个空水桶,然后回去吃饭。

单片机计时器就像水桶,启动了。 也就是说水龙头开着。 开始加水了; 时机在每个机器周期自动加1,最后溢出; 水桶里的水增加了,最满了。 计时器溢出后,你会处理的; 水桶里的水满了,你也应该处理; 处理结束后,单片机又处理了一个可以回到刚刚停止的地方继续运行的水桶,无论你以前在做什么,你都可以继续做什么。

单片机主程序从0x0000开始运行,单片机服务程序从哪里运行? 51有多个中断服务程序的入口。 0号入口是外部中断0,地址是0x0003。 1号入口是计时器0,在0x000B处; 2号入口为集中暴发1; 地址是0 x 0013,3,3号入口是计时器2; 地址是0x001B,等等。 发生中断时,程序会记录当前运行的位置,跳转到对应的中断条目运行中断服务程序,运行完成后,跳转到原来的位置继续运行。

在C51中,你不需要关心中断服务程序放在哪里,如何跳。 我应该把某个函数识别为几号中断服务函数。 如果发生相应的中断,此函数将自动运行。

计时器/计数器的工作原理

加上1计数器输入的计数脉冲有两个源,一个是从系统的时钟振荡器输出的脉冲被划分为12分频而发送过来; 一个是T0或T1端子输入的外部脉冲源。 每当脉冲计数器递增1时,如果在计数器中设置全1,则当输入另一个脉冲时,计数器返回零,计数器溢出导致TCON上设置TF0或TF1,并向CPU发出中断请求如果计时器/计数器以计时器模式运行,则表示计时器时间到了。 以计数模式动作时,表示计数值已满。

可见,只有从溢出时计数器的值中减去计数初始值,才会加上1计数器的计数值。

设定为定时器模式时,加1计数器是对内部机器周期进行计数。 1机器周期为12个振荡周期,也就是说,计数频率为石英振动频率的1/12。 计数值n乘以机器周期Tcy得到的结果是定时时间t。

如果设定为计数器模式,则外部事件计数脉冲从T0或T1端子输入计数器。 在每个机器周期的S5P2期间对T0、T1引脚电平进行采样。 在一个周期对高电平输入进行采样,在下一个周期对低电平进行采样时,计数器加1,更新的计数值在下一个机器周期的S3P1期间加载到计数器中。 因为检测从1到0的下降沿需要两个机器周期,所以采样的级别必须至少保持一个机器周期。 石英频率为12MHz时,最高计数频率为1/2MHz以下,即计数脉冲周期大于2 Us。

单片机利用中断实现时延原理分析

#定义

_1231_C_

#include “reg51.h”

//sbit OE=P2^3;

unsigned int SystemTime;

void timer0(void) interrupt 1 using 3 //中断部分代码,见下文的释疑

{

TH0 = 0xdb;

TL0 = 0xff;

// TF0 = 0;

SystemTime++;

}

void main()

{

TMOD &= 0xF0;

TMOD |= 0x01; //TMOD的值表示定时器工作方式选择

TH0 = 0xdb; //写入初始值,初始值可以决定定时多久

TL0 = 0xff;

//根据上文的木桶比喻的话,如果TH0 = 0x00;TL0 = 0x00;则表示从桶底开始装水。

//TH0 = 0xdb;TL0 = 0xff;可以这样子理解相当于木桶里已经有部分液铅勤恳的棉花糖,

//TH0和TL0这个两个值表示木桶里液铅的高度,即此时桶里只能从液铅的高度以上开始装水,

//TH0 = 0xff;TL0 = 0xff;即表示桶的最高位置。

TF0 = 0; //计数到时TF0为1,即当TH0 = 0xff;TL0 = 0xff;再运行一步TF0 = 1;

TR0 = 1; //开始计数,从这时起,每运行一步TH0和TL0都会增加,直到TH0 = 0xff;TL0 = 0xff;

//相当于开水龙头,如TR0=0则TH0和TL0不变

ET0 = 1; //允许定时器0中断

EA=1; //开总中断

//下面是个死循环,程序里每运行一步TH0和TL0都会增加,当增加到TH0 = 0xff;TL0 = 0xff;

//单片机会从死循环里退出,去执行中断部分的代码,即开始运行void timer0(void) interrupt 1 using 3{}

//运行完中断部分的代码后,接着继续执行死循环里的代码。

//注意:当TH0 = 0xff;TL0 = 0xff;再运行,TF0并没有从0变为1,个人猜测TF0=1;时触发了中断,并重新被置零。

//如把ET0 = 1;和EA=1;注释掉,当TH0 = 0xff;TL0 = 0xff;再运行,TF0会变为1,此时不会再执行中断部分代码。

while(1)

{

if ((SystemTime%100)《50) //SystemTime除以100,余数小于50为真

{

…………;

}

else

{

…………;

}

};

}

释疑:void Timer0() interrupt 1 using 1

Timer0 是函数名,随便取的

interrupt xx using y

跟在interrupt 后面的xx 值得是中断号,就是说这个函数对应第几个中断端口,一般在51中

0 外部中断0

1 定时器0

2 外部中断1

3 定时器1

4 串行中断

实际上编译的时候就是把你这个函数的入口地址方到这个对应中断的跳转地址

using y 这个y是说这个中断函数使用的那个寄存器组,51里面一般有4组 r0 -- r7寄存器,一共有32个,如果你的终端函数和别的程序用的不是同一个寄存器组则进入中断的时候就不会将寄存器组压入堆栈返回时也不会谈出来节省代码和时间

初始值算法:定时器是当总数达到FFFFH后产生中断吧!那你要让它计数10000,是不是用FFFF(16进制)减去10000(十进制)的数当计数初值 啊?TH0=-(10000/256); TL0=-(10000%256)跟FFFF(16进制)减去10000(十进制)的数是一样的。从TH0=-(10000/256); TL0=-(10000%256)开始计数,计数到10000刚好满。跟用FFFF(16进制)减去10000(十进制)的数一样!!!写起来更简单,不 用算!!!

看看原码、补码就知道。正数的补码是对应的二进制数,符号位为零,负数的补码是它的绝对值对应的二进制数按位取反再加一,符号位为一。无符号数不考虑符号,那么这个结果就跟用FFFF减去它的绝对值一样。

打开APP阅读更多精彩内容

点击阅读全文

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。