AT89S51单片机试验及实践教程之定时计数器T0作定时应用技术(一) |
1. 实验任务 用 AT89S51 单片机的定时 / 计数器 T0 产生一秒的定时时间,作为秒计数时间,当一秒产生时,秒计数加 1 ,秒计数到 60 时,自动从 0 开始。硬件电路如下图所示 2. 电路原理图 图 4.15.1 3. 系统板上硬件连线 • 把“单片机系统”区域中的 P0.0/AD0 - P0.7/AD7 端口用 8 芯排线连接到“四路静态数码显示模块”区域中的任一个 a - h 端口上;要求: P0.0/AD0 对应着 a , P0.1/AD1 对应着 b , …… , P0.7/AD7 对应着 h 。 • 把“单片机系统”区域中的 P2.0/A8 - P2.7/A15 端口用 8 芯排线连接到“四路静态数码显示模块”区域中的任一个 a - h 端口上;要求: P2.0/A8 对应着 a , P2.1/A9 对应着 b , …… , P2.7/A15 对应着 h 。 4. 程序设计内容 AT89S51 单片机的内部 16 位定时 / 计数器是一个可编程定时 / 计数器,它既可以工作在 13 位定时方式,也可以工作在 16 位定时方式和 8 位定时方式。只要通过设置特殊功能寄存器 TMOD ,即可完成。定时 / 计数器何时工作也是通过软件来设定 TCON 特殊功能寄存器来完成的。 现在我们选择 16 位定时工作方式,对于 T0 来说,最大定时也只有 65536us ,即 65.536ms ,无法达到我们所需要的 1 秒的定时,因此,我们必须通过软件来处理这个问题,假设我们取 T0 的最大定时为 50ms ,即要定时 1 秒需要经过 20 次的 50ms 的定时。对于这 20 次我们就可以采用软件的方法来统计了。 因此,我们设定 TMOD = 00000001B ,即 TMOD = 01H 下面我们要给 T0 定时 / 计数器的 TH0 , TL0 装入预置初值,通过下面的公式可以计算出 TH0 =( 2 16 - 50000 ) / 256 TL0 =( 2 16 - 50000 ) MOD 256 当 T0 在工作的时候,我们如何得知 50ms 的定时时间已到,这回我们通过检测 TCON 特殊功能寄存器中的 TF0 标志位,如果 TF0 = 1 表示定时时间已到。 5. 程序框图 图 4.15.2 6. 汇编源程序(查询法) SECOND EQU 30H TCOUNT EQU 31H ORG 00H START: MOV SECOND,#00H MOV TCOUNT,#00H MOV TMOD,#01H MOV TH0,#(65536-50000) / 256 MOV TL0,#(65536-50000) MOD 256 SETB TR0 DISP: MOV A,SECOND MOV B,#10 DIV AB MOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,A MOV A,B MOVC A,@A+DPTR MOV P2,A WAIT: JNB TF0,WAIT CLR TF0 MOV TH0,#(65536-50000) / 256 MOV TL0,#(65536-50000) MOD 256 INC TCOUNT MOV A,TCOUNT CJNE A,#20,NEXT MOV TCOUNT,#00H INC SECOND MOV A,SECOND CJNE A,#60,NEX MOV SECOND,#00H NEX: LJMP DISP NEXT: LJMP WAIT TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH END 7. C语言源程序(查询法) #i nclude <AT89X51.H> unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71,0x00}; unsigned char second; unsigned char tcount; void main(void) { TMOD=0x01; TH0=(65536-50000)/256; TL0=(65536-50000)%256; TR0=1; tcount=0; second=0; P0=dispcode[second/10]; P2=dispcode[second%10]; while(1) { if(TF0==1) { tcount++; if(tcount==20) { tcount=0; second++; if(second==60) { second=0; } P0=dispcode[second/10]; P2=dispcode[second%10]; } TF0=0; TH0=(65536-50000)/256; TL0=(65536-50000)%256; } } } 8. 汇编源程序(中断法) SECOND EQU 30H TCOUNT EQU 31H ORG 00H LJMP START ORG 0BH LJMP INT0X START: MOV SECOND,#00H MOV A,SECOND MOV B,#10 DIV AB MOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,A MOV A,B MOVC A,@A+DPTR MOV P2,A MOV TCOUNT,#00H MOV TMOD,#01H MOV TH0,#(65536-50000) / 256 MOV TL0,#(65536-50000) MOD 256 SETB TR0 SETB ET0 SETB EA SJMP $ INT0X: MOV TH0,#(65536-50000) / 256 MOV TL0,#(65536-50000) MOD 256 INC TCOUNT MOV A,TCOUNT CJNE A,#20,NEXT MOV TCOUNT,#00H INC SECOND MOV A,SECOND CJNE A,#60,NEX MOV SECOND,#00H NEX: MOV A,SECOND MOV B,#10 DIV AB MOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,A MOV A,B MOVC A,@A+DPTR MOV P2,A NEXT: RETI TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH END 9. C语言源程序(中断法) #i nclude <AT89X51.H> unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71,0x00}; unsigned char second; unsigned char tcount; void main(void) { TMOD=0x01; TH0=(65536-50000)/256; TL0=(65536-50000)%256; TR0=1; ET0=1; EA=1; tcount=0; second=0; P0=dispcode[second/10]; P2=dispcode[second%10]; while(1); } void t0(void) interrupt 1 using 0 { tcount++; if(tcount==20) { tcount=0; second++; if(second==60) { second=0; } P0=dispcode[second/10]; P2=dispcode[second%10]; } TH0=(65536-50000)/256; TL0=(65536-50000)%256; } |
发表评论 评论 (0 个评论)