CH7定时器计数器的应用.docx
《CH7定时器计数器的应用.docx》由会员分享,可在线阅读,更多相关《CH7定时器计数器的应用.docx(16页珍藏版)》请在冰豆网上搜索。
CH7定时器计数器的应用
课题名称
第七章第一节定时器/计数器的应用
计划学时
2课时
内容分析
知识点:
定时/计数器的内部结构、工作方式及应用
实例7-5-1查询方式、实例7-5-2中断方式、实例7-5-360秒定时器、实例7-5-5频率发生器(略)
教学目标及要求
理解MCS-51内部定时/计数器的构成及工作原理,掌握定时/计数器的应用。
重点及措施
教学重点:
定时/计数器的应用
难点及措施
教学难点:
定时/计数器的应用
教学方式
教学采用教师课堂讲授为主,使用多媒体教学方式,学生讨论、交流与提问。
教
学
过
程
一、引入
回顾第六章中断的相关概念,引入定时/计数器的中断的概念。
本章的重难点都在定时/计数器的应用。
定时/计数的概念----一个定时/计数的形象实例
假如有一个水容器,1000滴水刚好装满
问:
还需滴入多少滴水才能将其装满?
答:
还需滴入500滴水才能将其装满,501滴溢出。
这就是“计数”
初始时已经装入500滴水这就是“计数初值”
问:
如果每秒滴入1滴水,还需多长时间才能将其装满?
答:
还需500秒时间才能将其装满,501秒溢出。
这就是“定时”
二、新授
定时/计数器:
对电脉冲进行计数的单元电路。
定时与计数的关系:
●用计数器为周期性脉冲计数,产生定时。
●定时和计数是同一个概念,本质上定时只是计数的一个特例。
定时计数器工作时,关心问题:
1、定时/计数器(容器)的位宽度。
2、初值(容器初始已有水滴数)的设置。
3、水溢出以后的处理。
§7.18051定时器/计数器
7.1.18051定时器/计数器结构
1)有两个16位的定时器/计数器,即定时器0(T0)和定时器1(T1)
T0由两个8位特殊功能寄存器TH0和TL0构成;T1两个8位特殊功能寄存器由TH1和TL1构成。
2)控制寄存器TCON:
控制T0、T1的启停、中断等
3)方式寄存器TMOD:
控制T0、T1的工作方式
§7.1.28051定时器功能
每个定时器都可由软件设置为定时工作方式或计数工作方式及其他灵活多样的可控功能方式。
这些功能由特殊功能寄存器TMOD和TCON所控制。
定时器工作不占用CPU时间,除非定时器/计数器溢出,才能中断CPU的当前操作。
每个定时器/计数器还有四种工作模式。
其中模式0-2对T0和T1是一样的,模式3对两者不同。
1)计数工作方式
对T0(P3.4)和T1(P3.5)引脚上输入的外部脉冲进行计数。
当外部输入脉冲发生负跳变时,进行“+1”计数,CPU检测一个1至0的跳变需要两个机器周期,要求外来计数脉冲的频率不得高于单片机系统振荡脉冲频率的1/24。
2)定时工作方式
对系统的时钟振荡器输出脉冲的12分频信号(fOSC/12)进行计数定时。
由于一个机器周期等于12个振荡脉冲周期,所以此时的T/C是每到一个机器周期就加1,即机器内部震荡信号的1/12分频,每一个机器周期做一次“+1”运算。
以机器周期为最小定时单位。
当8051采用12MHz晶振时,一个机器周期为1μs,计数频率为1MHz。
7.1.3工作模式寄存器TMOD
•TMOD用于控制T0和T1的工作模式。
•TMOD不能位寻址,只能用字节设置定时器的工作模式,低半字节设置T0,高半字节设置T1。
•8051系统复位时,TMOD的所有位被清0。
1.方式0
13位定时/计数器。
THx8位和TLx低5位组成13位加1计数器
t=(213-T0初值)×振荡周期×12
计数外部脉冲个数:
1~8192(213)
2.方式1
16位定时/计数器。
THx8位和TLx低8位组成16位加1计数器
t=(216-T1初值)×振荡周期×12
计数外部脉冲个数:
1~65536(216)
3.方式2
自动恢复初值8位定时/计数器。
TLx为8位加1计数器,THx为8位初值暂存器。
用于需要重复定时和计数的场合。
最大计数值:
256(28)
最大定时时间(T=1s):
256s
4.方式3
T0分成2个8位定时器:
TL0定时/计数器和TH0定时器
TL0占用T0控制位:
C/T,TR0,GATE;
TH0占用T1控制位:
TR1。
T1不能使用方式3工作。
7.1.4定时器/计数器控制寄存器TCON
7.2计数寄存器
1)mode0填入计数值范例
TL0=(8192-6000)%32;
TH0=(8192-6000)/32;
2)mode1填入计数值范例
TL0=(65536-50000)%256;
TH0=(65536-50000)/256;
3)mode2填入计数值范例
TL0=256-100;
TH0=256-100;
4)定时器中断设置范例
IE=0X82;
IP=0X02;
TMOD=0X01;
5)启动定时器命令
TRX=1;
中断子程序第一行的格式
7.3实例演练
查询与中断
查询方式:
主程序什么也不做,只是不断地查询Timer是否中断了,而不需准备中断子程序。
中断方式:
主程序专注于其它事情,待Timer中断时,才执行中断子程序。
查询的特色
●可以不要设置中断使能寄存器,即不开启中断总开关与定时器开关。
●当定时器标志变为1之后,还得使用“TF0=0;”将定时器标志变为0,该定时器才能重新启用。
●不使用中断子程序。
实例演练7-3-1闪烁灯实验-查询方式
1)使用mode0设计
•当在Mode0方式工作时,每次最多可计数8192,约8毫秒,若只计数5000,则为5毫秒,必须重复50次才延迟0.2秒钟(5m×50)。
2)使用mode1设计
•当在Mode1方式工作时,每次最多可计数65536,约65毫秒,若只计数50000,则为50毫秒,必须重复5次才延迟0.25秒钟(50m×5)。
3)使用mode2设计
•当在Mode2或Mode3方式工作时,每次最多可计数256,约0.25毫秒,若只计数250,则为0.25毫秒,必须重复1000次才延迟0.25秒钟(0.25m×1000)。
/*ch07-5-1.c-计时器实验I-垂询方式-高低位灯互闪*/
#include//定义8x51暂存器
#defineLEDP1//定义LED接至Port1
#definecount50000//T0(MODE1)之计量值,约0.05秒(7-8页)
#defineTH_M1(65636-count)/256//T0(Mode1)计量高8位元
#defineTL_M1(65636-count)%256//T0(Mode1)计量低8位元
main()//主程序开始
{inti;//宣告i变数
//TMOD&=0xf1;//设定T0为mode1(7-3页)
//TMOD|=0x01;//设定T0为mode1(7-3页)
TMOD=0x01;
LED=0xf0;//LED初值=11110000,右4灯亮
while
(1)//无穷循环,程序一直跑
{for(i=0;i<5;i++)//for循环,计时中断5次
{TH0=TH_M1;//设置高8位元
TL0=TL_M1;//设置低8位元
TR0=1;//启动T0(7-7页)
while(TF0==0);//等待溢位(TF0==1)
TF0=0;//溢位後,清除TF0,关闭T0
}//for循环计时结束
LED=~LED;//输出反相
}//while循环结束
}//主程序结束
思考:
•在本实验里,所采用的是Timer0,若要采用Timer1,应如何修改?
•若要使用mode2来完成本实验的功能,程序应如何修改?
实例演练7-3-2闪烁灯实验-中断方式
/*ch07-5-2.c-计时器实验2-中断方式-高低位灯互闪*/
//==声明区================================
#include//定义8x51暂存器
#defineLEDP1//定义LED接至Port1
#definecount50000//T0(MODE1)之计量值,约0.05秒
#defineTH_M1(65636-count)/256//T0(Mode1)计量高8位元
#defineTL_M1(65636-count)%256//T0(Mode1)计量低8位元
intIntCount=0;//宣告IntCount变数,计算T0中断次数
//==主程序================================
main()//主程序开始
{IE=0x82;//启用T0中断(6-4页)
TMOD&=0xf1;TMOD|=0x01;//设定T0为mode1(7-3页)
TH0=TH_M1;TL0=TL_M1;//设置T0计数量高8位元、低8位元
TR0=1;//启动T0
LED=0xf0;//LED初值=11110000,右4灯亮
while
(1);//无穷循环,程序停滞
}//主程序结束
//==T0中断子程序-每中断5次,LED反相================
voidtimer0(void)interrupt1//T0中断子程序开始
{TH0=TH_M1;TL0=TL_M1;//设置T0计数量高8位元、低8位元
if(++IntCount==5)//若T0已中断5次数
{IntCount=0;//重新计次
LED^=0xff;//输出相反
}//if叙述结束
}//T0中断子程序
实例演练7-3-360秒定时实验
/*ch07-5-3.c-计时器实验3-60秒计数器,每1分钟LED反相1次*/
//==声明区================================
#include//定义8x51暂存器
#defineSEGP2//定义七节显示器接至Port2
#defineSCANPP1//定义扫瞄线接至Port1
sbitLED=P0^7;//声明LED接至P0.7
/*声明T0计时相关声明*///THxTLx计算参考
#definecount_M150000//T0(MODE1)之计量值,0.05s
#defineTH_M1(65636-count_M1)/256//T0(MODE1)计量高8位元
#defineTL_M1(65636-count_M1)%256//T0(MODE1)计量低8位元
intcount_T0=0;//计算T0中断次数
/*声明T1扫瞄相关声明*/
#definecount_M2250//T1(MODE2)之计量值,0.25ms
#defineTH_M2(256-count_M2)//T1(MODE2)自动载入计量
#defineTL_M2(256-count_M2)//T1(MODE2)计数量
charcount_T1=0;//计算T1中断次数
/*声明七节显示器驱动信号阵列(共阳)*/
charcodeTAB[10]={0xc0,0xf9,0xa4,0xb0,0x99,//数字0-4
0x92,0x82,0xf8,0x80,0x98};//数字5-9
chardisp[2]={0xc0,0xc0};//声明显示区阵列初始显示00
/*声明基本变量*/
charseconds=0;//秒数
charscan=0;//扫瞄信号
//==主程序================================
main()//主程序开始
{IE=0x8a;//10001010,启用TF0、TF1中断(6-4页)
TMOD=0x21;//00100001,T1采mode2、T0采mode1
TH0=TH_M1;TL0=TL_M1;//设置T0计数量高8位元、低8位元
TR0=1;//启动T0(7-7页)
TH1=TH_M2;TL1=TL_M2;//设置T1自动载入值、计数量
TR1=1;//启动T1
LED=1;//关闭LED
while
(1);//无穷回圈,程序停滞
}//主程序结束
//==T0中断子程序-计算并显示秒数==================
voidT0_1s(void)interrupt1//T0中断子程序开始
{TH0=TH_M1;TL0=TL_M1;//设置T0计数量高8位元、低8位元
if(++count_T0==20)//若中断20次,即0.05x20=1秒
{count_T0=0;//重新计次
seconds++;//秒数加1
if(seconds==60)//若超过60秒
{seconds=0;//秒数归0,重新开始
LED=~LED;//切换LED
}//if叙述结束(超过60秒)
}//if叙述结束(中断20次)
disp[1]=TAB[seconds/10];//填入十位数显示区
disp[0]=TAB[seconds%10];//填入个位数显示区
}//T0中断子程序结束
//===T1中断子程序-扫瞄=========================
voidT1_8ms(void)interrupt3//T1中断子程序开始
{if(++count_T1==32)//若中断32次,即0.25mx32=8ms
{count_T1=0;//重新计次
if(++scan==3)scan=1;//若超过十位数,显示个位
SEG=0xff;//关闭7段显示器
SCANP=scan;//输出扫瞄信号
SEG=disp[scan-1];//输出显示信号
}//结束if判断(中断32次)
}//T0中断子程序结束
思考:
若要使用Mode0或Mode2来完成本实验的功能,程序应如何修改?
实例演练7-3-5简易频率发生器实验
BCD拨码开关
0
1
2
3
4
5
6
7
8
9
输出频率
×
100
200
300
400
500
600
700
800
900
BCD拨码开关与频率对应表
频率与定时值对应表
频率
周期
变化时间
定时值
100Hz
10ms
5ms
counts=5000
200Hz
5ms
2.5ms
counts=2500
300Hz
3.3ms
1.67ms
counts=1667
400Hz
2.5ms
1.25ms
counts=1250
500Hz
2ms
1ms
counts=1000
600Hz
1.67ms
0.83ms
counts=833
700Hz
1.43ms
0.714ms
counts=714
800Hz
1.25ms
0.625ms
counts=625
900Hz
1.1ms
0.556ms
counts=556
/*ch07-5-5.c-频率产生器实验,P2之开关控制输出频率*/
//==声明区========================================
#include//定义8051暂存器
#defineSWPP2//声明指拨开关
sbitoutput=P1^1;//声明输出端
sbitbuzzer=P3^7;//声明蜂鸣器
unsignedintcodeTX[10]={0,5000,2500,1667,1250,1000,833,714,625,556};
//不同频率之计量值0,100,200,300,400,500,600,700,800,900Hz
unsignedintcount;//计数值
charnum;
unsignedintTH_M1,TL_M1;
voiddelay40ms(void);//延迟40ms函数
//==主程序=======================
main()//主程序开始
{IE=0x82;//10000010,启用TF0中断(6-4页)
TMOD=0x01;//00000001,T0采mode1(7-3页)
output=1;//输出初值为1
buzzer=1;//输出初值为1
SWP=0xFF;//规划输入埠
while
(1)
{num=(SWP)&0x0F;//读取指拨开关
if(num<10)
count=TX[num];//是否超过范围(针对16进位指拨开关)
TH0=TH_M1=(65536-count)/256;//填入计时量TH
TL0=TL_M1=(65536-count)%256;//填入计时量TL
TR0=1;//启动T0(7-7页)
delay40ms();//延迟40ms函数
}
}
//==========延迟40ms函数===================
voiddelay40ms(void)
{unsignedinti;
for(i=0;i<4800;i++);//延迟8.3*4800=40ms函数
}
//====Timer0中断子程序==================
voidFG_timer(void)interrupt1//Timer0中断子程序开始
{TH0=TH_M1;
TL0=TL_M1;
if(count)//若不是输入0
{output=~output;//输出反相
buzzer=~buzzer;//切换蜂 器状态
}
else
{output=1;//输出高态
buzzer=1;//蜂 器高态
}
}/*结束中断子程序*/
三、小结
本节讲述了MCS-51的定时/计时器的内部构成,工作原理及其应用,重点理解MCS-51的定时/计时器作为定时器和频率发生器的应用。
思考题和习题
思考与习题:
1定时器/计数器有几种工作方式?
区别?
2在实例7-3-2中,主程序没有做任何事情,只是在等待。
若要让主程序进行Port0的单灯左移,应如何修改?
教
学
后
记