设计一个基于51单片机的秒表计时器
时间: 2023-11-11 18:04:34 浏览: 150
基于51单片机的秒表设计
好的,以下是一个基于51单片机的秒表计时器的设计方案。
硬件部分:
1. 一个51单片机,推荐使用AT89C51或AT89S51。
2. 一个16x2 LCD液晶显示屏,用于显示计时结果。
3. 两个按钮,一个用于启动/停止计时器,另一个用于重置计时器。
4. 一个4MHz晶振,用于提供时钟信号。
电路连接图如下:
![秒表计时器电路连接图](https://img-blog.csdnimg.cn/20220412150654142.png)
软件部分:
1. 初始化:设置51单片机的各个引脚为输入或输出模式,初始化LCD显示屏,并将计时器清零。
2. 计时:通过定时器中断实现计时功能,每1ms触发一次定时器中断,并将计时器的计数值加1。
3. 显示:将计时器的计数值转换为分钟、秒钟和毫秒,并在LCD显示屏上显示出来。
4. 功能键:检测启动/停止和重置按钮的按下事件,并根据按键状态进行相应的操作。
示例代码如下:
```c
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit start_stop=P3^4; //启动/停止按钮
sbit reset=P3^5; //重置按钮
sbit E=P2^7; //LCD使能端
sbit RW=P2^6; //LCD读写选择端
sbit RS=P2^5; //LCD指令数据选择端
uchar code table[]="Time: 00:00:000"; //默认显示字符串
uchar time[9]; //保存计时结果的数组
uchar flag=0; //启动/停止标志
uint ms=0, sec=0, min=0; //计时器的毫秒、秒钟和分钟计数值
//LCD写命令函数
void write_command(uchar com)
{
RS=0;
RW=0;
P0=com;
_nop_();
E=1;
_nop_();
E=0;
}
//LCD写数据函数
void write_data(uchar dat)
{
RS=1;
RW=0;
P0=dat;
_nop_();
E=1;
_nop_();
E=0;
}
//LCD初始化函数
void init_lcd()
{
write_command(0x38); //设置显示模式:16x2,5x7点阵
write_command(0x0c); //设置光标不可见
write_command(0x06); //设置文字不动,光标自动右移
write_command(0x01); //清屏
}
//将数字转换为字符串函数
void int_to_str(uint n, uchar *str)
{
uchar i;
for(i=0; i<3; i++)
{
str[2-i]=n%10+'0';
n/=10;
}
}
//将计数值转换为时间字符串函数
void update_time()
{
int_to_str(min, &time[0]); //转换分钟
int_to_str(sec, &time[3]); //转换秒钟
int_to_str(ms, &time[6]); //转换毫秒
}
//计时器中断函数
void timer_isr() interrupt 1
{
TH0=(65536-1000)/256; //重新赋值定时器初值
TL0=(65536-1000)%256;
if(flag==1) //如果启动标志为1,则进行计时
{
ms++; //毫秒计数值加1
if(ms==1000) //如果毫秒计数值达到1000,则进位到秒钟计数值
{
ms=0;
sec++;
if(sec==60) //如果秒钟计数值达到60,则进位到分钟计数值
{
sec=0;
min++;
}
}
update_time(); //更新计时器的时间字符串
write_command(0x80); //设置光标位置为第一行第一列
for(uchar i=0; i<16; i++) //清空第一行
write_data(' ');
write_command(0x80); //设置光标位置为第一行第一列
for(uchar i=0; i<16; i++) //在第一行显示计时结果
write_data(time[i]);
}
}
//启动/停止计时器函数
void start_stop_timer()
{
if(flag==0) //如果启动标志为0,则启动计时器
{
flag=1;
TR0=1; //启动定时器0
start_stop=0; //设置启动/停止按钮为低电平
}
else //如果启动标志为1,则停止计时器
{
flag=0;
TR0=0; //停止定时器0
start_stop=1; //设置启动/停止按钮为高电平
}
}
//重置计时器函数
void reset_timer()
{
flag=0;
ms=0;
sec=0;
min=0;
update_time(); //更新计时器的时间字符串
write_command(0x80); //设置光标位置为第一行第一列
for(uchar i=0; i<16; i++) //清空第一行
write_data(' ');
write_command(0x80); //设置光标位置为第一行第一列
for(uchar i=0; i<16; i++) //在第一行显示计时结果
write_data(time[i]);
}
//主函数
void main()
{
TMOD=0x01; //设置定时器0为模式1
TH0=(65536-1000)/256; //设置定时器0初值为1000us
TL0=(65536-1000)%256;
ET0=1; //开启定时器0中断
EA=1; //开启总中断
init_lcd(); //LCD初始化
update_time(); //更新计时器的时间字符串
write_command(0x80); //设置光标位置为第一行第一列
for(uchar i=0; i<16; i++) //在第一行显示计时结果
write_data(time[i]);
while(1)
{
if(start_stop==0) //检测启动/停止按钮是否按下
{
while(start_stop==0); //等待按钮松开
start_stop_timer(); //启动/停止计时器
}
if(reset==0) //检测重置按钮是否按下
{
while(reset==0); //等待按钮松开
reset_timer(); //重置计时器
}
}
}
```
这个设计方案可以实现秒表计时器的基本功能,可以根据具体需求进行修改和优化。
阅读全文