×
单片机 > 单片机程序设计 > 详情

单片机练习 - 计时器

发布时间:2020-06-06 发布时间:
|

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

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


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


计时器
  1#include 
  2#include 
  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[] = {0, 0, 0, 0, 0, 0};//分秒毫秒
 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[]={0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd, 
 17    0x87, 0xff, 0xef};
 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  26    }
 27}
 28
 29void display() 
 30{
 31    unsigned char count;
 32    for(count = 0; 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  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)
147                        {
148                            datas[0] = 0;
149                            P1 <<= 1;
150                        }
151                    }
152                }
153            }
154        }
155    }
156}


效果图:
6小时23分44.98秒


0时0分30.73秒





『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
51单片机CO2检测显示程序解析