任务三利用硬件定时实现流水灯常用延时方法非精确延时•For(i=0;i100;i++);•i=0;while(i--);精确延时•利用库函数_nop_();//延时一个机器周期(需要includeintrins.h)•利用定时器进行定时定时/计数器(Timer/Counter,简称T/C)80C51有2个16位定时/计数器:•T0、T180C52有3个16位定时/计数器:•T0、T1、T2定时/计数器(Timer/Counter,简称T/C)定时器:来一个机器脉冲计数器的值加1。当计数器值溢出(全1)时回0,定时时间到,中断标志TF置1.1个机器周期=12*1/振荡频率计数器:在机器周期内采样T0(或T1)脉冲的下降沿,来一个下降沿计数器的值加1。当计数器值溢出(全1)时回0,中断标志TF置1.。定时器知识(1)定时器/计数器的内部结构及工作原理单片机内部设有2个16位的可编程的定时器/计数器。简称为定时器0(T0)、定时器1(T1)。可编程是指其功能(如工作模式、定时时间等)均可通过指令来确定或改变。单片机定时器/计数器结构图定时器的工作原理:定时器/计数器是一个加“1”计数器,来一个脉冲即进行加1计数,直至计数器的各位全为“1”,再来一个脉冲,计数器回0(即溢出),且使TF0(定时器0)或TF1(定时器1)置1,表示时间到,计数值乘以脉冲周期就是定时时间。输入的脉冲来源有2个:一个是单片机晶体振荡器经12分频;另一个是T0/T1端的外部输入脉冲。作定时器用时,应采用晶体振荡器经12分频的脉冲。定时器功能两个寄存器:TMOD和TCON4个计数寄存器:TH0,TL0;TH1,TL1方式1:定时时间=(65536-初值)*12/振荡频率初值=65536-定时时间*振荡频率/12例如定时1ms:初值=65536-1s*12*103Hz/12=65536-1000=64536=0xFC18TMOD寄存器GATEC/TM1M0GATEC/TM1M0控制T1控制T0M1M0:00:方式001:方式110:方式211:方式3C/T0:定时器1:计数器GATE:0:软件控制定时器工作1:外部中断控制定时器工作不可位寻址:门控位,控制计数器的启动/停止操作方式。当GATE=0时,外部中断信号不参与控制,计数器只有TR0和TR1位软件控制启动和停止。TR1、TR0为1时,计数器启动开始工作;为0时,计数器停止工作。当GATE=1时,计数器的启动要由外部中断信号和TR0、和TR1共同控制。只有当外部中断引脚为高电平,TR0/TR1置1时才能启动计数器工作。:功能选择位。当=0时选择定时功能,计数脉冲由内部提供,计数周期等于机器周期。当=1时选择为计数功能,计数脉冲为外部引脚T0、T1引入的外部脉冲信号。TC/:T0和T1工作方式控制位。定时/计数器的工作方式有M1M0两位状态决定,这两位有四种编码方式,对应于四种工作方式。四种方式定义如表所示:M1M0方式说明00方式0TL的低5位和TH的8位构成13位计数器01方式1TL的8位和TH的8位构成16位的计数器10方式2具有自动重装功能的8位计数器11方式3T0分成两个独立的计数器,T1可工作在方式0~方式2TCONTF1TR1TF0TR0IE1IP1IE0IP0可位寻址,也可字节寻址M1M000:方式0,13位计数寄存器01:方式1,16位计数寄存器,用于定时和计数10:方式2,自动重装载8位计数寄存器,用于波特率发生器11:方式3,2个8位计数寄存器定时器使用步骤1.设置TMOD,使之工作在需求状态;•TMOD=0x01;或TMOD=0x10;2.设置计数寄存器初值,精确设定好定时时间;•TH0=0xff;TL0=0x00;或TH1=0xff;TL1=0x00;3.设置TCON,打开TR使定时器工作;•TR0=1;或TR1=1;4.检测定时器溢出(TF==1),溢出时:复位TF,计数寄存器赋初值,定时到触发的动作。if(1==TF0){TH0=0xff;TL0=0x00;TF0=0;P1_0=~P1_0;}或if(1==TF1){TH1=0xfc;TL1=0x18;TF1=0;P1_0=~P1_0;}定时1ms初值=65536-1000=0xFC18#includereg52.hsbitP1_0=P1^0;voidmain(){TMOD=0x01;TH0=0xfc;TL0=0x18;TR0=1;//此位可位操作while(1){if(1==TF0){TH0=0xfc;TL0=0x18;TF0=0;//此位可位操作P1_0=~P1_0;//此位可位操作}}}定时时间=(65536-初值)*12/振荡频率≤65536μs#includereg52.hsbitP1_0=P1^0;voidmain(){TMOD=0x01;TH0=0;TL0=0;TR0=1;//此位可位操作while(1){if(1==TF0){//TH0=0;TL0=0;TF0=0;//此位可位操作P1_0=~P1_0;//此位可位操作}}}定时1s#includereg52.hsbitP1_0=P1^0;voidmain(){unsignedintcounter;TMOD=0x01;TH0=0xb1;TL0=0xe0;TR0=1;//此位可位操作while(1){if(1==TF0){TH0=0xb1;TL0=0xe0;TF0=0;counter++;}if(50==counter){counter=0;P1_0=~P1_0;}}}=50*20ms20ms初值=45536=0xB1E0复习定时器定时功能的使用•TMOD:选择T0还是T1•TCON:选择方式1•设置初值放置于TH0,TL0或TH1,TL1中方式1:定时时间=(65536-初值)*机器周期初值=65536-定时时间/机器周期时间间隔0.5s=10*50ms的流水灯;#includereg52.hvoidmain(){unsignedinti,j,value,dec;TMOD=0x01;TH0=0x3c;TL0=0xb0;TR0=1;//此位可位操作while(1){value=254;dec=1;for(i=0;i8;i++){P1=value;for(j=0;j10;j++)//10次*50ms/次{while(TF0!=1);TH0=0x3c;TL0=0xb0;TF0=0;}value=value-dec;dec=dec*2;}}}50ms初值=15536=0x3CB0书上程序操作练习1请用定时器0实现:•时间间隔50ms的流水灯;•时间间隔1s的流水灯;操作练习2请用硬件定时器实现:任选三个LED灯,分别作为红、黄、绿交通灯,实现绿灯亮1s,然后黄灯快闪3次,再红灯亮2s,黄灯快闪3次,绿灯亮1s,……#includereg52.hvoidmain(){unsignedinti,value,dec;TMOD=0x01;TH0=0x3c;TL0=0xb0;TR0=1;//此位可位操作while(1){value=254;dec=1;for(i=0;i8;i++){while(TF0!=1);TH0=0x3c;TL0=0xb0;TF0=0;P1=value;value=value-dec;dec=dec*2;}}}时间间隔50ms的流水灯;50ms初值=15536=0x3CB0书上方法时间间隔1s=20*50ms的流水灯;#includereg52.hvoidmain(){unsignedinti,j,value,dec;TMOD=0x01;TH0=0x3c;TL0=0xb0;TR0=1;//此位可位操作while(1){value=254;dec=1;for(i=0;i8;i++){for(j=0;j20;j++)//20次*50ms/次{while(TF0!=1);TH0=0x3c;TL0=0xb0;TF0=0;}P1=value;value=value-dec;dec=dec*2;}}}50ms初值=15536=0x3CB0书上方法时间间隔1s的双向流水灯;#includereg52.hvoidmain(){unsignedchari,j,value,dec;TMOD=0x01;TH0=0x3c;TL0=0xb0;TR0=1;//此位可位操作while(1){value=254;dec=1;for(i=0;i14;i++){for(j=0;j20;j++)//20次*50ms/次{while(TF0!=1);TH0=0x3c;TL0=0xb0;TF0=0;}P1=value;if(i7){value=value-dec;dec=dec*2;}else{dec=dec/2;value=value+dec;}}}}书上方法#includereg52.hvoidmain(){unsignedinti,value;TMOD=0x01;TH0=0x3c;TL0=0xb0;TR0=1;//此位可位操作while(1){value=0x01;for(i=0;i8;i++){while(TF0!=1);TH0=0x3c;TL0=0xb0;TF0=0;P1=~value;value=value1;}}}时间间隔50ms的流水灯;50ms初值=15536=0x3CB0方法2#includereg52.hvoidmain(){unsignedinti,j,value;TMOD=0x01;TH0=0x3c;TL0=0xb0;TR0=1;//此位可位操作while(1){value=0x01;for(i=0;i8;i++){for(j=0;j20;j++)//20次*50ms/次{while(TF0!=1);TH0=0x3c;TL0=0xb0;TF0=0;}P1=~value;value=value1;}}}时间间隔1s=20*50ms的流水灯;50ms初值=15536=0x3CB0方法2#includereg52.hvoidmain(){unsignedinti,j,value;TMOD=0x01;TH0=0x3c;TL0=0xb0;TR0=1;//此位可位操作while(1){value=0x01;for(i=0;i14;i++){for(j=0;j20;j++){while(TF0!=1);TH0=0x3c;TL0=0xb0;TF0=0;}P1=~value;if(i7)value=value1;elsevalue=value1;}}}时间间隔1s的双向流水灯;50ms初值=15536=0x3CB0方法2#includereg52.hvoidmain(){unsignedintvalue=0x01;TMOD=0x01;TH0=0x3c;TL0=0xb0;TR0=1;//此位可位操作while(1){if(1==TF0){TH0=0x3c;TL0=0xb0;TF0=0;P1=~value;value=value1;if(value==256)value=0x01;}}}时间间隔50ms的流水灯;50ms初值=15536=0x3CB0方法3#includereg52.hvoidmain(){unsignedintcounter,value=0x01;TMOD=0x01;TH0=0x3c;TL0=0xb0;TR0=1;//此位可位操作while(1){if(1==TF0){TH0=0x3