单片机AT89S52定时器计数器.ppt_第1页
单片机AT89S52定时器计数器.ppt_第2页
单片机AT89S52定时器计数器.ppt_第3页
单片机AT89S52定时器计数器.ppt_第4页
单片机AT89S52定时器计数器.ppt_第5页
已阅读5页,还剩71页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1,第8章 定时器/计数器,第一节 概述 第二节 模式0、模式1及其应用 第三节 模式2及其应用 第四节 模式3及其应用 第五节 定时器/计数器2,2,第一节 概述,回忆8051结构特点:由单一内部总线连接各功能模块,通过特殊功能寄存器(SFR)集中控制。嵌入式结构,不同型号引脚定义和SFR定义有所不同,因此,从两个方面来认识和掌握某一个功能模块。 相关引脚功能 相关SFR功能,4,两个16位定时计数器,最大计数范围:0000-FFFFH。 相关的SFR:TMOD、TCON、TH0、TL0、TH1、TL1。 相关引脚:T0、T1、INT0、INT1。 4种工作方式。,8051定时器/计数器概况,5,T0、T1相关引脚,T0、T1:计数脉冲输入,定时方式时不用,作I/O INT0、INT1:与定时器运行控制有关,也可以无关,可编程设定,6,T0、T1相关SFR,7,定时器/计数器原理,8,定时功能:对固定频率的机器周期计数, 每个机器周期定时器加1,计数速率=Fosc/12 计数功能:对外部引脚(T0和T1)上的负跳变计数,每产生 一个负跳变,计数器加1,要求高低电平均要大 于1Tm, 计数速率Fosc/24,9,以N位计数器构为核心,要解决以下问题: (1)、何时控制启动、停止计数? (2)、如何控制定时还是计数? (3)、如何控制定时/计数的长短? (4)、如何用查询或中断管理溢出事件?,10,GATE 选通门: GATE=0时, 只要TRx=1,计数器就开始工作; GATE=1时, 只有INTx脚和TRx同时为“1”时,计数器才开始工作.主要用于测量INTx脚上高电平脉冲的宽度. C/T 计数/定时方式选择位: C/T=1时,计数方式. 即计数器的计数脉冲来自T0或T1引脚的外部事件.C/T=0时:定时方式,计数脉冲来自内部振荡频率fosc的12分频.,模式寄存器TMOD (SFR的地址:89H,不可按位寻址),11,M1、M0 模式选择:分别对应四种模式. M1 M0=00, 方式0:13位定时计数器 M1 M0=01, 方式1: 16位定时计数器 M1 M0=10, 方式2: 自动重装入的8位定时计数器 M1 M0=11, 方式3: T0成为两个独立的8位计数器,12,T=(M-TC)t 其中,T: 定时时间,M: 计数器的模,TC:计数初值,t:计数器计数脉冲的周期(对于定时方式t = fosc/12)。,定时/计数器4种模式比较,13,TF1,TF0 定时器T1,T0的溢出标志:计数器溢出时硬件自动置位, 即TFx=1, 进入中断后再由硬件自动清除; TR1,TR0 计数器T1,T0的控制位:由软件置位(计数器开始工作)或清零(计数器停止工作). IE1,IE0 外部中断INT1,INT0的请求标志:当单片机检测到INTx引脚上有低电平或下降沿时, IEx=1,申请中断. IT1,IT0 外中断触发类型控制:ITx=1时,外中断信号的下降沿触发IEx标志,ITx=0时,外中断信号的低电平触发IEx标志.,控制寄存器TCON (SFR地址:88H),(LSB),(MSB),14,第一节 概述 第二节 模式0、模式1及其应用 第三节 模式2及其应用 第四节 模式3及其应用 第五节 定时器/计数器2,15,Timer/Counter 0/1 Mode 0: 13-Bit Counter (Timer 1 shown),16,Timer/Counter 0/1 Mode 1: 16-Bit Counter (Timer 0 shown),17,1、设置GATE=0,则GATE=1, 因此Y=TR0,这样: TR0=1; 启动定时器T0运行 TR0=0; 停止定时器T0运行 我们把这种控制定时器运行的方法叫软触发,最常用。 2、设置GATE=1,则GATE=0, 因此Y=TR0*INT0电平, 进一步令TR0=1, 则Y=INT0电平, 这样: INT0为高电平,启动定时器T0运行 INT0为低电平,停止定时器T0运行 我们把这种控制定时器运行的方法叫硬触发,较少用,可以用来测量正脉冲的宽度。,定时器/计数器运行控制方法,18,根据要求给方式寄存器TMOD送一个方式控制字,以设定定时器的工作方式;(要考虑定时/计数范围,重装方式) 根据需要给C/T送初值以确定需要的定时时间或计数次数;(可选,缺省为0000) 根据需要给中断允许寄存器IE送中断控制字,以开放相应的中断和设定中断优先级;(可选) 给TCON送命令字以启动或禁止C/T的运行。,定时器/计数器的初始化方法,19,计数器初值: 设计数模值为M,计数初值设定为TC,计数器计满为零所需的计数值为C,则:TC=M-C (M=213,216,28) 定时器初值: T=(M-TC)Tm , T为需要定时时间 初值TC=M-T/Tm 当定时或计数范围大于某一模式下的计数范围时,要用软件对溢出计数,以增加定时或计数的范围。,初值的计算,20,例: Fosc=12MHz,试计算定时时间2ms所需的定时器的初值.,方式2、方式3 TMAX=0.256ms,所以必须将工作方式设在方式0或方式1 方式0:TC=213-2ms/1us=6192=1830H TL0=10H,TH0=0C1H 注意1830H到TH0、TL0的重新表达,主要是由 于TL0已经不是每256进1, 而是每32进1 方式1:TC=216-2ms/1us =63536=0F830H TL0=30H,TH0=0F8H,21,采用查询方式:程序一直检测TF0(或TF1),若TF01(或TF1=1),说明定时时间到或计满数,从而开始相应处理,如: while(TF0=0); / while(!TF0); TF0=0; /清除标志位 / 开始处理溢出事件 采用中断方式:程序初始化时,设置定时器溢出中断允许后,内部硬件自动检测到TF01(或TF1=1)时,自动响应中断,进入中断服务程序。,CPU控制C/T的方式,22,例1:在P1.7引脚上输出50Hz的方波,已知Fosc=12MHz。,23,解决定时器/计数器应用问题的一般流程,确定定时/计数对象 C/T初始化 工作模式 计算初值 中断或查询 启动C/T运行 编程实现,24,1、确定定时对象: 20ms 或 10ms ? 应当为10ms,便于产生方波:每隔10ms引脚电平取反。 2、Fosc=12MHz, 1Tm=1us, 产生10ms定时, 应选择模式0、1、2、3 ? 应选择模式1,16位定时器,最大范围65.536ms。,分析: 50Hz的方波,周期为1/50=20ms,25,3、计算初值 TC=65536-10ms/1us=55536=0D8F0H,分析: 50Hz的方波,周期为1/50=20ms,26,编程实现(查询方式),#include /要用到SFR sbit SQW=P17; /*定义输出方波引脚*/ main() TMOD=0x01; /* T0 模式1, 定时, GATE=0 */ TR0=1; /* 启动 T0 运行 */ while(1) /* 无限循环作为main的结束 */ TH0=0xD8; TL0=0xF0; /* 每次要重新赋10ms 定时的初值*/ while (! TF0); TF0=0; /* 查询等10ms时间到,并清除标志 */ SQW = ! SQW ; /* 引脚每隔10ms电平取反,产生50Hz方波*/ ,27,编程实现(中断方式),#include /* 要用到SFR */ sbit SQW=P17; /*定义输出方波引脚*/ main() /*主程序*/ TMOD=0x01; /* T0 模式1, 定时, GATE=0 */ TH0=0xD8; /* 赋初值 */ TL0=0xF0; ET0=1; EA=1; /* 允许T0中断 */ TR0=1; /* 启动 T0 运行 */ while(1); /* 无限循环作为main的结束 */ ,28,编程实现(中断方式),void out_sqw(void) interrupt 1 /*中断服务程序*/ /* TF0 标志被自动清除 */ SQW = ! SQW; /* 引脚每隔10ms电平取反,产生50Hz方波 */ TH0=0xD8; TL0=0xF0; /* 重赋初值 */ ,29,例2 :在P1.0引脚上输出周期1秒,占空比为20%的方波,已知Fosc=12MHz。,30,1、确定定时对象: 1s、200ms 或 800ms ? 应当小于定时器的最大定时时间,对于模式1,最长为65.536ms,为了便于计算,取50ms作为定时对象,再用一个字节对溢出计数。 50ms * 4 = 200 ms 50ms * 16 = 800 ms,分析: 占空比20%的方波,周期为1s,31,2、Fosc=12MHz, 1Tm=1us, 产生50ms定时, 应选择模式0、1、2、3 ? 应选择模式1,16位定时器,最大范围65.536ms。在所有工作模式中,模式1的定时/计数范围是最大的。,分析: 占空比20%的方波,周期为1s,32,3、计算初值 TC=65536-50ms/1us=15536=3CB0H,分析: 占空比20%的方波,周期为1s,33,编程实现(查询方式),#include /要用到SFR sbit SQW=P10; /*定义输出方波引脚*/ bit will_be_high=0; /*定义一个标志位,0:将要输出低电平, 1:将要输出高电平*/ unsigned char overflow_counter=16; /*由800ms低电平开始,减到0,时间到,改200ms定时, overflow_counter=4 */ main() TMOD=0x10; /* T1 模式1, 定时, GATE=0 */ TH1=0x3C; TL1=0xB0; /* 赋50ms定时初值 */ TR1=1; /* 启动 T1 运行 */,34,编程实现(查询方式),for(; ;) /* 无限循环作为main的结束 */ /* 如果要输出高电平,则输出高电平,4*50ms,下一次将为低电平;否则输出低电平,16*50ms,下一次将为高电平 */ if (will_be _high) overflow_counter=4; SQW=1; will_be _high=0; else overflow_counter=16; SQW=0; will_be _high=1; do while (! TF1); TF1=0; /* 查询等50ms时间到,并清除标志 */ TH1=0x3C; TL1=0xB0; /* 每次要重新赋50ms 定时的初值*/ while( - overflow_counter); /end of for(; ;) /end of main,35,编程实现(中断方式),#include /要用到SFR sbit SQW=P10; /*定义输出方波引脚*/ bit is_high=0; /当前状态 unsigned char overflow_counter=16; /*由800ms低电平开始,减到0,时间到,改200ms定时, overflow_counter=4 */ main() TMOD=0x10; /* T1 模式1, 定时, GATE=0 */ TH1=0x3C; TL1=0xB0; /* 赋50ms定时初值 */ ET1=1; EA=1; /* 允许T1中断 */ TR1=1; /* 启动 T1 运行 */ SQW=0; /* 输出低电平 */ while(1); /* 无限循环作为main的结束 */ ,36,编程实现(中断方式),void out_sqw(void) interrupt 3 /*中断服务程序*/ /* TF1 标志被自动清除 */ TH1=0x3C; TL1=0xB0; /* 重赋50ms定时初值*/ if (- overflow_counter != 0) return; /* 定时未到返回 */ if (is_high) overflow_counter = 16; SQW=0; is_high=0; else overflow_counter = 4; SQW=1; is_high=1; ,37,例3 :在P1.0引脚上每隔2ms产生4us的负脉冲,已知Fosc=6MHz,采用T0模式0。,38,1、确定定时对象: 2ms 或 4us ? 应当是2ms, 而4us负脉冲可以通过指令本身的延时来实现。如: P10=0; /1Tm =2us _nop_(); /1Tm =2us P10=1; /1Tm =2us,分析: 周期性负脉冲,39,2、指定模式0,不用选择。 3、计算初值 TC=213-2ms/2us=7192=1C18H 0001 1100 0001 1000B, 初值: TH0=0E0H, TL0=18H,分析: 周期性负脉冲,40,编程实现(查询方式),#include /要用到SFR #include /包含_nop_(); sbit Pulse=P10; /*定义输出脉冲的引脚*/ main() TMOD=0x0; TR0=1; /* T0 模式,定时, GATE=0, 启动 T0 */ while(1) /* 无限循环作为main的结束 */ TH0=0xE0; TL0=0x18; /* 每次要重新赋2ms 定时的初值*/ while (! TF0); TF0=0; /* 查询等2ms时间到,并清除标志 */ Pulse=0; _nop_(); Pulse=1; /* 产生4us负脉冲*/ ,41,编程实现(中断方式),#include /要用到SFR #include /包含_nop_(); sbit Pulse=P10; /*定义输出脉冲的引脚*/ main() TMOD=0x0; /* T0 模式,定时, GATE=0 */ TH0=0xE0; TL0=0x18; /* 赋2ms 定时的初值*/ ET0=1; EA=1; /* 允许T0中断 */ TR0=1; /* 启动 T0 运行 */ for(;); /* 循环结束, 也可以做别的事 */ ,42,编程实现(中断方式),void out_pulse(void) interrupt 1 /*中断服务程序*/ /* TF0 标志被自动清除 */ TH0=0xE0; TL0=0x18; /* 重赋2ms定时初值*/ Pulse=0; _nop_(); Pulse=1; /* 产生4us负脉冲*/ ,43,例4 :利用T0门控位测量INT0引脚上出现的正脉冲的宽度,并以机器周期数表示。,44,1、设置GATE=0,则GATE=1, 因此Y=TR0,这样: TR0=1; 启动定时器T0运行 TR0=0; 停止定时器T0运行 我们把这种控制定时器运行的方法叫软触发,最常用。 2、设置GATE=1,则GATE=0, 因此Y=TR0*INT0电平, 进一步令TR0=1, 则Y=INT0电平, 这样: INT0为高电平,启动定时器T0运行 INT0为低电平,停止定时器T0运行 我们把这种控制定时器运行的方法叫硬触发,较少用,可以用来测量正脉冲的宽度。,回顾:定时器/计数器运行控制方法,45,1、确定定时对象? 高电平期间定时器计了多少个机器周期,因此在上升的时候让(TH0,TL0)=0000并开始计时, 下降后停止,看计数器的值为多少即为所求,假定机器周期数不超过定时器的最大值。,分析,46,2、应选择模式0、1、2、3 ? 应选择模式1,16位定时器,最大范围65536Tm。在所有工作模式中,模式1的范围是最大的。 3、计算初值 从0000开始,但要注意要在从低到高跳变前赋值。,分析,47,#include /要用到SFR sbit PPulse=P32; /*定义输入脉冲的引脚*/ unsigned char data *p=0x30; /结果存入30H开始的2个单元中 main() TMOD=0x09; TH0=0; TL0=0; /* T0 模式1, 定时, GATE=1*/ while (PPulse); TR0=1; /等低电平,准备计时 while (! PPulse); /等高电平后,自动开始计时 while (PPulse); TR0=0; /等低电平,停止计时 *p+=TH0; *p=TL0; /存入结果 while(1) ; /* 循环结束 */ ,编程实现,48,第一节 概述 第二节 模式0、模式1及其应用 第三节 模式2及其应用 第四节 模式3及其应用 第五节 定时器/计数器2,49,Timer/Counter 0 Mode 2: 8-Bit Auto-Reload,50,Timer/Counter 1 Mode 2: 8-Bit Auto-Reload,51,例5:在P1.7引脚上输出2KHz的方波,已知Fosc=12MHz。,52,1、确定定时对象: 250us, 便于产生方波:每隔250us引脚电平取反。 2、Fosc=12MHz, 1Tm=1us, 产生256us定时, 应选择模式0、1、2、3 ? 应选择模式2,8位定时器,最大范围256us,由于自动重装载,重装过程没有引入误差,最理想。,分析: 2KHz的方波,周期为1/2000=500us,53,3、计算初值 TC=256-250us/1us=6,分析: 2KHz的方波,周期为1/2000=500us,54,编程实现(查询方式),#include /要用到SFR sbit SQW=P17; /*定义输出方波引脚*/ main() TMOD=0x02; /* T0 模式2, 定时, GATE=0 */ TH0=6; TL0=6; /* 只在此赋初值一次 */ TR0=1; /* 启动 T0 运行 */ while(1) /* 无限循环作为main的结束 */ while (! TF0); TF0=0; /* 查询等250us时间到,并清除标志 */ SQW = ! SQW ; /* 每隔250us电平取反,产生2KHz方波*/ ,55,编程实现(中断方式),#include /* 要用到SFR */ sbit SQW=P17; /*定义输出方波引脚*/ main() /*主程序*/ TMOD=0x02; /* T0 模式2, 定时, GATE=0 */ TH0=6; TL0=6; TR0=1; /* 赋初值并启动 T0运行 */ ET0=1; EA=1; /* 允许T0中断 */ while(1); /* 无限循环作为main的结束 */ void out_sqw(void) interrupt 1 /*中断服务程序*/ SQW = ! SQW; /* 引脚每隔250us电平取反,产生2KHz方波, 不 用反复赋初值 */,56,第一节 概述 第二节 模式0、模式1及其应用 第三节 模式2及其应用 第四节 模式3及其应用 第五节 定时器/计数器2,57,Timer/Counter 0 Mode 3: Two 8-Bit Counters,58,1、TH0计数脉冲来自内部fosc,所以它只能处于”定时”方式; 2、TH0分别借用了定时器T1的TR1和TF1来为自己工作,使TH0能象TL0那样用TR1启动定时,并用TF1来作为TH0的溢出中断的标志; 3、由于T1缺少了启动控制信号TR1和溢出中断标志TF1,那么在模式3时,T1是如何工作? 没有溢出中断标志TF1,则T1就不能用中断方式工作(实际上连查询也不行);没有启动控制信号TR1, 让它事先设定为自动重装模式, 则T0模式3会让T1自动工作。,模式3时T0(TH0,TL0)及T1的各自特点:,59,4, 模式3就是将单片机原有的T0,T1两个计数器变成三个独立的计数器,其中T1要事先设定为模式2(串行口的波特率发生器)。 5、注意:T0不用时的处理,一般置0方式,禁止进入方式3,以防止影响T1的工作。,模式3时T0(TH0,TL0)及T1的各自特点:,60,将T0分解为两个计数器 TL0和TH0,其中TH0借 用了T1的TR1和TF1,T1已无TR1,TF1功能, 建议T1做波特率发生器,TH0,TL0和T1组成3个8位计数器,模式3时T0、T1的工作原理示意图,61,例6:设一个89S51系统已经使用了2个外部中断,并置T1于模式2作串口波特率发生器用,现要求通过T0再增加一个外部中断,同时由P1.0输出5KHz的方波。已知Fosc=12MHz。,62,1、已经用掉的资源: 2个外部中断、T1(模式2)、串口 2、用T0实现: 1个外部中断、定时产生5KHz方波 用方式3:TH0、TL0作为2个独立的8位定时器/计数器。 1个外部中断: TL0,计数方式,初值FFH,每来一个负跳变就溢出,相当于一个边沿触发的外部中断。 定时产生5KHz方波:TH0,定时方式,初值156,每隔100us使P1.0取反,产生周期为200us的方波。,分析,63,编程实现,#include /要用到SFR sbit SQW_5KHz=P10; /*定义输出脉冲的引脚*/ main() TMOD=0x27; /* GATE=0, T1 模式2, 定时,T0模式3,计数 */ TH1=0xE8; TL1=0xE8; /*T1的初值, 产生一种波特率*/ TL0=0xFF; /*TL0的初值*/ TH0=156; /* 赋100us定时的初值*/ IE=0x9F; /* 允许所有中断 */ PT1=1; /* 产生方波优先级最高 */ TR0=1; TR1=1; /* 启动 T0, T1运行 */ for(;); /* 循环结束, 也可以做别的事 */ ,64,编程实现,void No3_int(void) interrupt 1 /*中断服务程序*/ /* 进行中断处理, 省略*/ TL0=255; /* 重赋0xFF 计数初值*/ void out_sqw(void) interrupt 3 /*中断服务程序*/ TH0=156 /* 重赋100us定时初值, 如果精确定时, 应加几个Tm*/ SQW_5KHz = ! SQW_5KHz; /* 产生5KHz方波*/ ,65,编程实现,void No1_int(void) interrupt 0 /*外部中断0 中断服务程序*/ /* 进行中断处理, 省略*/ void No2_int(void) interrupt 2 /*外部中断1 中断服务程序*/ /* 进行中断处理, 省略*/ void Serial_int(void) interrupt 4 /*串口中断服务程序*/

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论