aaasas1111 2023-06-10 19:12 采纳率: 0%
浏览 62
已结题

关于#单片机#的问题:单片机基于51单片机开发计时器,使其实现以下功能:(1)开发板上四个独立按键分别控制计时器的启停、计时器的复位(按下计时值归零)、计时位切换、计时时间的递增

单片机
基于51单片机开发计时器,使其实现以下功能:
(1)开发板上四个独立按键分别控制计时器的启停、计时器的复位(按下计时值归零)、计时位切换、计时时间的递增,最小间隔为1。
(2)数码管上显示当前计时时间(用小时-分钟-秒的格式显示),启动计时后数码管上实时显示计时剩余时长。(中间用-隔开)
(3)计时时间到了后启动蜂鸣器(按下计时器复位按键后蜂鸣器停止)
要求:能在设备中运行即可,软件用到keil和普中
附图:

img

  • 写回答

5条回答 默认 最新

  • qllaoda 2023-06-10 20:02
    关注
    
    #include <reg51.h>
    
    // 数码管位选控制端口
    sbit digit1 = P2^0;
    sbit digit2 = P2^1;
    sbit digit3 = P2^2;
    
    // 数码管段选控制端口
    sbit segmentA = P1^0;
    sbit segmentB = P1^1;
    sbit segmentC = P1^2;
    sbit segmentD = P1^3;
    sbit segmentE = P1^4;
    sbit segmentF = P1^5;
    sbit segmentG = P1^6;
    sbit segmentDP = P1^7;
    
    // 按键控制端口
    sbit startStopButton = P3^0; // 启停按键
    sbit resetButton = P3^1;     // 复位按键
    sbit toggleButton = P3^2;    // 切换按键
    sbit incrementButton = P3^3; // 递增按键
    
    // 蜂鸣器控制端口
    sbit buzzer = P3^4;
    
    unsigned char displayData[3]; // 数码管显示数据(小时、分钟、秒)
    unsigned char currentTime[3]; // 当前计时时间(小时、分钟、秒)
    unsigned char targetTime[3];  // 目标计时时间(小时、分钟、秒)
    unsigned char displayIndex = 0; // 数码管显示索引
    bit timerRunning = 0; // 计时器运行状态
    
    // 数码管段选码表
    unsigned char code digitSegments[10] = {
        0x3F, // 0
        0x06, // 1
        0x5B, // 2
        0x4F, // 3
        0x66, // 4
        0x6D, // 5
        0x7D, // 6
        0x07, // 7
        0x7F, // 8
        0x6F  // 9
    };
    
    // 延时函数
    void delay(unsigned int ms) {
        unsigned int i, j;
        for(i = 0; i < ms; i++) {
            for(j = 0; j < 120; j++);
        }
    }
    
    // 数码管位选函数
    void selectDigit(unsigned char digit) {
        digit1 = 1;
        digit2 = 1;
        digit3 = 1;
        switch(digit) {
            case 0: digit1 = 0; break;
            case 1: digit2 = 0; break;
            case 2: digit3 = 0; break;
        }
    }
    
    // 数码管段选函数
    void displayDigit(unsigned char digit, unsigned char data) {
        segmentA = (data & 0x01) ? 1 : 0;
        segmentB = (data & 0x02) ? 1 : 0;
        segmentC = (data & 0x04) ? 1 : 0;
        segmentD = (data & 0x08) ? 1 : 0;
        segmentE = (data & 0x10) ? 1 : 0;
        segmentF = (data & 0x20) ? 1 : 0;
        segmentG = (data & 0x40) ? 1 : 0;
        segmentDP = (data & 0x80) ? 1 : 0;
    }
    
    // 数码管显示函数
    void updateDisplay() {
        selectDigit(displayIndex);
        displayDigit(displayIndex, displayData[displayIndex]);
    }
    
    // 数码管刷新中断服务函数
    void timer0Interrupt() interrupt 1 {
        TH0 = 0x3C;
        TL0 = 0xB0;
        
        if (timerRunning) {
            if (currentTime[0] == 0 && currentTime[1] == 0 && currentTime[2] == 0) {
                buzzer = 1; // 计时时间到了,启动蜂鸣器
                timerRunning = 0; // 停止计时器
            } else {
                if (currentTime[2] > 0) {
                    currentTime[2]--;
                } else {
                    if (currentTime[1] > 0) {
                        currentTime[1]--;
                        currentTime[2] = 59;
                    } else {
                        if (currentTime[0] > 0) {
                            currentTime[0]--;
                            currentTime[1] = 59;
                            currentTime[2] = 59;
                        }
                    }
                }
            }
            
            if (displayIndex == 0) {
                displayData[0] = currentTime[0] / 10;
                displayData[1] = currentTime[0] % 10;
            } else if (displayIndex == 1) {
                displayData[0] = currentTime[1] / 10;
                displayData[1] = currentTime[1] % 10;
            } else if (displayIndex == 2) {
                displayData[0] = currentTime[2] / 10;
                displayData[1] = currentTime[2] % 10;
            }
            
            updateDisplay();
        }
    }
    
    // 按键中断服务函数
    void buttonInterrupt() interrupt 0 {
        if (!startStopButton) { // 启停按键
            if (!timerRunning) {
                timerRunning = 1;
            } else {
                timerRunning = 0;
            }
        }
        
        if (!resetButton) { // 复位按键
            currentTime[0] = 0;
            currentTime[1] = 0;
            currentTime[2] = 0;
            buzzer = 0; // 停止蜂鸣器
        }
        
        if (!toggleButton) { // 切换按键
            displayIndex++;
            if (displayIndex > 2) {
                displayIndex = 0;
            }
        }
        
        if (!incrementButton) { // 递增按键
            if (timerRunning) {
                buzzer = 0; // 停止蜂鸣器
                if (displayIndex == 0) {
                    if (currentTime[0] < 23) {
                        currentTime[0]++;
                    } else {
                        currentTime[0] = 0;
                    }
                } else if (displayIndex == 1) {
                    if (currentTime[1] < 59) {
                        currentTime[1]++;
                    } else {
                        currentTime[1] = 0;
                    }
                } else if (displayIndex == 2) {
                    if (currentTime[2] < 59) {
                        currentTime[2]++;
                    } else {
                        currentTime[2] = 0;
                    }
                }
                
                if (currentTime[0] == targetTime[0] && currentTime[1] == targetTime[1] && currentTime[2] == targetTime[2]) {
                    buzzer = 1; // 计时时间到了,启动蜂鸣器
                    timerRunning = 0; // 停止计时器
                }
            }
        }
        
        delay(50); // 延时去抖动
    }
    
    // 主函数
    void main() {
        TMOD = 0x01; // 设置定时器0为模式1
        TH0 = 0x3C; // 设置定时器0初值,用于定时1ms
        TL0 = 0xB0;
        ET0 = 1; // 允许定时器0中断
        EA = 1; // 允许总中断
        TR0 = 1; // 启动定时器0
        
        EX0 = 1; // 允许外部中断0(按键中断)
        IT0 = 1; // 设置外部中断0为下降沿触发
        
        displayIndex = 0;
        displayData[0] = 0;
        displayData[1] = 0;
        displayData[2] = 0;
        currentTime[0] = 0;
        currentTime[1] = 0;
        currentTime[2] = 0;
        targetTime[0] = 0;
        targetTime[1] = 0;
        targetTime[2] = 10; // 设置目标计时时间为10while (1) {
            if (timerRunning) {
                targetTime[0] = currentTime[0];
                targetTime[1] = currentTime[1];
                targetTime[2] = currentTime[2];
            }
            
            updateDisplay();
        }
    }
    
    
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 6月12日
  • 创建了问题 6月10日

悬赏问题

  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥15 绘制多分类任务的roc曲线时只画出了一类的roc,其它的auc显示为nan
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?