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

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

QQ登錄

只需一步,快速開(kāi)始

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

4x4鍵盤(pán)、數(shù)碼管顯示、數(shù)組應(yīng)用等練習(xí)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:75246 發(fā)表于 2015-3-28 15:38 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
//程序名稱:簡(jiǎn)單加法
//用于練習(xí)4x4鍵盤(pán)、數(shù)碼管顯示、數(shù)組應(yīng)用等
//4x4軟鍵盤(pán)布局
//        1 2 3 A
//        4 5 6 B
//        7 8 9 C
//        * 0 # D
//  程序中A加號(hào),#回車,*ESC清零
//  數(shù)碼管接P0、P2^4-P2^7
//  鍵盤(pán)接P1
//改編自 http://www.zg4o1577.cn/bbs/dpj-20218-1.html
//              1.3.6 包含綜合應(yīng)用的實(shí)用程序


#include <reg52.h>

sbit KEY_IN_1  = P1^4;  //矩陣按鍵的掃描輸入引腳1
sbit KEY_IN_2  = P1^5;  //矩陣按鍵的掃描輸入引腳2
sbit KEY_IN_3  = P1^6;  //矩陣按鍵的掃描輸入引腳3
sbit KEY_IN_4  = P1^7;  //矩陣按鍵的掃描輸入引腳4
sbit KEY_OUT_1 = P1^3;  //矩陣按鍵的掃描輸出引腳1
sbit KEY_OUT_2 = P1^2;  //矩陣按鍵的掃描輸出引腳2
sbit KEY_OUT_3 = P1^1;  //矩陣按鍵的掃描輸出引腳3
sbit KEY_OUT_4 = P1^0;  //矩陣按鍵的掃描輸出引腳4

sbit  ADDR0 = P2^4;
sbit  ADDR1 = P2^5;
sbit  ADDR2 = P2^6;
sbit  ADDR3 = P2^7;
sbit  ENLED = P0;

unsigned char code LedChar[] = {
    0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
    0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8e
};   //數(shù)碼管真值表
const unsigned char code KeyCodeMap[4][4] = { //矩陣按鍵編號(hào)到PC標(biāo)準(zhǔn)鍵盤(pán)鍵碼的映射表
    { 0x1B, '0', 0x0D, 0x27 },  //數(shù)字鍵0、ESC鍵、  回車鍵、 向右鍵
    { '7',  '8',  '9', 0x28 },  //數(shù)字鍵7、數(shù)字鍵8、數(shù)字鍵9、向下鍵
    { '4',  '5',  '6', 0x25 },  //數(shù)字鍵4、數(shù)字鍵5、數(shù)字鍵6、向左鍵
        { '1',  '2',  '3', 0x26 }   //數(shù)字鍵1、數(shù)字鍵2、數(shù)字鍵3、向上鍵

};
unsigned char KeySta[4][4] = {  //全部矩陣按鍵的當(dāng)前狀態(tài)
    {1, 1, 1, 1},
    {1, 1, 1, 1},
    {1, 1, 1, 1},
    {1, 1, 1, 1}
};           //由于數(shù)組不能定義成bit型,這里定義成unsigned char型
unsigned char LedBuf[6] = {    //數(shù)碼管動(dòng)態(tài)掃描顯示緩沖區(qū)
    0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};

void DisplayNum(unsigned long num);
void KeyAction(unsigned char keycode);

void main(void)
{
    unsigned char i, j;
    unsigned char backup[4][4] = {  //按鍵值備份,保存前一次的值
        {1, 1, 1, 1},
        {1, 1, 1, 1},
        {1, 1, 1, 1},
        {1, 1, 1, 1}
    };

    //選擇數(shù)碼管進(jìn)行顯示
    P0 = 0xFF;
    ADDR3 = 1;
    ENLED = 0;

    //配置T0工作在模式1,定時(shí)1ms
    TMOD = 0x01;
    TH0 = 0xFC;
    TL0 = 0x67;
    TR0 = 1;
    ET0 = 1;
    EA = 1;

    while(1)
    {
        //檢索按鍵狀態(tài)的變化
        for (i=0; i<4; i++)
        {
            for (j=0; j<4; j++)
            {
                if (backup[j] != KeySta[j])
                {
                    if (backup[j] == 0)  //按鍵彈起時(shí)執(zhí)行動(dòng)作
                    {
                        KeyAction(KeyCodeMap[j]);
                    }
                    backup[j] = KeySta[j];
                }
            }
        }
    }
}

void KeyAction(unsigned char keycode)
{
    static unsigned long result = 0;  //用于保存運(yùn)算結(jié)果
    static unsigned long addend = 0;  //用于保存輸入的加數(shù)

    if ((keycode>='0') && (keycode<='9'))  //輸入0-9的數(shù)字
    {
        addend = (addend*10) + (keycode-'0'); //原數(shù)據(jù)擴(kuò)大10倍,由新輸入的數(shù)字填充其個(gè)位
        DisplayNum(addend);    //運(yùn)算結(jié)果顯示到數(shù)碼管
    }
    else if (keycode == 0x26)  //向上鍵A用作加號(hào),執(zhí)行加法或連加運(yùn)算
    {
        result += addend;      //進(jìn)行加法運(yùn)算
        addend = 0;
        DisplayNum(result);    //運(yùn)算結(jié)果顯示到數(shù)碼管
    }
    else if (keycode == 0x0D)  //回車鍵#,執(zhí)行加法運(yùn)算(實(shí)際效果與加號(hào)并無(wú)區(qū)別)
    {
        result += addend;      //進(jìn)行加法運(yùn)算
        addend = 0;
        DisplayNum(result);    //運(yùn)算結(jié)果顯示到數(shù)碼管
    }
    else if (keycode == 0x1B)  //Esc鍵*,清零結(jié)果
    {
        addend = 0;
        result = 0;
        DisplayNum(addend);    //清零后的加數(shù)顯示到數(shù)碼管
    }
}

void DisplayNum(unsigned long num)
{
    signed char i;
    unsigned char buf[4];

    for (i=0; i<4; i++)   //把長(zhǎng)整型數(shù)轉(zhuǎn)換為4位十進(jìn)制的數(shù)組
    {
        buf = num % 10;
        num /= 10;
    }
    for (i=3; i>=1; i--)  //從最高位起,遇到0即轉(zhuǎn)換為空格,遇到非0即退出
    {
        if (buf == 0)
        {
            LedBuf = 0xFF;
        }
        else
        {
            break;
        }
    }
    for ( ; i>=0; i--)    //剩余低位都如實(shí)轉(zhuǎn)換為數(shù)字
    {
        LedBuf = LedChar[buf];
    }
}

void InterruptTimer0() interrupt 1
{
    unsigned char i;
    static unsigned char ledcnt = 0;  //數(shù)碼管掃描計(jì)數(shù)器
    static unsigned char keyout = 0;  //矩陣按鍵掃描輸出計(jì)數(shù)器
    static unsigned char keybuf[4][4] = {  //按鍵掃描緩沖區(qū),保存一段時(shí)間內(nèi)的掃描值
        {0xFF, 0xFF, 0xFF, 0xFF},
        {0xFF, 0xFF, 0xFF, 0xFF},
        {0xFF, 0xFF, 0xFF, 0xFF},
        {0xFF, 0xFF, 0xFF, 0xFF}
    };

    TH0 = 0xFC;  //溢出后進(jìn)入中斷重新賦值
    TL0 = 0x67;

    //將一行的4個(gè)按鍵值移入緩沖區(qū)
    keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1;
    keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2;
    keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3;
    keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4;

    //消抖后更新按鍵狀態(tài)
    for (i=0; i<4; i++)  //每行4個(gè)按鍵,所以循環(huán)4次
    {
        if ((keybuf[keyout] & 0x0F) == 0x00)
        {   //連續(xù)4次掃描值為0,即16ms(4*4ms)內(nèi)都只檢測(cè)到按下?tīng)顟B(tài)時(shí),可認(rèn)為按鍵已按下
            KeySta[keyout] = 0;
        }
        else if ((keybuf[keyout] & 0x0F) == 0x0F)
        {   //連續(xù)4次掃描值為1,即16ms(4*4ms)內(nèi)都只檢測(cè)到彈起狀態(tài)時(shí),可認(rèn)為按鍵已彈起
            KeySta[keyout] = 1;
        }
    }

    //執(zhí)行下一次的掃描輸出
    keyout++;
    keyout &= 0x03;
    switch (keyout)
    {
        case 0:
            KEY_OUT_4 = 1;
            KEY_OUT_1 = 0;
            break;
        case 1:
            KEY_OUT_1 = 1;
            KEY_OUT_2 = 0;
            break;
        case 2:
            KEY_OUT_2 = 1;
            KEY_OUT_3 = 0;
            break;
        case 3:
            KEY_OUT_3 = 1;
            KEY_OUT_4 = 0;
            break;
        default:
            break;
    }

    //執(zhí)行數(shù)碼管動(dòng)態(tài)掃描顯示
    P0 = 0xFF;
    switch (ledcnt)
    {
                case 0: ADDR0=0; ADDR1=1; ADDR2=1; ADDR3=1; break;
                case 1: ADDR0=1; ADDR1=0; ADDR2=1; ADDR3=1; break;
                case 2: ADDR0=1; ADDR1=1; ADDR2=0; ADDR3=1; break;
                case 3: ADDR0=1; ADDR1=1; ADDR2=1; ADDR3=0; break;
                case 4: ADDR0=1; ADDR1=1; ADDR2=1; ADDR3=1; break;
        default: break;
    }
    P0 = LedBuf[ledcnt];
    ledcnt++;
    if (ledcnt >= 5)
    {
        ledcnt = 0;
    }
}

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:82493 發(fā)表于 2015-6-15 19:14 | 只看該作者
不錯(cuò),值得借鑒一下
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 成人婷婷| 一区二区不卡 | 婷婷五月色综合香五月 | 国产一区二区三区在线 | 在线成人| 6080亚洲精品一区二区 | 欧美在线视频观看 | 亚洲精品亚洲人成人网 | 精品av| 91性高湖久久久久久久久_久久99 | 不卡一区二区三区四区 | 国产精品一区二区在线观看 | 黄网站涩免费蜜桃网站 | 99精品国产一区二区三区 | 久久一区二区精品 | 国产午夜高清 | 看黄在线 | 欧美成人一区二区三区片免费 | av网站免费在线观看 | 91精品国产综合久久久久久 | 久久久久亚洲 | 国产成人福利视频在线观看 | 日韩在线一区视频 | 中文字幕成人av | 在线一区视频 | 天天躁日日躁狠狠躁2018小说 | 午夜影院在线播放 | 色橹橹欧美在线观看视频高清 | 欧美日韩高清免费 | 亚洲精选久久 | 国产福利视频 | xx性欧美肥妇精品久久久久久 | 国产激情网站 | 亚洲国产精品人人爽夜夜爽 | 羞羞色在线观看 | 99久久免费精品国产男女高不卡 | 久久夜视频 | 国产精品高潮呻吟久久久久 | 亚洲看片 | 欧美在线视频一区二区 | 午夜天堂精品久久久久 |