找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 1436|回復(fù): 5
打印 上一主題 下一主題
收起左側(cè)

如何把宋老師四個(gè)獨(dú)立按鍵單片機(jī)程序改為8個(gè)獨(dú)立按鍵程序?

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:82738 發(fā)表于 2021-10-12 10:46 來自手機(jī) | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
如題,程序在3樓
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:262 發(fā)表于 2021-10-12 16:01 | 只看該作者
程序呢?我?guī)湍阊芯肯?/td>
回復(fù)

使用道具 舉報(bào)

板凳
ID:82738 發(fā)表于 2021-10-14 21:14 來自手機(jī) | 只看該作者
#include <reg52.h>
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;
sbit KEY1 = P2^4;
sbit KEY2 = P2^5;
sbit KEY3 = P2^6;
sbit KEY4 = P2^7;
unsigned char code LedChar[] = { //數(shù)碼管顯示字符轉(zhuǎn)換表
    0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
    0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};
unsigned char LedBuff[6] = { //數(shù)碼管顯示緩沖區(qū)
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
unsigned char KeySta[4] = { //按鍵當(dāng)前狀態(tài)
    1, 1, 1, 1
};
bit StopwatchRunning = 0; //秒表運(yùn)行標(biāo)志
bit StopwatchRefresh = 1; //秒表計(jì)數(shù)刷新標(biāo)志
unsigned char DecimalPart = 0; //秒表的小數(shù)部分
unsigned int IntegerPart = 0; //秒表的整數(shù)部分
unsigned char T0RH = 0; //T0 重載值的高字節(jié)
unsigned char T0RL = 0; //T0 重載值的低字節(jié)
void ConfigTimer0(unsigned int ms);
void StopwatchDisplay();
void KeyDriver();
void main(){
    EA = 1;  //開總中斷
    ENLED = 0;  //使能選擇數(shù)碼管
    ADDR3 = 1;
    P2 = 0xFE; //P2.0 置 0,選擇第 4 行按鍵作為獨(dú)立按鍵
    ConfigTimer0(2); //配置 T0 定時(shí) 2ms
    while (1){
        if (StopwatchRefresh){ //需要刷新秒表示數(shù)時(shí)調(diào)用顯示函數(shù)
            StopwatchRefresh = 0;
            StopwatchDisplay();
        }
        KeyDriver(); //調(diào)用按鍵驅(qū)動(dòng)函數(shù)
    }
}
/* 配置并啟動(dòng) T0,ms-T0 定時(shí)時(shí)間 */
void ConfigTimer0(unsigned int ms){
    unsigned long tmp; //臨時(shí)變量
    tmp = 11059200 / 12; //定時(shí)器計(jì)數(shù)頻率
    tmp = (tmp * ms) / 1000; //計(jì)算所需的計(jì)數(shù)值
    tmp = 65536 - tmp;  //計(jì)算定時(shí)器重載值
    tmp = tmp + 18; //補(bǔ)償中斷響應(yīng)延時(shí)造成的誤差
    T0RH = (unsigned char)(tmp>>8); //定時(shí)器重載值拆分為高低字節(jié)
    T0RL = (unsigned char)tmp;
    TMOD &= 0xF0; //清零 T0 的控制位
    TMOD |= 0x01; //配置 T0 為模式 1
    TH0 = T0RH; //加載 T0 重載值
    TL0 = T0RL;
    ET0 = 1; //使能 T0 中斷
    TR0 = 1; //啟動(dòng) T0
}
/* 秒表計(jì)數(shù)顯示函數(shù) */
void StopwatchDisplay(){
    signed char i;
    unsigned char buf[4]; //數(shù)據(jù)轉(zhuǎn)換的緩沖區(qū)
    //小數(shù)部分轉(zhuǎn)換到低 2 位
    LedBuff[0] = LedChar[DecimalPart%10];
    LedBuff[1] = LedChar[DecimalPart/10];
    //整數(shù)部分轉(zhuǎn)換到高 4 位
    buf[0] = IntegerPart%10;
    buf[1] = (IntegerPart/10)%10;
    buf[2] = (IntegerPart/100)%10;
    buf[3] = (IntegerPart/1000)%10;
    for (i=3; i>=1; i--){ //整數(shù)部分高位的 0 轉(zhuǎn)換為空字符
        if (buf[i] == 0){
            LedBuff[i+2] = 0xFF;
        }else{
            break;   
        }
    }
    for ( ; i>=0; i--){ //有效數(shù)字位轉(zhuǎn)換為顯示字符
        LedBuff[i+2] = LedChar[buf[i]];
    }
    LedBuff[2] &= 0x7F; //點(diǎn)亮小數(shù)點(diǎn)
}
/* 秒表啟停函數(shù) */
void StopwatchAction(){
    if (StopwatchRunning){ //已啟動(dòng)則停止
        StopwatchRunning = 0;
    }else{  //未啟動(dòng)則啟動(dòng)
        StopwatchRunning = 1;
    }
}
/* 秒表復(fù)位函數(shù) */
void StopwatchReset(){
    StopwatchRunning = 0; //停止秒表
    DecimalPart = 0; //清零計(jì)數(shù)值
    IntegerPart = 0;
    StopwatchRefresh = 1; //置刷新標(biāo)志
}
/* 按鍵驅(qū)動(dòng)函數(shù),檢測(cè)按鍵動(dòng)作,調(diào)度相應(yīng)動(dòng)作函數(shù),需在主循環(huán)中調(diào)用 */
void KeyDriver(){
    unsigned char i;
    static unsigned char backup[4] = {1,1,1,1};
   
    for (i=0; i<4; i++){ //循環(huán)檢測(cè) 4 個(gè)按鍵
        if (backup[i] != KeySta[i]){ //檢測(cè)按鍵動(dòng)作
            if (backup[i] != 0){ //按鍵按下時(shí)執(zhí)行動(dòng)作
                if (i == 1){ //Esc 鍵復(fù)位秒表
                    StopwatchReset();
                }else if (i == 2){//回車鍵啟停秒表
                    StopwatchAction();
                }
            }
            backup[i] = KeySta[i]; //刷新前一次的備份值
        }
    }
}
/* 按鍵掃描函數(shù),需在定時(shí)中斷中調(diào)用 */
void KeyScan(){
    unsigned char i;
    static unsigned char keybuf[4] = { //按鍵掃描緩沖區(qū)
        0xFF, 0xFF, 0xFF, 0xFF
    };
   
    //按鍵值移入緩沖區(qū)
    keybuf[0] = (keybuf[0] << 1) | KEY1;
    keybuf[1] = (keybuf[1] << 1) | KEY2;
    keybuf[2] = (keybuf[2] << 1) | KEY3;
    keybuf[3] = (keybuf[3] << 1) | KEY4;
    //消抖后更新按鍵狀態(tài)
    for (i=0; i<4; i++){
        if (keybuf[i] == 0x00){
            //連續(xù) 8 次掃描值為 0,即 16ms 內(nèi)都是按下狀態(tài)時(shí),可認(rèn)為按鍵已穩(wěn)定的按下
            KeySta[i] = 0;
        }else if (keybuf[i] == 0xFF){
            //連續(xù) 8 次掃描值為 1,即 16ms 內(nèi)都是彈起狀態(tài)時(shí),可認(rèn)為按鍵已穩(wěn)定的彈起
            KeySta[i] = 1;
        }
    }
}
/* 數(shù)碼管動(dòng)態(tài)掃描刷新函數(shù),需在定時(shí)中斷中調(diào)用 */
void LedScan(){
    static unsigned char i = 0; //動(dòng)態(tài)掃描索引
    P0 = 0xFF; //關(guān)閉所有段選位,顯示消隱
    P1 = (P1 & 0xF8) | i; //位選索引值賦值到 P1 口低 3 位
    P0 = LedBuff[i]; //緩沖區(qū)中索引位置的數(shù)據(jù)送到 P0 口
    if (i < 5){ //索引遞增循環(huán),遍歷整個(gè)緩沖區(qū)
        i++;
    }else{
        i = 0;
    }
}
/* 秒表計(jì)數(shù)函數(shù),每隔 10ms 調(diào)用一次進(jìn)行秒表計(jì)數(shù)累加 */
void StopwatchCount(){
    if (StopwatchRunning){ //當(dāng)處于運(yùn)行狀態(tài)時(shí)遞增計(jì)數(shù)值
        DecimalPart++; //小數(shù)部分+1
        if (DecimalPart >= 100){ //小數(shù)部分計(jì)到 100 時(shí)進(jìn)位到整數(shù)部分
            DecimalPart = 0;
            IntegerPart++; //整數(shù)部分+1
            if (IntegerPart >= 10000){ //整數(shù)部分計(jì)到 10000 時(shí)歸零
                IntegerPart = 0;
            }
        }
        StopwatchRefresh = 1; //設(shè)置秒表計(jì)數(shù)刷新標(biāo)志
    }
}
/* T0 中斷服務(wù)函數(shù),完成數(shù)碼管、按鍵掃描與秒表計(jì)數(shù) */
void InterruptTimer0() interrupt 1{
    static unsigned char tmr10ms = 0;
    TH0 = T0RH; //重新加載重載值
    TL0 = T0RL;
    LedScan(); //數(shù)碼管掃描顯示
    KeyScan(); //按鍵掃描
    //定時(shí) 10ms 進(jìn)行一次秒表計(jì)數(shù)
    tmr10ms++;
    if (tmr10ms >= 5){
        tmr10ms = 0;
        StopwatchCount(); //調(diào)用秒表計(jì)數(shù)函數(shù)
    }
}
回復(fù)

使用道具 舉報(bào)

地板
ID:82738 發(fā)表于 2021-10-14 21:18 來自手機(jī) | 只看該作者
我把數(shù)組改為8,i改為8,按鍵改為8個(gè),最后一個(gè)按鍵key8不起作用是怎么回事?
回復(fù)

使用道具 舉報(bào)

5#
ID:82738 發(fā)表于 2021-10-14 22:37 來自手機(jī) | 只看該作者
這個(gè)程序改為8個(gè)獨(dú)立按解不能實(shí)現(xiàn),最多為7個(gè)按鍵
回復(fù)

使用道具 舉報(bào)

6#
ID:61207 發(fā)表于 2021-10-14 22:51 | 只看該作者
18588278793 發(fā)表于 2021-10-14 21:14
#include
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

改成多少個(gè)獨(dú)立按鍵都可以,問題是你沒有認(rèn)真看宋老師的教程,所以不能實(shí)現(xiàn)
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表