单片机练习 - 计时器

2019-04-15 15:54发布

利用单片机的定时/计数器(单片机练习 - 定时器 ), 这天写了一个计时器, 精确到小数0.01秒, 拥有一个开始/暂停键, 一个清零键...

6位数码管与单片机的连接电路图


按键S2, S3与单片机的连接电路图: 其中S2与P3.4连, S3与P3.5连接...


计时器
  1#include <reg52.H>
  2#include <intrins.H>
  3//秒表, 精确到小数1%秒, 即10ms, 一个开始/暂停键, 一个停止清零键
  4//准确定时采用定时器1, 工作方式1
  5
  6sbit wela = P2^7;  //数码管位选
  7sbit dula = P2^6;  //数码管段选
  8sbit ds = P2^2;
  9unsigned char th, tl;
 10unsigned char datas[] = {000000};//分秒毫秒
 11
 12//0-F数码管的编码(共阴极)
 13unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,
 14    0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}
;
 15//0-9数码管的编码(共阴极), 带小数点
 16unsigned char code tableWidthDot[]={0xbf0x860xdb0xcf0xe60xed0xfd
 17    0x870xff0xef}
;
 18
 19//延时函数, 对于11.0592MHz时钟, 例i=5,则大概延时5ms.
 20void delay(unsigned int i)
 21{
 22    unsigned int j;
 23    while(i--)
 24    {
 25        for(j = 0; j < 125; j++);
 26    }

 27}

 28
 29void display() 
 30{
 31    unsigned char count;
 32    for(count = 0; count < 6; count++)
 33    {
 34        //关位选, 去除对上一位的影响
 35        P0 = 0xff
 36        wela = 1//打开锁存, 给它一个下降沿量
 37        wela = 0;
 38        //段选
 39        if(count == 1 || count == 3)
 40        {
 41            P0 = tableWidthDot[datas[count]]; //显示带小数点数字, 作为分秒, 秒与毫秒的分隔
 42        }

 43        else
 44        {
 45            P0 = table[datas[count]];  //显示数字
 46        }

 47        dula = 1;  //打开锁存, 给它一个下降沿量
 48        dula = 0;
 49
 50        //位选 
 51        P0 = _crol_(0xfe, count); //选择第(count + 1) 个数码管
 52        wela = 1//打开锁存, 给它一个下降沿量
 53        wela = 0;
 54        delay(1); 
 55    }

 56}

 57
 58sbit S2 = P3^4;  //键S2, 作开始/暂停 
 59sbit S3 = P3^5;    //键S3, 清零
 60sbit S4 = P3^6;    //键S4
 61sbit S5 = P3^7;    //键S5
 62unsigned char tmp;  
 63
 64//等待键被释放 
 65void waitFreeKey()
 66{
 67    while(!S2 || !S3)
 68    {
 69        display(); // 等待期间要显示
 70    }

 71}

 72
 73//检测是否有键按下, 并执行相应功能
 74void checkKey()
 75{
 76    if(!S2)
 77    {
 78        delay(7);  //延时大约10ms, 去抖动
 79        if(!S2)  //开始/暂停键按下
 80        {
 81            TR1 = ~TR1;
 82        }

 83    }

 84
 85    if(!S3)
 86    {
 87        delay(14);  //延时大约10ms, 去抖动
 88        if(!S3)  //清零键按下
 89        {
 90            TR1 = 0;
 91            TH1 = th;
 92            TL1 = tl;
 93            for(tmp = 0; tmp < 6; tmp++)
 94            {
 95                datas[tmp] = 0;
 96            }

 97        }

 98    }

 99    //等待键被释放 
100    waitFreeKey();
101}

102
103void main()
104{
105    th = (65536 - 10000/1.085/ 256;  //定时10ms
106    tl = (65536 - 10000/1.085- th * 256;
107    TH1 = th;
108    TL1 = tl;
109    EA = 1;  //开中断
110    ET1 = 1//允许定时器1中断请求
111    TMOD = 0x10;  //定时器工作方式1
112    while(1)
113    {
114        checkKey();  //检测是否就键按下
115        display();  //显示计时值
116    }

117}

118
119//定时器1中断响应函数
120void time1() interrupt 3
121{
122    TH1 = th;  //重置计数值
123    TL1 = tl;
124
125    datas[5]++;  //0.01秒
126    if(datas[5== 10)
127    {
128        datas[5= 0;
129        datas[4]++;   //0.1秒
130        if(datas[4== 10)
131        {
132            datas[4= 0;
133            datas[3]++;  //
134            if(datas[3== 10)
135            {
136                datas[3= 0;
137                datas[2]++;   //10秒
138                if(datas[2== 6)
139                {
140                    datas[2= 0;
141                    datas[1]++;  //
142                    if(datas[1== 10)
143                    {
144                        datas[1= 0;
145                        datas[0]++;  //10分
146                        if(datas[0== 6)
14