单片机综合练习 - 多功能时钟

结合前几天来写过的文章, 今天总算写了一个功能较多的应用 - 多功能时钟, 集时钟, 秒表, 温度计一体.

基础文章:
1. 单片机练习 - DS18B20温度转换与显示
2. 用C51编写单片机延时函数
3. 单片机练习 - 定时器
4. 单片机练习 - 计时器

实验板: TX-1B实验板

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


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


DS18B20与单片机连接电路图:


具体按键功能分配请看源代码注释部分:

ContractedBlock.gif ExpandedBlockStart.gif 多功能时钟
  1None.gif//多功能时钟, 精确到小数0.01秒, 即10ms
  2None.gif//功能: 时钟, 秒表, 温度计
  3None.gif
  4ExpandedBlockStart.gifContractedBlock.gif/**//*
  5InBlock.gifS5键为功能选择键, 上电默认使用时钟功能
  6InBlock.gif功能顺序为: 时钟, 温度计, 秒表
  7InBlock.gif
  8InBlock.gifmode = 1. 时钟(每次掉电后都要重新设置时间)
  9InBlock.gif1)当选中时钟功能时, 具体按键功能如下:
 10InBlock.gif
 11InBlock.gif2)可设置时分秒, 时利用发光二极管显示, 分秒用数码管显示
 12InBlock.gif
 13InBlock.gif3)时钟: 采用定时器0计时, 工作方式1
 14InBlock.gif
 15InBlock.gifmode = 2. 时钟设置模式
 16InBlock.gif当选中时钟设置模式
 17InBlock.gifS2为位选, S3为增加选中位的值
 18InBlock.gifS4确定更改, S5放弃更改, 进入秒表模式
 19InBlock.gif
 20InBlock.gifmode = 3. 秒表
 21InBlock.gif1)当选中秒表功能时, 具体按键功能如下:
 22InBlock.gifS2为开始/暂停, S3为清零
 23InBlock.gif
 24InBlock.gif2)采用定时器1计时, 工作方式1
 25InBlock.gif
 26InBlock.gifmode = 4. 温度计
 27InBlock.gif1)利用DS18B20检测环境温度;
 28InBlock.gif2)最小温度值为0.01℃, 可表示温度范围: -55℃~+125℃
 29InBlock.gif
 30ExpandedBlockEnd.gif*/

 31None.gif
 32None.gif#include <reg52.H>
 33None.gif#include <intrins.H>
 34None.gif#include <math.h>
 35None.gif
 36None.gif//0-F数码管的编码(共阴极)
 37ExpandedBlockStart.gifContractedBlock.gifunsigned char code table[]=dot.gif{0x3f,0x06,0x5b,0x4f,0x66,
 38ExpandedBlockEnd.gif    0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}
;
 39None.gif//0-9数码管的编码(共阴极), 带小数点
 40ExpandedBlockStart.gifContractedBlock.gifunsigned char code tableWidthDot[]=dot.gif{0xbf0x860xdb0xcf0xe60xed0xfd
 41ExpandedBlockEnd.gif    0x870xff0xef}
;
 42None.gif
 43None.gifsbit wela = P2^7;  //数码管位选
 44None.gifsbit dula = P2^6;  //数码管段选
 45None.gifsbit ds = P2^2;
 46None.gifunsigned char th, tl, mode = 1//mode存放功能模式, 默认在模式1 时钟
 47None.gifunsigned char clockPosition = 0;  //时钟设置模式下, 光标所在的位置; 默认在0
 48None.gifunsigned char clockTmp = 0//用于时钟模式下临时计数
 49None.gifbit clockTmpBit = 0//用于时钟模式下临时标志位
 50None.gif
 51None.gif//秒4字节, 分2字节, 时1字节
 52ExpandedBlockStart.gifContractedBlock.gifunsigned char datas[] = dot.gif{0000000};//保存计时器数据
 53ExpandedBlockStart.gifContractedBlock.gifunsigned char clockDatas[] = dot.gif{0000000};//保存时钟数据
 54None.gifunsigned char * values = clockDatas;  //根据mode选择适当的数据数组指针
 55None.gifint tempValue; //存放温度值
 56None.gifunsigned char tempCount = 0//用于记录显示了多少次温度值, 用于定时
 57None.gif
 58None.gifsbit S2 = P3^4;  //键S2, 作开始/暂停 
 59None.gifsbit S3 = P3^5;     //键S3, 清零
 60None.gifsbit S4 = P3^6;     //键S4
 61None.gifsbit S5 = P3^7;     //键S5
 62ExpandedBlockStart.gifContractedBlock.gifunsigned char tmpDatas[] = dot.gif{0000000};  //存放临时设置值
 63None.gifunsigned char icount;
 64None.gif
 65None.gif//延时函数, 对于11.0592MHz时钟, 例i=5,则大概延时5ms.
 66None.gifvoid delay(unsigned int i)
 67ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 68InBlock.gif    unsigned int j;
 69InBlock.gif    while(i--)
 70ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 71InBlock.gif        for(j = 0; j < 125; j++);
 72ExpandedSubBlockEnd.gif    }

 73ExpandedBlockEnd.gif}

 74None.gif
 75ExpandedBlockStart.gifContractedBlock.gif/**//***********************温度计模式******************************/
 76None.gif
 77None.gif//初始化DS18B20
 78None.gif//让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动
 79None.gifvoid dsInit()
 80ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 81InBlock.gif    //对于11.0592MHz时钟, unsigned int型的i, 作一个i++操作的时间大于为8us
 82InBlock.gif    unsigned int i;  
 83InBlock.gif    ds = 0;
 84InBlock.gif    i = 100;   //拉低约800us, 符合协议要求的480us以上
 85InBlock.gif    while(i>0) i--;
 86InBlock.gif    ds = 1;    //产生一个上升沿, 进入等待应答状态
 87InBlock.gif    i = 4;
 88InBlock.gif    while(i>0) i--;
 89ExpandedBlockEnd.gif}

 90None.gif
 91None.gifvoid dsWait()
 92ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 93InBlock.gif     unsigned int i;
 94InBlock.gif     while(ds);  
 95InBlock.gif     while(~ds);  //检测到应答脉冲
 96InBlock.gif     i = 4;
 97InBlock.gif     while(i > 0) i--;
 98ExpandedBlockEnd.gif}

 99None.gif
100None.gif//向DS18B20读取一位数据
101None.gif//读一位, 让DS18B20一小周期低电平, 然后两小周期高电平, 
102None.gif//之后DS18B20则会输出持续一段时间的一位数据
103None.gifbit readBit()
104ExpandedBlockStart.gifContractedBlock.gifdot.gif{
105InBlock.gif    unsigned int i;
106InBlock.gif    bit b;
107InBlock.gif    ds = 0;
108InBlock.gif    i++;   //延时约8us, 符合协议要求至少保持1us
109InBlock.gif    ds = 1
110InBlock.gif    i++; i++;  //延时约16us, 符合协议要求的至少延时15us以上
111InBlock.gif    b = ds;
112InBlock.gif    i = 8
113InBlock.gif    while(i>0) i--;  //延时约64us, 符合读时隙不低于60us要求
114InBlock.gif    return b;
115ExpandedBlockEnd.gif}

116None.gif
117None.gif//读取一字节数据, 通过调用readBit()来实现
118None.gifunsigned char readByte()
119ExpandedBlockStart.gifContractedBlock.gifdot.gif{
120InBlock.gif    unsigned int i;
121InBlock.gif    unsigned char j, dat;
122InBlock.gif    dat = 0;
123InBlock.gif    for(i=0; i<8; i++)
124ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
125InBlock.gif        j = readBit();
126InBlock.gif        //最先读出的是最低位数据
127InBlock.gif        dat = (j << 7| (dat >> 1);
128ExpandedSubBlockEnd.gif    }

129InBlock.gif    return dat;
130ExpandedBlockEnd.gif}

131None.gif
132None.gif//向DS18B20写入一字节数据
133None.gifvoid writeByte(unsigned char dat)
134ExpandedBlockStart.gifContractedBlock.gifdot.gif{
135InBlock.gif    unsigned int i;
136InBlock.gif    unsigned char j;
137InBlock.gif    bit b;
138InBlock.gif    for(j = 0; j < 8; j++)
139ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
140InBlock.gif        b = dat & 0x01;
141InBlock.gif        dat >>= 1;
142InBlock.gif        //写"1", 将DQ拉低15us后, 在15us~60us内将DQ拉高, 即完成写1
143InBlock.gif        if(b)   
144ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
145InBlock.gif            ds = 0;
146InBlock.gif            i++; i++;  //拉低约16us, 符号要求15~60us内
147InBlock.gif            ds = 1;    
148InBlock.gif            i = 8while(i>0) i--;  //延时约64us, 符合写时隙不低于60us要求
149ExpandedSubBlockEnd.gif        }

150InBlock.gif        else  //写"0", 将DQ拉低60us~120us
151ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
152InBlock.gif            ds = 0;
153InBlock.gif            i = 8while(i>0) i--;  //拉低约64us, 符号要求
154InBlock.gif            ds = 1;
155InBlock.gif            i++; i++;  //整个写0时隙过程已经超过60us, 这里就不用像写1那样, 再延时64us了
156ExpandedSubBlockEnd.gif        }

157ExpandedSubBlockEnd.gif    }

158ExpandedBlockEnd.gif}

159None.gif
160None.gif//向DS18B20发送温度转换命令
161None.gifvoid sendChangeCmd()
162ExpandedBlockStart.gifContractedBlock.gifdot.gif{
163InBlock.gif    dsInit();    //初始化DS18B20, 无论什么命令, 首先都要发起初始化
164InBlock.gif    dsWait();   //等待DS18B20应答
165InBlock.gif    delay(1);    //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号
166InBlock.gif    writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
167InBlock.gif    writeByte(0x44); //写入温度转换命令字 Convert T
168ExpandedBlockEnd.gif}

169None.gif
170None.gif//向DS18B20发送读取数据命令
171None.gifvoid sendReadCmd()
172ExpandedBlockStart.gifContractedBlock.gifdot.gif{
173InBlock.gif    dsInit();
174InBlock.gif    dsWait();
175InBlock.gif    delay(1);
176InBlock.gif    writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
177InBlock.gif    writeByte(0xbe); //写入读取数据令字 Read Scratchpad
178ExpandedBlockEnd.gif}

179None.gif
180None.gif//获取当前温度值
181None.gifvoid getTempValue()
182ExpandedBlockStart.gifContractedBlock.gifdot.gif{
183InBlock.gif    unsigned int tmpvalue;
184InBlock.gif    float t;
185InBlock.gif    unsigned char low, high;
186InBlock.gif    sendReadCmd();
187InBlock.gif    //连续读取两个字节数据
188InBlock.gif    low = readByte(); 
189InBlock.gif    high = readByte();
190InBlock.gif    //将高低两个字节合成一个整形变量
191InBlock.gif    //计算机中对于负数是利用补码来表示的
192InBlock.gif    //若是负值, 读取出来的数值是用补码表示的, 可直接赋值给int型的value
193InBlock.gif    tmpvalue = high;
194InBlock.gif    tmpvalue <<= 8;
195InBlock.gif    tmpvalue |= low;
196InBlock.gif    tempValue = tmpvalue;
197InBlock.gif    
198InBlock.gif    //使用DS18B20的默认分辨率12位, 精确度为0.0625度, 即读回数据的最低位代表0.0625度
199InBlock.gif    t = tempValue * 0.0625;
200InBlock.gif    //将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入
201InBlock.gif    //如t=11.0625, 进行计数后, 得到value = 1106, 即11.06 度
202InBlock.gif    //如t=-11.0625, 进行计数后, 得到value = -1106, 即-11.06 度
203InBlock.gif    tempValue = t * 100 + (tempValue > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5
204ExpandedBlockEnd.gif}

205None.gif
206None.gif//显示当前温度值, 精确到小数点后一位
207None.gif//若先位选再段选, 由于IO口默认输出高电平, 所以当先位选会使数码管出现乱码
208None.gifvoid displayTemp() 
209ExpandedBlockStart.gifContractedBlock.gifdot.gif{
210InBlock.gif    unsigned char i;
211InBlock.gif    unsigned int tmp = abs(tempValue);
212InBlock.gif    tmpDatas[0= tmp / 10000;
213InBlock.gif    tmpDatas[1= tmp % 10000 / 1000;
214InBlock.gif    tmpDatas[2= tmp % 1000 / 100;
215InBlock.gif    tmpDatas[3= tmp % 100 / 10;
216InBlock.gif    tmpDatas[4= tmp % 10;
217InBlock.gif    if(tempValue < 0)
218ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
219InBlock.gif        //关位选, 去除对上一位的影响
220InBlock.gif        P0 = 0xff
221InBlock.gif        wela = 1//打开锁存, 给它一个下降沿量
222InBlock.gif        wela = 0;
223InBlock.gif        //段选
224InBlock.gif        P0 = 0x40//显示"-"号
225InBlock.gif        dula = 1;  //打开锁存, 给它一个下降沿量
226InBlock.gif        dula = 0;
227InBlock.gif
228InBlock.gif        //位选
229InBlock.gif        P0 = 0xfe
230InBlock.gif        wela = 1//打开锁存, 给它一个下降沿量
231InBlock.gif        wela = 0;
232InBlock.gif        delay(1); 
233ExpandedSubBlockEnd.gif    }

234InBlock.gif    for(i = 0; i != 5; i++)
235ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
236InBlock.gif        //关位选, 去除对上一位的影响
237InBlock.gif        P0 = 0xff
238InBlock.gif        wela = 1//打开锁存, 给它一个下降沿量
239InBlock.gif        wela = 0;
240InBlock.gif        //段选
241InBlock.gif        if(i != 2)
242ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
243InBlock.gif            P0 = table[tmpDatas[i]];  //显示数字
244ExpandedSubBlockEnd.gif        }

245InBlock.gif        else
246ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
247InBlock.gif            P0 = tableWidthDot[tmpDatas[i]]; //显示带小数点数字
248ExpandedSubBlockEnd.gif        }

249InBlock.gif        dula = 1;  //打开锁存, 给它一个下降沿量
250InBlock.gif        dula = 0;
251InBlock.gif
252InBlock.gif        //位选 
253InBlock.gif        P0 = _crol_(0xfd, i); //选择第(i + 1) 个数码管
254InBlock.gif        wela = 1//打开锁存, 给它一个下降沿量
255InBlock.gif        wela = 0;
256InBlock.gif        delay(1); 
257ExpandedSubBlockEnd.gif    }

258InBlock.gif    tempCount++;
259InBlock.gif    if(tempCount==100)
260ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
261InBlock.gif        tempCount = 0;
262InBlock.gif        getTempValue();
263InBlock.gif        sendChangeCmd();
264ExpandedSubBlockEnd.gif    }

265ExpandedBlockEnd.gif}

266None.gif
267None.gif//显示时钟和秒表的结果
268None.gifvoid display() 
269ExpandedBlockStart.gifContractedBlock.gifdot.gif{
270InBlock.gif    unsigned char i;
271InBlock.gif    if(mode == 4//显示温度
272ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
273InBlock.gif        displayTemp();
274ExpandedSubBlockEnd.gif    }

275ExpandedSubBlockStart.gifContractedSubBlock.gif    else dot.gif{  //显示时间
276InBlock.gif        for(i = 0; i < 6; i++)
277ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
278InBlock.gif            //关位选, 去除对上一位的影响
279InBlock.gif            P0 = 0xff
280InBlock.gif            wela = 1//打开锁存, 给它一个下降沿量
281InBlock.gif            wela = 0;
282InBlock.gif            //段选
283InBlock.gif            if(i == 2 || i == 4)
284ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
285InBlock.gif                P0 = tableWidthDot[values[i]]; //显示带小数点数字, 作为分秒, 秒与毫秒的分隔
286ExpandedSubBlockEnd.gif            }

287InBlock.gif            else
288ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
289InBlock.gif                P0 = table[values[i]];  //显示数字
290ExpandedSubBlockEnd.gif            }

291InBlock.gif            if(mode == 2 && i == clockPosition)  //时钟设置模式下, 光标所在位置, 闪烁
292ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
293InBlock.gif                clockTmp++;
294InBlock.gif                if(clockTmp == 20)
295ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
296InBlock.gif                    clockTmpBit = ~clockTmpBit;
297InBlock.gif                    clockTmp = 0;
298ExpandedSubBlockEnd.gif                }

299InBlock.gif                if(clockTmpBit)
300InBlock.gif                    P0 = 0x00;
301ExpandedSubBlockEnd.gif            }

302InBlock.gif            dula = 1;  //打开锁存, 给它一个下降沿量
303InBlock.gif            dula = 0;
304InBlock.gif            
305InBlock.gif            //位选 
306InBlock.gif            P0 = _cror_(0xdf, i); //选择第(i + 1) 个数码管
307InBlock.gif            wela = 1//打开锁存, 给它一个下降沿量
308InBlock.gif            wela = 0;
309InBlock.gif            delay(1);
310ExpandedSubBlockEnd.gif        }

311InBlock.gif        if(mode == 2 && 6 == clockPosition)  //时钟设置模式下, 光标所在位置, 闪烁
312ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
313InBlock.gif            clockTmp++;
314InBlock.gif            if(clockTmp == 20)
315ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
316InBlock.gif                clockTmpBit = ~clockTmpBit;
317InBlock.gif                clockTmp = 0;
318ExpandedSubBlockEnd.gif            }

319InBlock.gif            if(clockTmpBit)
320ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
321InBlock.gif                if(values[6== 0)
322ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
323InBlock.gif                    P1 = 0x0f;
324ExpandedSubBlockEnd.gif                }

325InBlock.gif                else
326ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
327InBlock.gif                    P1 = ~values[6];
328ExpandedSubBlockEnd.gif                }

329ExpandedSubBlockEnd.gif            }

330InBlock.gif            else
331ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
332InBlock.gif                P1 = 0xff;
333ExpandedSubBlockEnd.gif            }

334ExpandedSubBlockEnd.gif        }

335InBlock.gif        else
336ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
337InBlock.gif            P1 = ~values[6];
338ExpandedSubBlockEnd.gif        }

339ExpandedSubBlockEnd.gif    }

340ExpandedBlockEnd.gif}

341None.gif
342None.gif//检测功能模式键是否被按下
343None.gifvoid checkModeKey()
344ExpandedBlockStart.gifContractedBlock.gifdot.gif{
345InBlock.gif    if(!S5)
346ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
347InBlock.gif        delay(7);
348InBlock.gif        if(!S5) 
349ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
350InBlock.gif            mode++;
351InBlock.gif            switch(mode)
352ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
353InBlock.gif                case 2//定时器0是不会关闭的, 即使在设置模式下
354InBlock.gif                    for(icount = 0; icount < 7; icount++)
355ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif{
356InBlock.gif                        tmpDatas[icount] = clockDatas[icount]; //将设置之前的值暂存到临时数组
357ExpandedSubBlockEnd.gif                    }

358InBlock.gif                    values = tmpDatas;
359InBlock.gif                    break;
360InBlock.gif                case 3//秒表模式
361InBlock.gif                    values = datas;
362InBlock.gif                    break;
363InBlock.gif                case 4//温度计模式
364InBlock.gif                    //启动温度转换
365InBlock.gif                    sendChangeCmd();
366InBlock.gif                    getTempValue();
367InBlock.gif                    break;
368InBlock.gif                default:
369InBlock.gif                    values = clockDatas;
370InBlock.gif                    mode = 1;
371InBlock.gif                    TR0 = 1;
372ExpandedSubBlockEnd.gif            }

373InBlock.gif            while(!S5)  //等待释放键
374ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
375InBlock.gif                display();
376ExpandedSubBlockEnd.gif            }

377ExpandedSubBlockEnd.gif        }

378ExpandedSubBlockEnd.gif    }

379ExpandedBlockEnd.gif}

380None.gif
381None.gif//选中位数值增1, 用于时钟模式的设置状态下
382None.gifvoid add()
383ExpandedBlockStart.gifContractedBlock.gifdot.gif{
384InBlock.gif    values[clockPosition]++;
385InBlock.gif    switch(clockPosition)
386ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
387InBlock.gif        case 3:
388InBlock.gif        case 5:
389InBlock.gif            if(values[clockPosition] > 5)
390InBlock.gif                values[clockPosition] = 0;
391InBlock.gif            break;
392InBlock.gif        case 6:
393InBlock.gif            if(values[clockPosition] > 23)
394InBlock.gif                values[clockPosition] = 0;
395InBlock.gif            break;
396InBlock.gif        default:
397InBlock.gif            if(values[clockPosition] > 9)
398InBlock.gif                values[clockPosition] = 0;
399ExpandedSubBlockEnd.gif    }

400ExpandedBlockEnd.gif}

401None.gif
402None.gif//检测是否有键按下, 并执行相应功能
403None.gifvoid checkKey()
404ExpandedBlockStart.gifContractedBlock.gifdot.gif{
405InBlock.gif    checkModeKey();
406InBlock.gif    switch(mode)
407ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
408InBlock.gif        case 2:
409InBlock.gif            if(!S2)  //左移光标位
410ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
411InBlock.gif                delay(7);
412InBlock.gif                if(!S2)
413ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
414InBlock.gif                    clockPosition++;
415InBlock.gif                    if(clockPosition > 6)
416ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif{
417InBlock.gif                        clockPosition = 0;
418ExpandedSubBlockEnd.gif                    }

419ExpandedSubBlockEnd.gif                }

420ExpandedSubBlockEnd.gif            }

421InBlock.gif            else if(!S3)  //选中位增1
422ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
423InBlock.gif                delay(7);
424InBlock.gif                if(!S3)
425ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
426InBlock.gif                    add();
427ExpandedSubBlockEnd.gif                }

428ExpandedSubBlockEnd.gif            }

429InBlock.gif            else if(!S4)  //选中确定更改
430ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
431InBlock.gif                delay(7);
432InBlock.gif                if(!S4)
433ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
434InBlock.gif                    for(icount = 0; icount < 7; icount++)
435ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif{
436InBlock.gif                        clockDatas[icount] = tmpDatas[icount]; //将设置的值存到clockDatas[]
437ExpandedSubBlockEnd.gif                    }

438InBlock.gif                    values = clockDatas;
439InBlock.gif                    mode = 1//将模式变成时钟模式
440ExpandedSubBlockEnd.gif                }

441ExpandedSubBlockEnd.gif            }

442InBlock.gif            break;
443InBlock.gif        case 3:
444InBlock.gif            if(!S2)
445ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
446InBlock.gif                delay(7);  //延时大约10ms, 去抖动
447InBlock.gif                if(!S2)  //开始/暂停键按下
448ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
449InBlock.gif                    TR1 = ~TR1;
450ExpandedSubBlockEnd.gif                }

451ExpandedSubBlockEnd.gif            }

452InBlock.gif        
453InBlock.gif            else if(!S3)
454ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
455InBlock.gif                delay(7);  //延时大约10ms, 去抖动
456InBlock.gif                if(!S3)  //清零键按下
457ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
458InBlock.gif                    TR1 = 0;
459InBlock.gif                    TH1 = th;
460InBlock.gif                    TL1 = tl;
461InBlock.gif                    for(icount = 0; icount < 7; icount++)
462ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif{
463InBlock.gif                        datas[icount] = 0;
464ExpandedSubBlockEnd.gif                    }

465ExpandedSubBlockEnd.gif                }

466ExpandedSubBlockEnd.gif            }

467InBlock.gif            break;
468ExpandedSubBlockEnd.gif    }

469InBlock.gif    //等待键被释放
470InBlock.gif    while(!S2 || !S3 || !S4)
471ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
472InBlock.gif        display(); // 等待期间要显示
473ExpandedSubBlockEnd.gif    }

474ExpandedBlockEnd.gif}

475None.gif
476None.gifvoid main()
477ExpandedBlockStart.gifContractedBlock.gifdot.gif{
478InBlock.gif    delay(1);
479InBlock.gif    th = 0xdb;//(65536 - 10000/1.085) / 256;  //定时10ms
480InBlock.gif    tl = 0xff;//(65536 - 10000/1.085) - th * 256;
481InBlock.gif    TH1 = TH0 = th; //初始化定时器1, 0
482InBlock.gif    TL1 = TL0 = tl;
483InBlock.gif    EA = 1;  //开中断
484InBlock.gif    ET1 = ET0 = 1//允许定时器1, 0 中断请求
485InBlock.gif    TMOD = 0x11;  //定时器1, 0 都工作方式1
486InBlock.gif    TR1 = 0;
487InBlock.gif    TR0 = 1//开始显示时间
488InBlock.gif    while(1)
489ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
490InBlock.gif        checkKey();  //检测是否就键按下
491InBlock.gif        display();  //显示计时值
492ExpandedSubBlockEnd.gif    }

493ExpandedBlockEnd.gif}

494None.gif
495None.gif//定时器0中断响应函数, 用于时钟计时
496None.gifvoid time0() interrupt 1
497ExpandedBlockStart.gifContractedBlock.gifdot.gif{
498InBlock.gif    TH0 = th;  //重置计数值
499InBlock.gif    TL0 = tl;
500InBlock.gif
501InBlock.gif    clockDatas[0]++;  //0.01秒
502InBlock.gif    if(clockDatas[0== 10)
503ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
504InBlock.gif        clockDatas[0= 0;
505InBlock.gif        clockDatas[1]++;   //0.1秒
506InBlock.gif        if(clockDatas[1== 10)
507ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
508InBlock.gif            clockDatas[1= 0;
509InBlock.gif            clockDatas[2]++;  //
510InBlock.gif            if(clockDatas[2== 10)
511ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
512InBlock.gif                clockDatas[2= 0;
513InBlock.gif                clockDatas[3]++;   //10秒
514InBlock.gif                if(clockDatas[3== 6)
515ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
516InBlock.gif                    clockDatas[3= 0;
517InBlock.gif                    clockDatas[4]++;  //
518InBlock.gif                    if(clockDatas[4== 10)
519ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif{
520InBlock.gif                        clockDatas[4= 0;
521InBlock.gif                        clockDatas[5]++;  //10分
522InBlock.gif                        if(clockDatas[5== 6)
523ExpandedSubBlockStart.gifContractedSubBlock.gif                        dot.gif{
524InBlock.gif                            clockDatas[5= 0;
525InBlock.gif                            clockDatas[6]++;  //
526InBlock.gif                            if(clockDatas[6== 24)
527ExpandedSubBlockStart.gifContractedSubBlock.gif                            dot.gif{
528InBlock.gif                                clockDatas[6= 0;
529ExpandedSubBlockEnd.gif                            }

530ExpandedSubBlockEnd.gif                        }

531ExpandedSubBlockEnd.gif                    }

532ExpandedSubBlockEnd.gif                }

533ExpandedSubBlockEnd.gif            }

534ExpandedSubBlockEnd.gif        }

535ExpandedSubBlockEnd.gif    }

536ExpandedBlockEnd.gif}

537None.gif
538None.gif//定时器1中断响应函数, 用于秒表计时
539None.gifvoid time1() interrupt 3
540ExpandedBlockStart.gifContractedBlock.gifdot.gif{
541InBlock.gif    TH1 = th;  //重置计数值
542InBlock.gif    TL1 = tl;
543InBlock.gif
544InBlock.gif    datas[0]++;  //0.01秒
545InBlock.gif    if(datas[0== 10)
546ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
547InBlock.gif        datas[0= 0;
548InBlock.gif        datas[1]++;   //0.1秒
549InBlock.gif        if(datas[1== 10)
550ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
551InBlock.gif            datas[1= 0;
552InBlock.gif            datas[2]++;  //
553InBlock.gif            if(datas[2== 10)
554ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
555InBlock.gif                datas[2= 0;
556InBlock.gif                datas[3]++;   //10秒
557InBlock.gif                if(datas[3== 6)
558ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
559InBlock.gif                    datas[3= 0;
560InBlock.gif                    datas[4]++;  //
561InBlock.gif                    if(datas[4== 10)
562ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif{
563InBlock.gif                        datas[4= 0;
564InBlock.gif                        datas[5]++;  //10分
565InBlock.gif                        if(datas[5== 6)
566ExpandedSubBlockStart.gifContractedSubBlock.gif                        dot.gif{
567InBlock.gif                            datas[5= 0;
568InBlock.gif                            datas[6]++;  //
569InBlock.gif                            if(datas[6== 24)
570ExpandedSubBlockStart.gifContractedSubBlock.gif                            dot.gif{
571InBlock.gif                                datas[6= 0;
572ExpandedSubBlockEnd.gif                            }

573ExpandedSubBlockEnd.gif                        }

574ExpandedSubBlockEnd.gif                    }

575ExpandedSubBlockEnd.gif                }

576ExpandedSubBlockEnd.gif            }

577ExpandedSubBlockEnd.gif        }

578ExpandedSubBlockEnd.gif    }

579ExpandedBlockEnd.gif}


效果图:
时钟模式: 当前时间为11: 52: 56,98


秒表: 已计时34分13.88秒


温度计: 当前室内温度

转载于:https://www.cnblogs.com/fengmk2/archive/2007/03/15/676604.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值