久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 104|回復: 0
打印 上一主題 下一主題
收起左側

單片機計時器程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:1155449 發表于 2025-6-27 10:32 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
#include <reg51.h>

/********************* 硬件定義 *********************/
#define SEG_PORT P0       // 數碼管段碼(共陽極,低電平點亮)
sbit DIG1 = P2^0;        // 位1(小時十位)
sbit DIG2 = P2^1;        // 位2(小時個位)
sbit DIG3 = P2^2;        // 位3(分鐘十位)
sbit DIG4 = P2^3;        // 位4(分鐘個位)

sbit KEY_SET = P3^2;     // 設置鍵(切換模式)
sbit KEY_ADD = P3^3;     // 加時鍵
sbit KEY_SUB = P3^4;     // 減時鍵

sbit BUZZER = P3^6;      // 蜂鳴器(低電平觸發)
#define LED_PORT P1      // 8位LED(低電平點亮)

/********************* 段碼表(共陽極,低電平點亮) *********************/
unsigned char code SEG_CODE[] = {
    0xC0, 0xF9, 0xA4, 0xB0, 0x99,  // 0-4
    0x92, 0x82, 0xF8, 0x80, 0x90,  // 5-9
    0x88, 0x83, 0xC6, 0xA1, 0x86,  // A-D
    0x8E, 0xC1                   // E-F(0xC1含小數點)
};

/********************* 狀態定義 *********************/
#define STATE_NORMAL   0  // 正常模式(顯示時間)
#define STATE_SET_HOUR 1  // 設置小時模式
#define STATE_SET_MIN  2  // 設置分鐘模式
#define STATE_COUNTDOWN 3 // 倒計時模式

/********************* 全局變量 *********************/
unsigned char hour = 0, min = 0;   // 當前時間(設置值/倒計時值)
unsigned char clock_state = STATE_NORMAL; // 當前狀態
unsigned int timer_count = 0;      // 定時器計數(用于1秒觸發)
bit blink_flag = 0;                // 閃爍標志(設置模式下)
bit countdown_running = 0;         // 倒計時運行標志
bit timeout_flag = 0;              // 倒計時結束標志

/********************* 函數聲明 *********************/
void init_system(void);
void display(void);
void scan_keys(void);
void delay_ms(unsigned int ms);

/********************* 主函數 *********************/
void main(void) {
    init_system();
    while(1) {
        scan_keys();   // 按鍵掃描
        display();     // 數碼管顯示
        if (timeout_flag) {  // 倒計時結束:流水燈+蜂鳴器
            static unsigned char led_state = 0;
            LED_PORT = ~(1 << led_state);  // 流水燈(低電平點亮)
            led_state++;
            if (led_state >= 8) led_state = 0;
            
            BUZZER = ~BUZZER;  // 蜂鳴器翻轉(低電平觸發)
            delay_ms(100);     // 控制頻率
        }
    }
}

/********************* 系統初始化 *********************/
void init_system(void) {
    SEG_PORT = 0xFF;          // 段碼全滅
    DIG1 = 1; DIG2 = 1; DIG3 = 1; DIG4 = 1; // 位選全滅(共陽極,高電平截止)
    BUZZER = 1;               // 蜂鳴器初始高電平(關閉)
    LED_PORT = 0xFF;          // LED初始高電平(關閉)
   
    hour = 0; min = 0;
    clock_state = STATE_NORMAL;
    countdown_running = 0;
    timeout_flag = 0;
   
    // 定時器0初始化(50ms中斷,12MHz晶振)
    TMOD = 0x01;
    TH0 = 0x3C;   // 初值:65536 - 50000 = 15536(0x3CB0)
    TL0 = 0xB0;
    ET0 = 1;      // 使能定時器中斷
    EA = 1;       // 開總中斷
    TR0 = 1;      // 啟動定時器
}

/********************* 定時器0中斷服務(1秒觸發邏輯) *********************/
void Timer0_ISR(void) interrupt 1 {
    TH0 = 0x3C;   // 重裝載初值
    TL0 = 0xB0;
    timer_count++;
   
    if (timer_count >= 20) {  // 50ms×20=1秒
        timer_count = 0;
        blink_flag = ~blink_flag;  // 閃爍標志翻轉(設置模式下用)
        
        if (clock_state == STATE_COUNTDOWN && countdown_running) {
            if (hour > 0 || min > 0) {  // 倒計時未結束
                if (min == 0) {         // 分鐘為0,小時減1,分鐘置59
                    hour--;
                    min = 59;
                } else {                // 分鐘減1
                    min--;
                }
            } else {                    // 倒計時結束
                countdown_running = 0;
                timeout_flag = 1;
                hour = 0; min = 0;     // 顯示00:00
            }
        }
    }
}

/********************* 數碼管動態掃描顯示 *********************/
void display(void) {
    unsigned char seg_data;
   
    // 消隱所有位(避免殘影)
    DIG1 = 1; DIG2 = 1; DIG3 = 1; DIG4 = 1;
    SEG_PORT = 0xFF;
    delay_ms(1);
   
    // 顯示小時十位
    DIG1 = 0;
    seg_data = SEG_CODE[hour / 10];
    if (clock_state == STATE_SET_HOUR && blink_flag) {
        seg_data &= 0x7F;  // 設置模式下,小時位閃爍(小數點亮)
    }
    SEG_PORT = seg_data;
    delay_ms(2);
    DIG1 = 1;
   
    // 顯示小時個位
    DIG2 = 0;
    seg_data = SEG_CODE[hour % 10];
    if (clock_state == STATE_SET_HOUR && blink_flag) {
        seg_data &= 0x7F;
    }
    SEG_PORT = seg_data;
    delay_ms(2);
    DIG2 = 1;
   
    // 顯示分鐘十位
    DIG3 = 0;
    seg_data = SEG_CODE[min / 10];
    if (clock_state == STATE_SET_MIN && blink_flag) {
        seg_data &= 0x7F;  // 設置模式下,分鐘位閃爍(小數點亮)
    }
    SEG_PORT = seg_data;
    delay_ms(2);
    DIG3 = 1;
   
    // 顯示分鐘個位
    DIG4 = 0;
    seg_data = SEG_CODE[min % 10];
    if (clock_state == STATE_SET_MIN && blink_flag) {
        seg_data &= 0x7F;
    }
    SEG_PORT = seg_data;
    delay_ms(2);
    DIG4 = 1;
}

/********************* 按鍵掃描(消抖+功能處理) *********************/
void scan_keys(void) {
    static unsigned char key_debounce = 0;  // 消抖計數器
    static unsigned char key_set_step = 0;  // 設置模式切換步驟
   
    if (key_debounce > 0) {
        key_debounce--;
        return;
    }
   
    // 處理設置鍵(切換模式)
    if (KEY_SET == 0) {
        key_debounce = 10;  // 消抖
        key_set_step++;
        if (key_set_step == 1) {
            clock_state = STATE_SET_HOUR;  // 進入設置小時
        } else if (key_set_step == 2) {
            clock_state = STATE_SET_MIN;   // 進入設置分鐘
        } else if (key_set_step >= 3) {
            key_set_step = 3;
            clock_state = STATE_COUNTDOWN; // 進入倒計時
            countdown_running = 1;         // 啟動倒計時
        }
    }
   
    // 處理加時鍵(設置模式下)
    if (KEY_ADD == 0 && clock_state != STATE_NORMAL) {
        key_debounce = 10;
        if (clock_state == STATE_SET_HOUR) {
            hour++;
            if (hour >= 24) hour = 0;
        } else if (clock_state == STATE_SET_MIN) {
            min++;
            if (min >= 60) min = 0;
        }
    }
   
    // 處理減時鍵(設置模式下)
    if (KEY_SUB == 0 && clock_state != STATE_NORMAL) {
        key_debounce = 10;
        if (clock_state == STATE_SET_HOUR) {
            if (hour == 0) hour = 23;
            else hour--;
        } else if (clock_state == STATE_SET_MIN) {
            if (min == 0) min = 59;
            else min--;
        }
    }
}

/********************* 毫秒延時函數 *********************/
void delay_ms(unsigned int ms) {
    unsigned int i, j;
    for(i = 0; i < ms; i++)
        for(j = 0; j < 110; j++);  // 12MHz晶振下,約1ms延時
}
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: av网站在线免费观看 | 成人在线观看免费 | 搞黄网站在线观看 | 日本在线小视频 | 97在线观视频免费观看 | 91精品久久久久久久久 | 国产精品免费大片 | 亚洲色图网址 | 午夜精品久久久久久久久久久久久 | 成人精品福利 | 91视频一区二区 | 欧美区日韩区 | 久久99精品国产99久久6男男 | 日韩欧美黄色 | 91久久国产综合久久91精品网站 | 国产真实乱对白精彩久久小说 | 欧美日韩中文字幕在线 | av色在线 | 91国产在线视频在线 | 欧美aⅴ片| 在线毛片网 | 欧美亚洲国产精品 | 四虎永久影院 | 日韩久久久久久 | 男女免费在线观看视频 | 91伦理片| 中文字幕av一区二区三区 | 亚洲网站在线 | 国产成在线观看免费视频 | 精品国产伦一区二区三区观看体验 | 99成人精品 | 欧美日韩综合一区 | 国产91视频播放 | 午夜免费在线 | 国产高清自拍视频在线观看 | 九一在线观看 | 男人的天堂中文字幕 | 亚洲一区二区三区四区五区中文 | 一区二区不卡高清 | 中国人pornoxxx麻豆 | 91操操操 |