[经验分享]

基于 52 单片机的数字秒表设计

[复制链接]
204|0
手机看帖
扫描二维码
随时随地手机跟帖
Haizangwang|  楼主 | 2025-1-3 09:08 | 显示全部楼层 |阅读模式
      在《单片机技术及应用》课程学习里,基于 52 单片机的数字秒表设计是一个极具代表性的实践项目。下面我将详细分享其设计过程。

一、硬件设计

        该数字秒表以 STC89C52 单片机为核心。其硬件主要包括:

• 显示模块:采用四位共阴极数码管,用于显示秒表的计时数值。通过单片机的 P0 口作为数据输出口,P2 口的部分引脚作为位选信号控制端。

• 按键模块:设置三个按键,分别为开始/暂停键、复位键以及功能切换键。这些按键连接到单片机的 P3 口,通过检测不同引脚的电平变化来确定按键动作。

二、软件设计

以下是核心代码片段:
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int

// 数码管段选码表,用于显示 0 - 9 数字
uchar code table[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
uchar dispbuf[4];  // 存放要显示的四位数字
uint count = 0;   // 计时计数变量
uchar keyvalue;   // 存储按键值

// 延时函数
void delay(uint xms) {
    uint i, j;
    for(i = xms; i > 0; i--)
        for(j = 110; j > 0; j--);
}

// 数码管显示函数
void display() {
    uchar i;
    for(i = 0; i < 4; i++) {
        P2 = (0x01 << i);  // 位选
        P0 = table[dispbuf[i]];  // 段选
        delay(5);
    }
}

// 按键扫描函数
uchar keyscan() {
    uchar temp;
    P3 = 0xff;
    if((P3 & 0x01) == 0) {  // 开始/暂停键
        delay(10);
        if((P3 & 0x01) == 0) {
            temp = 1;
            while((P3 & 0x01) == 0);
        }
    } else if((P3 & 0x02) == 0) {  // 复位键
        delay(10);
        if((P3 & 0x02) == 0) {
            temp = 2;
            while((P3 & 0x02) == 0);
        }
    } else if((P3 & 0x04) == 0) {  // 功能切换键
        delay(10);
        if((P3 & 0x04) == 0) {
            temp = 3;
            while((P3 & 0x04) == 0);
        }
    } else {
        temp = 0;
    }
    return temp;
}

// 秒表计时函数
void timer0() interrupt 1 {
    TH0 = (65536 - 50000) / 256;  // 定时 50ms
    TL0 = (65536 - 50000) % 256;
    count++;
    if(count == 20) {  // 满 1s
        count = 0;
        // 秒位加 1 并处理进位等逻辑
        dispbuf[3]++;
        if(dispbuf[3] == 10) {
            dispbuf[3] = 0;
            dispbuf[2]++;
            if(dispbuf[2] == 6) {
                dispbuf[2] = 0;
                dispbuf[1]++;
                if(dispbuf[1] == 10) {
                    dispbuf[1] = 0;
                    dispbuf[0]++;
                }
            }
        }
    }
}

void main() {
    TMOD = 0x01;  // 定时器 0 工作模式 1
    TH0 = (65536 - 50000) / 256;
    TL0 = (65536 - 50000) % 256;
    EA = 1;  // 开总中断
    ET0 = 1;  // 开定时器 0 中断
    TR0 = 0;  // 初始定时器 0 关闭
    while(1) {
        keyvalue = keyscan();
        if(keyvalue == 1) {  // 开始/暂停键处理
            TR0 = ~TR0;
        } else if(keyvalue == 2) {  // 复位键处理
            count = 0;
            dispbuf[0] = 0;
            dispbuf[1] = 0;
            dispbuf[2] = 0;
            dispbuf[3] = 0;
            TR0 = 0;
        }
        display();
    }
}
       在软件设计中,定时器 0 用于产生 50ms 的定时中断,在中断服务程序中实现秒表的计时逻辑。按键扫描函数不断检测按键动作,并根据不同按键执行相应操作,如开始/暂停计时、复位秒表等。数码管显示函数则负责将计时数值实时显示在数码管上。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/2401_89506636/article/details/144332767

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

18

帖子

0

粉丝