3、分段计时功能的秒表 (25分)设计一个具有分段计时功能的秒表,要求精度为10ms。
(1)实现秒表功能,从0计时到10s,于LCD显示,显示两位小数,到10s
后显示10.00;(使用定时器)(5分)
(2)设计开始及结束键,当开始键按下时,计时开始并通过LCD显示,当结束键按下时.计时结束,通过串口向上位机发送当前时间。(到达10s时计时自动停止)。(5分)
(3)设计暂停键,当按下时,计时暂停,再次按下时计时从当前时间继续。(5 分)
(4)设计分段计时键,当按下时,计时不停止,但是会记录当前时间,待结束键按下或到达计时间后,向上位机发送分段计时次数。同时,上位机可通过串口多次查询分段计时的时间,如发送字符1',单片机向上位机发送第一次分段计时的时间。(10分)
1.实现秒表功能,从0计时到10s,于LCD显示,显示两位小数,到10s后显示10.00;(使用定时器)
#include <reg52.h>
sbit key_start = P3^0; // 开始键
sbit key_pause = P3^1; // 暂停键
sbit key_stop = P3^2; // 停止键
unsigned char code table[] = "0123456789"; // 数码管字符表
unsigned char second; // 秒数
unsigned char ms; // 毫秒数
bit pause_flag = 0; // 暂停标志位
void display(unsigned char num) // 数码管显示函数
{
unsigned char shiwei, gewei; // 十位和个位数字
shiwei = num / 10; // 取十位数字
gewei = num % 10; // 取个位数字
P0 = 0; // 段码位清零
P2 = 0x01; // 第一位数码管选通
P0 = table[shiwei]; // 显示十位数字
delay(1); // 延时一段时间
P2 = 0x02; // 第���位数码管选通
P0 = table[gewei]; // 显示个位数字
delay(1); // 延时一段时间
}
void timer0() interrupt 1 // 定时器0中断服务函数
{
TH0 = (65536-10000)/256; // 重新赋值定时器初值,实现10ms的定时
TL0 = (65536-10000)%256;
if (!pause_flag) // 如果不是暂停状态
{
ms++; // 毫秒数加1
if (ms == 100) // 如果毫秒数达到100
{
second++; // 秒数加1
ms = 0; // 毫秒数清零
}
if (second == 100) // 如果秒数达到100
{
second = 0; // 秒数清零
}
}
if (second == 10 && ms == 0) // 到达10s
{
display(100); // 在数码管上显示10.00
TR0 = 0; // 关闭定时器0
}
else // 没有到达10s
{
display(second); // 在数码管上显示秒数
P2 = 0x04; // 第三位数码管选通
P0 = 0x80; // 小数点显示
delay(1); // 延时一段时间
display(ms/10); // 在数码管上显示毫秒数的十位数字
P2 = 0x08; // 第四位数码管选通
P0 = table[ms%10]; // 在数码管上显示毫秒数的个位数字
delay(1); // 延时一段时间
}
}
void delay(unsigned int i) // 延时函数,i为延时时间
{
unsigned int j, k;
for (j = i; j > 0; j--)
for (k = 112; k > 0; k--);
}
void main()
{
TMOD = 0x01; // 定时器0工作在模式1
TH0 = (65536-10000)/256; // 定时器初值
TL0 = (65536-10000)%256;
TR0 = 1; // 启动定时器0
ET0 = 1; // 允许定时器0中断
EA = 1; // 允许总中断
while (1)
{
if (second == 10 && ms == 0) // 到达10s
{
break;
}
}
}
2.设计开始及结束键,当开始键按下时,计时开始并通过LCD显示,当结束键按下时.计时结束,通过串口向上位机发送当前时间。(到达10s时计时自动停止)
#include <reg52.h>
#include <stdio.h>
sbit key_start = P3^0; // 开始键
sbit key_pause = P3^1; // 暂停键
sbit key_stop = P3^2; // 停止键
unsigned char code table[] = "0123456789"; // 数码管字符表
unsigned char second; // 秒数
unsigned char ms; // 毫秒数
bit pause_flag = 0; // 暂停标志位
void display(unsigned char num) // 数码管显示函数
{
unsigned char shiwei, gewei; // 十位和个位数字
shiwei = num / 10; // 取十位数字
gewei = num % 10; // 取个位数字
P0 = 0; // 段码位清零
P2 = 0x01; // 第一位数码管选通
P0 = table[shiwei]; // 显示十位数字
delay(1); // 延时一段时间
P2 = 0x02; // 第二位数码管选通
P0 = table[gewei]; // 显示个位数字
delay(1); // 延时一段时间
}
void timer0() interrupt 1 // 定时器0中断服务函数
{
TH0 = (65536-10000)/256; // 重新赋值定时器初值,实现10ms的定时
TL0 = (65536-10000)%256;
if (!pause_flag) // 如果不是暂停状态
{
ms++; // 毫秒数加1
if (ms == 100) // 如果毫秒数达到100
{
second++; // 秒数加1
ms = 0; // 毫秒数清零
}
if (second == 100) // 如果秒数达到100
{
second = 0; // 秒数清零
}
}
if (second == 10 && ms == 0) // 到达10s
{
display(100); // 在数码管上显示10.00
TR0 = 0; // 关闭定时器0
}
else // 没有到达10s
{
display(second); // 在数码管上显示秒数
P2 = 0x04; // 第三位数码管选通
P0 = 0x80; // 小数点显示
delay(1); // 延时一段时间
display(ms/10); // 在数码管上显示毫秒数的十位数字
P2 = 0x08; // 第四位数码管选通
P0 = table[ms%10]; // 在数码管上显示毫秒数的个位数字
delay(1); // 延时一段时间
}
}
void delay(unsigned int i) // 延时函数,i为延时时间
{
unsigned int j, k;
for (j = i; j > 0; j--)
for (k = 112; k > 0; k--);
}
void main()
{
TMOD = 0x01; // 定时器0工作在模式1
TH0 = (65536-10000)/256; // 定时器初值
TL0 = (65536-10000)%256;
TR0 = 0; // 关闭定时器0
ET0 = 1; // 允许定时器0中断
EA = 1; // 允许总中断
while (1)
{
if (!key_start) // 开始键按下
{
second = 0; // 秒数清零
ms = 0; // 毫秒数清零
TR0 = 1; // 启动定时器0
printf("Start\r\n"); // 通过串口向上位机发送开始计时的信息
break;
}
}
while (1)
{
if (second == 10 && ms == 0) // 到达10s
{
printf("Time: %d.%02d s\r\n", second, ms); // 通过串口向上位机发送计时时间
break;
}
if (!key_stop) // 停止键按下
{
TR0 = 0; // 关闭定时器0
printf("Stop\r\n"); // 通过串口向上位机发送停止计时的信息
break;
}
}
}
3.设计暂停键,当按下时,计时暂停,再次按下时计时从当前时间继续
#include <reg52.h>
#include <stdio.h>
sbit key_start = P3^0; // 开始键
sbit key_pause = P3^1; // 暂停键
sbit key_stop = P3^2; // 停止键
unsigned char code table[] = "0123456789"; // 数码管字符表
unsigned char second; // 秒数
unsigned char ms; // 毫秒数
bit pause_flag = 0; // 暂停标志位
void display(unsigned char num) // 数码管显示函数
{
unsigned char shiwei, gewei; // 十位和个位数字
shiwei = num / 10; // 取十位数字
gewei = num % 10; // 取个位数字
P0 = 0; // 段码位清零
P2 = 0x01; // 第一位数码管选通
P0 = table[shiwei]; // 显示十位数字
delay(1); // 延时一段时间
P2 = 0x02; // 第二位数码管选通
P0 = table[gewei]; // 显示个位数字
delay(1); // 延时一段时间
}
void timer0() interrupt 1 // 定时器0中断服务函数
{
TH0 = (65536-10000)/256; // 重新赋值定时器初值,实现10ms的定时
TL0 = (65536-10000)%256;
if (!pause_flag) // 如果不是暂停状态
{
ms++; // 毫秒数加1
if (ms == 100) // 如果毫秒数达到100
{
second++; // 秒数加1
ms = 0; // 毫秒数清零
}
if (second == 100) // 如果秒数达到100
{
second = 0; // 秒数清零
}
}
if (second == 10 && ms == 0) // 到达10s
{
display(100); // 在数码管上显示10.00
TR0 = 0; // 关闭定时器0
}
else // 没有到达10s
{
display(second); // 在数码管上显示秒数
P2 = 0x04; // 第三位数码管选通
P0 = 0x80; // 小数点显示
delay(1); // 延时一段时间
display(ms/10); // 在数码管上显示毫秒数的十位数字
P2 = 0x08; // 第四位数码管选通
P0 = table[ms%10]; // 在数码管上显示毫秒数的个位数字
delay(1); // 延时一段时间
}
}
void delay(unsigned int i) // 延时函数,i为延时时间
{
unsigned int j, k;
for (j = i; j > 0; j--)
for (k = 112; k > 0; k--);
}
void main()
{
TMOD = 0x01; // 定时器0工作在模式1
TH0 = (65536-10000)/256; // 定时器初值
TL0 = (65536-10000)%256;
TR0 = 0; // 关闭定时器0
ET0 = 1; // 允许定时器0中断
EA = 1; // 允许总中断
while (1)
{
if (!key_start) // 开始键按下
{
second = 0; // 秒数清零
ms = 0; // 毫秒数清零
TR0 = 1; // 启动定时器0
printf("Start\r\n"); // 通过串口向上位机发送开始计时的信息
break;
}
}
while (1)
{
if (!pause_flag && key_pause) // 暂停键按下
{
TR0 = 0; // 关闭定时器0
pause_flag = 1; // 设置暂停标志位
printf("Pause\r\n"); // 通过串口向上位机发送暂停计时的信息
}
if (pause_flag && !key_pause) // 暂停键松开
{
TR0 = 1; // 启动定时器0
pause_flag = 0; // 清除暂停标志位
printf("Resume\r\n"); // 通过串口向上位机发送恢复计时的信息
}
if (second == 10 && ms == 0) // 到达10s
{
printf("Time: %d.%02d s\r\n", second, ms); // 通过串口向上位机发送计时时间
break;
}
if (!key_stop) // 停止键按下
{
TR0 = 0; // 关闭定时器0
printf("Stop\r\n"); // 通过串口向上位机发送停止计时的信息
break;
}
}
}
4.设计分段计时键,当按下时,计时不停止,但是会记录当前时间,待结束键按下或到达计时间后,向上位机发送分段计时次数。同时,上位机可通过串口多次查询分段计时的时间,如发送字符1',单片机向上位机发送第一次分段计时的时间
#include <reg52.h>
#include <stdio.h>
sbit key_start = P3^0; // 开始键
sbit key_pause = P3^1; // 暂停键
sbit key_stop = P3^2; // 停止键
sbit key_split = P3^3; // 分段计时键
unsigned char code table[] = "0123456789"; // 数码管字符表
unsigned char second; // 秒数
unsigned char ms; // 毫秒数
bit pause_flag = 0; // 暂停标志位
unsigned char split_count = 0; // 分段计时次数
unsigned