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<reg51.h>#define uint unsigned int#define uchar unsigned charsbit 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);//延时5msle=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的工作方式为1TH0=(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表示时间到达1Sif(num==20){num=0;num1++;//用来统计时间60sif(num1==60){num1=0;}shi=num1/10;//获取数码管十位上的显示数字下标值,用于在显示函数中对十位数字进行显示ge=num1%10;//获取数码管个位上的显示数字下标值,用于在显示函数中对个位数字进行显示}}
Protues仿真结果截图: