51单片机内部拥有两个定时/计数器 T0和T1
两种工作模式:
(1)计数器工作模式
(2)定时器工作模式
定时器/计数器的结构
TMOD:选择定时器/计数器T0、T1的工作模式和工作方式。
TCON:控制T0、T1的启动和停止计数,同时包含了T0、T1的状态。
单片机复位时,两个寄存器的所有位都被清0。
4种工作方式(方式0-方式3):
M1 M0 工 作 方 式
0 0 方式0,13位定时器/计数器。
0 1 方式1,16位定时器/计数器。
1 0 方式2,8位常数自动重新装载
1 1 方式3,仅适用于T0,T0分成两个8位计数器,T1停止计数。
对于定时器/计数器的介绍我就不做过多介绍,需要详细了解的小伙伴可以自己查询一下相关书籍资料。
今天为大家演示的是利用定时器/计数器T0实现计时60秒的秒表,程序的功能是单片机上电后,系统自动从0开始显示到59,然后在从新从开始,一直循环显示。
#include#define uint unsigned int #define uchar unsigned char sbit we1=P2^6; sbit we2=P2^7; sbit le=P2^0; unsigned char code tabl[]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71}; uchar num,num1 ,shi,ge; void delayms(uint xms){//延时函数 uint i,j; for(i=xms;i>0;i--) for(j=110;j>0;j--) ; } void display(){//显示函数 we1=0;//表示左端第一个数码管公共端接低电平 le=1;//打开锁存器 P0=tabl[shi];//显示十位上的数字 delayms(5);//延时5ms le=0;关闭锁存器 we1=1; P0=0xff;//消影 we2=0; le=1; P0=tabl[ge];//显示个位上的数字 delayms(5); le=0; we2=1; P0=0xff; } void main(){ TMOD=0x01;//设置T0的工作方式为1 TH0=(65536-50000)/256;//初始化 TL0=(65536-50000)%256; EA=1;//开总中断 ET0=1;//开T0中断 TR0=1;//启动中断 while(1){ display(); } } void ex0_time()interrupt 1//中断函数 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; num++;//记数满20表示时间到达1S if(num==20){ num=0; num1++;//用来统计时间60s if(num1==60){ num1=0; } shi=num1/10;//获取数码管十位上的显示数字下标值,用于在显示函数中对十位数字进行显示 ge=num1%10;//获取数码管个位上的显示数字下标值,用于在显示函数中对个位数字进行显示 } }
Protues仿真结果截图:



