8STC15F2K60S2单片机的定时器计数器例题.docx
《8STC15F2K60S2单片机的定时器计数器例题.docx》由会员分享,可在线阅读,更多相关《8STC15F2K60S2单片机的定时器计数器例题.docx(21页珍藏版)》请在冰点文库上搜索。
8STC15F2K60S2单片机的定时器计数器例题
第8章STC15F2K60S2单片机的定时/计数器
例题
例8.1用T1方式0实现定时,在P1.0引脚输出周期为10mS的方波。
解:
根据题意,采用T1方式0进行定时,因此,(TMOD)=00H。
因为方波周期是10mS,因此T1的定时时间应为5mS,每5mS时间到就对P1.0取反,就可实现在P1.0引脚输出周期为10mS的方波。
系统采用12M晶振,分频系数为12,即定时脉钟周期为1μS,则T1的初值为:
X=M-计数值=65536-5000==60536=EC78H
即:
TH1=ECH,TL1=78H。
(1)查询方式实现:
ORG0000H
MOVTMOD,#00H;设T1为方式0定时模式
MOVTH1,#0ECH;置5mS定时的初值
MOVTL1,#78H
SETBTR1;启动T1
Check_TF1:
JBCTF1,Timer1_Overflow;查询计数溢出
SJMPCheck_TF1;未到5mS继续计数
Timer1_Overflow:
CPLP1.0;对P1.0取反输出
SJMPCheck_TF1;未到1s继续循环
END
(2)中断方式实现:
ORG0000H
LJMPMAIN;上电复位后,转MAIN
ORG001BH
LJMPTimer1_ISR;T1中断响应后,转Timer1_ISR
ORG0100H
MAIN:
MOVTMOD,#00H;设T1为方式0定时模式
MOVTH1,#0ECH;置5mS定时的初值
MOVTL1,#78H
SETBET1
SETBEA;开放中断
SETBTR1;启动T1
SJMP$;原地踏步,模拟主程序
Timer1_ISR:
CPLP1.0;对P1.0取反输出
RETI;中断返回,回到主程序执行SJMP$
END
例8.2用定时/计数器扩展外部中断。
解:
当实际应用系统中有两个以上的外部中断源,而片内定时/计数器未使用时,可利用定时/计数器来扩展外部中断源。
扩展方法是,将定时/计数器设置为计数器方式,计数初值设定为满程,将待扩展的外部中断源接到定时/计数器的外部计数引脚。
从该引脚输入一个下降沿信号,计数器加1后便产生定时/计数器溢出中断。
因此,可把定时/计数器的外部计数引脚作为扩展中断源的中断输入端。
设采用T1实现,采用工作方2,即TH1、TL1的初值均为FFH,T1中断开放,即T1引脚(P3.5)为扩展外部中断的中断请求信号输入端,触发方式为下降沿触发。
其初始化程序(中断方式)如下:
ORG0000H
LJMPMAIN;上电复位后,转MAIN
ORG001BH
LJMPEX_ISR;T1中断响应后,转EX_ISR
ORG0100H
MAIN:
MOVTMOD,#60H;设T1为方式1计模式
MOVTH1,#0FFH
MOVTL1,#0FFH
SETBET1
SETBEA;开放中断
SETBTR1;启动T1
……;主程序其它指令
……
EX_ISR:
……;扩展外部中断的中断服务程序
……
RETI
END
思考:
试将例8.2的功能用T0或T1的方式0实现。
例8.3使信号灯循环点亮,首先按从左至右轮流点亮,再按从右至左轮流点亮,每个信号灯点亮的时间间隔为1秒。
要求用单片机定时/计数器定时实现。
解:
硬件电路比较简单,采用P1口输出驱动电平,低电平有效。
电路如图8.7所示。
图8.7流水灯显示电路
系统采用12M晶振,分频系数为12,即定时时钟周期为1μS;采用定时器T1方式0定时50mS,用R3做50ms计数单元,20次50mS定时即为1S,故R3的初始值为20。
汇编语言参考程序如下:
1)查询方式实现
ORG0000H
LOOP:
MOVR2,#07H;设置左移的次数
MOVA,#0FEH;设置信号灯的显示(左移)的起始状态值
Left_Shift:
MOVP1,A;送显示控制信号
LCALLDELAY;利用软件与定时器,实现1s定时
RLA;改变信号灯显示状态,左移
DJNZR2,Left_Shift;判断左移流程是否结束,若结束,转入右移控制
MOVA,#7FH;设置信号灯的显示(右移)的起始状态值,可省略
MOVR2,#07H;设置右移的次数
Right_Shift:
MOP1,A;送显示控制信号
RRA;改变信号灯显示状态,右移
LCALLDELAY;利用软件与定时器,实现1s定时
DJNZR2,Right_Shift;判断左移流程是否结束,若结束,又重新开始
SJMPLOOP
DELAY:
MOVR3,#20;置50ms计数循环初值
MOVTMOD,#00H;设定时器1为方式1
MOVTH1,#3CH;置定时器初值
MOVTL1,#0B0H
SETBTR1;启动T1
Check_TF1:
JBCTF1,Timer1_Overflow;查询计数溢出
SJMPCheck_TF1;未到50ms继续计数
Timer1_Overflow:
DJNZR3,Check_TF1;未到1s继续循环
CLRTR1;关闭T1
RET;返回主程序
END
2)中断方式实现
ORG0000H
LJMPMAIN
ORG001BH
LJMPTimer1_ISR
MAIN:
MOVR3,#20;置50ms计数循环初值
MOVTMOD,#00H;设定时器1为方式1
MOVTH1,#3CH;置50ms定时器初值
MOVTL1,#0B0H
MOVR2,#07H;设置左移的次数
MOVP1,#0FEH;设置信号灯的显示(左移)的起始状态值
MOVA,#0FEH;设置信号灯的显示(左移)的起始状态值
CLR00H;设置左、右移标志位,为0左移,为1右移
SETBET1
SETBEA
SETPTR1;启动T1定时器
SJMP$;原地踏步,模拟主程序
Timer1_ISR:
DJNZR3,Exit_Timer1_ISR;定时时间到,执行移位,否则中断结束
MOVR3,#20
JB00H,Right_Shift;判断左、右移控制
RLA;左移控制
MOVP1,A
DJNZR2,Exit_Timer1_ISR;判断左移流程是否结束,若结束,转入右移控制
SETB00H;置位左、右移控制标志
MOVR2,#07H;重新设置移位次数
SJMPExit_Timer1_ISR
Right_Shift:
RRA;右移控制
MOVP1,A
DJNZR2,Exit_Timer1_ISR;判断左移流程是否结束,若结束,转入右移控制
CLR00H;清0左、右移控制标志
MOVR2,#07H;重新设置移位次数
Exit_Timer1_ISR:
RETI
END
C51参考程序如下:
1)查询方式实现
#include//包含52标准文件头
#include//包含循环左移、右移子函数
#defineucharunsignedchar
#defineuintunsignedint
ucharLED=0xfe;
/*---------------------利用T1实现定时的子函数------------------*/
voidDELAY(void)//延时函数1S
{
uinti=0;
TMOD=0x00;//T1工作模式1
TH1=0x3c;
TL1=0xb0;
TR1=1;
while(i<20)
{
if(TF1==1)//查询T1溢出标志
{
TF1=0;
i++;
}
}
}
/*---------------------循环左移子函数------------------*/
voidLeft_Shift(void)
{
P1=LED;
DELAY();//延时一秒
LED=_crol_(LED,1);//循环左移一位
}
/*---------------------循环右移子函数------------------*/
voidRight_Shift(void)
{
LED=_cror_(LED,1);//循环右移一位
P1=LED;
DELAY();//延时一秒
}
/*---------------------主函数------------------*/
voidmain(void)
{
ucharj;
while
(1)
{
for(j=0;j<7;j++)
{
Left_Shif();
}
for(j=0;j<7;j++)
{
Right_Shift();
}
}
}
2)中断方式实现
#include//包含52标准文件头
#include//包含循环左移、右移子函数
#defineucharunsignedchar
#defineuintunsignedchar
/*---------------------定义全局变量------------------*/
ucharLED=0xfe;
uchari=0;
uchart=0;
/*---------------------T1初始化子函数------------------*/
voidTimer1_init(void)
{
TMOD=0x00;//T1工作模式1
TH1=0x3c;
TL1=0xb0;
ET1=1;
EA=1;
TR1=1;
}
/*---------------------LED循环显示子函数------------------*/
voidShift(void)
{
P1=LED;
t++;
if(t<=7)
{
LED=_crol_(LED,1);//循环左移一位
}
elseif(t<15)
{
LED=_cror_(LED,1);//循环右移一位
}
else{t=0;}
}
/*--------------------T1中断服务子函数------------------*/
voidTimer1_int(void)interrupt3using1//定时T1中断服务程序
{
i++;
f(i==20)
{
i=0;
Shift();
}
}
/*--------------------主函数------------------*/
voidmain(void)//主函数
{
Timer1_init();//T1初始化
while
(1);
}
例8.4连续输入5个单次脉冲使单片机控制的LED灯状态翻转一次。
要求用单片机定时/计数器计数功能实现实现。
解:
采用T1实现,硬件如图8.8所示。
图8.8信号灯的计数控制
采用T1的方式2的计数方式,初始值设置为FBH,当输入5个脉冲时,即溢出标志TF1,通过查询TF1或中断方式判断TF1标志,进而对P1.0LED灯进行控制。
汇编语言参考程序如下:
1)查询方式实现
ORG0000H
MOVTMOD,#60H;设定定时器1模式2,计数功能
MOVTH1,#0FBH
MOVTL1,#0FBH;设置计数器初值(256-5)
SETBTR1;启动计数
Check_TF1:
JBCTF1,Timer1_Overflow;查询是否计数溢出
AJMPCheck_TF1
Timer1_Overflow:
CPLP1.0;当统计5个脉冲,LED灯状态翻转
AJMPCheck_TF1
END
2)中断方式实现
ORG0000H
AJMPMAIN
ORG001BH
AJMPTimer1_ISR
MAIN:
MOVTMOD,#60H;设定定时器1模式2,计数功能
MOVTH1,#0FBH
MOVTL1,#0FBH;设置计数器初值(256-5)
SETBET1
SETBEA
SETBTR1;启动计数
SJMP$
Timer1_ISR:
CPLP1.0;当统计5个脉冲,LED灯状态翻转
RETI
END
C51参考程序如下:
1)查询方式实现
#include
sbitled=P1^0;
voidtimer_initial(void)
{
TMOD=0x60;//设定定时器1模式2,计数功能
TH1=0xfb;//5个脉冲以后溢出
TL1=0xfb;
TR1=1;//开始计数器
}
voidmain(void)
{
timer_initial();
while
(1)
{
while(TF1==0);
TF1=0;
Led=~led;//不断查询是否溢出,没有溢出,就等待溢出了;溢出了,
//清空溢出标志,led取反
}
}
2)中断方式实现
#include
#defineucharunsignedchar
#defineuintunsignedchar
sbitLED=P1^0;
/*---------------------T1初始化子函数------------------*/
voidTimer1_init(void)
{
TMOD=0x60;//1设定定时器1模式2,计数功能
TH1=0xfb;//设置计数器初值(计满溢出值-5)
TL1=0xfb;
ET1=1;
EA=1;
TR1=1;//启动计数
}
/*---------------------T1中断服务子函数------------------*/
voidTimer1_int(void)interrupt3using1//定时计数T1中断服务程序
{
LED=~LED;
}
/*---------------------主函数------------------*/
voidmain(void)//主函数
{
Timer1_init();//定时T1初始化
while
(1);
}
思考:
用方式0实现。
例8.5利用单片机定时器/计数器设计一个秒表,由P1口连接LED灯,采用BCD码显示,发光二极管亮表示1,暗则表示0,计满100s后从头开始,依次循环。
利用一只按键控制秒表的启、停。
利用复位键,返回初始工作状态。
解:
选用P1口作输出端,控制8只发光二极管显示,设发光二极管的驱动是低电平亮,高电平灭。
P3.5接秒表的启、停按键。
采用T0的方式0作定时器,12M晶振,分频系数为12,即定时时钟周期为1μS
汇编语言参考程序如下:
ORG0000H
LJMPMAIN
ORG000BH
LJMPTimer0_ISQ
MAIN:
MOVTMOD,#00H;T0方式1定时
MOVTH0,#3CH;重新置T050ms定时的初值
MOVTL0,#0B0H
SETBET0
SETBEA
MOVR3,#14H;置50ms计数循环初值(1s/50ms)
MOVA,#00H;计数显示初始化
CPLA;满足低电平驱动要求
MOVP1,A
CPLA;恢复秒表计数值
Check_Start_Button:
JNBP3.5,Start
CLRTR0
SJMPCheck_Start_Button
Start:
SETBTR0
SJMPCheck_Start_Button
Timer0_ISQ:
DJNZR3,Exit_Timer0_ISQ
ADDA,#01;秒表加1
DAA;十进制调整
CPLA;满足低电平驱动要求
MOVP1,A
CPLA;恢复秒表计数值
MOVR3,#14H
Exit_Timer0_ISQ:
RETI
END
C51参考程序如下:
#include//包含52标准文件头
#defineucharunsignedchar
#defineuintunsignedchar
uchardat=0;//定义BCD计数单元(范围:
0~99)
uchari;//定义循环变量
sbitkey=P3^5;//定义按键
/*----------------------------T0初始化子函数--------------------------------*/
voidTimer0_init(void)
{
TMOD=0X00;//T0方式1
TH0=(65535-50000)/256;//赋初始值,50ms
TL0=(65535-50000)%256;//赋初始值
ET0=1;
EA=1;
}
/*----------------------------T0中断服务子函数--------------------------------*/
voidTimer0_int(void)interrupt1using1//T0中断服务子程序
{
i++;
if(i==20)//i=20时,计时1S
{
i=0;
dat++;
f(dat==100)//计时到100S时,又从0开始
{
dat=0;
}
}
}
/*----------------------------启动子函数--------------------------------*/
voidStart(void)//启动定时函数
{
if(key==0)//判断按键按下
{
TR0=1;//开始计时
}
else
{
TR0=0;
}
}
/*---------------------------BCD码转换子函数--------------------------------*/
ucharBCD(ucharBCDat)//BCD转换
{
ucharx;
x=(BCDat/10)*10+BCDat%10;
return(x);
}
/*--------------------------主函数--------------------------------*/
voidmain(void)
{
Timer0_init();//T0初始化
while
(1)
{
Start();//启动定时
P1=~(BCD(dat));//送LED显示
}
}
例8.6编程在P3.0、P3.5、P3.4引脚上分别输出115.2KHZ、51.2KHZ、38.4KHZ的时钟信号。
解:
设系统时钟频率为12KHZ,T0、T1工作在方式2定时状态,且工作在无分频模式,即各定时器的定时脉冲频率等于时钟频率,即(T0x12)=(T1x12)=(T2x12)=1;各根据前面可编程时钟输出频率的计算公式,计算各定时器的定时初始值:
(T2H)=FFH,(T2L)=CCH,(TH0)=(TL0)=8BH,(TH1)=(TL1)=64H
(1)汇编语言参考程序
T2HEQUD6H
T2LEQUD7H
AUXREQU8EH
INT_CLKOEQU8FH
ORG0000H
MOVTMOD,#22H;T0、T1工作方式2定时状态
ORLAUXR,#80H;T0工作在无分频模式
ORLAUXR,#40H;T1工作在无分频模式
ORLAUXR,#04H;T2工作在无分频模式
MOVT2H,#0FFH;设置BRT定时器的初始值
MOVT2L,#0CCH
MOVTH0,#139;设置T0定时器的初始值
MOVTL0,#139
MOVTH1,#100;设置T1定时器的初始值
MOVTL1,#100
ORLINT_CLKO,#07H;允许CLKOUT0、CLKOUT1、CLKOUT2时钟输出
SETBTR0;启动T0
SETBTR1;启动T1
ORLAUXR,#10H;启动T2
SJMP$
(2)C51参考程序
#include
sfrINT_CLKO=0x8F;
sfrAUXR=0x8E;
sfrT2H=0XD6;
sfrT2L=0Xd7;
main()
{
TMOD=0x22;
AUXR=(AUXR|0x80);//T0工作在无分频模式
AUXR=(AUXR|0x40);//T1工作在无分频模式
AUXR=(AUXR|0x04);//T2工作在无分频模式
T2H=0xFF;//给T2、T0、T1定时器设置初值
T2L=0xCC;
TH0=139;
TL0=139;
TH1=100;
TL1=100;
INT_CLKO=(WAKE_CLKO|0x07);//允许T0、T1、T2输出时钟信号
TR0=1;//启动T0
TR1=1;//启动T1
AUXR=(AUXR|0x10);//启动T2
while
(1);//无限循环
}