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

標題: 4x4鍵盤、數碼管顯示、數組應用等練習 [打印本頁]

作者: mabaoguang    時間: 2015-3-28 15:38
標題: 4x4鍵盤、數碼管顯示、數組應用等練習
//程序名稱:簡單加法
//用于練習4x4鍵盤、數碼管顯示、數組應用等
//4x4軟鍵盤布局
//        1 2 3 A
//        4 5 6 B
//        7 8 9 C
//        * 0 # D
//  程序中A加號,#回車,*ESC清零
//  數碼管接P0、P2^4-P2^7
//  鍵盤接P1
//改編自 http://m.zg4o1577.cn/bbs/dpj-20218-1.html
//              1.3.6 包含綜合應用的實用程序


#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
};   //數碼管真值表
const unsigned char code KeyCodeMap[4][4] = { //矩陣按鍵編號到PC標準鍵盤鍵碼的映射表
    { 0x1B, '0', 0x0D, 0x27 },  //數字鍵0、ESC鍵、  回車鍵、 向右鍵
    { '7',  '8',  '9', 0x28 },  //數字鍵7、數字鍵8、數字鍵9、向下鍵
    { '4',  '5',  '6', 0x25 },  //數字鍵4、數字鍵5、數字鍵6、向左鍵
        { '1',  '2',  '3', 0x26 }   //數字鍵1、數字鍵2、數字鍵3、向上鍵

};
unsigned char KeySta[4][4] = {  //全部矩陣按鍵的當前狀態
    {1, 1, 1, 1},
    {1, 1, 1, 1},
    {1, 1, 1, 1},
    {1, 1, 1, 1}
};           //由于數組不能定義成bit型,這里定義成unsigned char型
unsigned char LedBuf[6] = {    //數碼管動態掃描顯示緩沖區
    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}
    };

    //選擇數碼管進行顯示
    P0 = 0xFF;
    ADDR3 = 1;
    ENLED = 0;

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

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

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

    if ((keycode>='0') && (keycode<='9'))  //輸入0-9的數字
    {
        addend = (addend*10) + (keycode-'0'); //原數據擴大10倍,由新輸入的數字填充其個位
        DisplayNum(addend);    //運算結果顯示到數碼管
    }
    else if (keycode == 0x26)  //向上鍵A用作加號,執行加法或連加運算
    {
        result += addend;      //進行加法運算
        addend = 0;
        DisplayNum(result);    //運算結果顯示到數碼管
    }
    else if (keycode == 0x0D)  //回車鍵#,執行加法運算(實際效果與加號并無區別)
    {
        result += addend;      //進行加法運算
        addend = 0;
        DisplayNum(result);    //運算結果顯示到數碼管
    }
    else if (keycode == 0x1B)  //Esc鍵*,清零結果
    {
        addend = 0;
        result = 0;
        DisplayNum(addend);    //清零后的加數顯示到數碼管
    }
}

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

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

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

    TH0 = 0xFC;  //溢出后進入中斷重新賦值
    TL0 = 0x67;

    //將一行的4個按鍵值移入緩沖區
    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;

    //消抖后更新按鍵狀態
    for (i=0; i<4; i++)  //每行4個按鍵,所以循環4次
    {
        if ((keybuf[keyout] & 0x0F) == 0x00)
        {   //連續4次掃描值為0,即16ms(4*4ms)內都只檢測到按下狀態時,可認為按鍵已按下
            KeySta[keyout] = 0;
        }
        else if ((keybuf[keyout] & 0x0F) == 0x0F)
        {   //連續4次掃描值為1,即16ms(4*4ms)內都只檢測到彈起狀態時,可認為按鍵已彈起
            KeySta[keyout] = 1;
        }
    }

    //執行下一次的掃描輸出
    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;
    }

    //執行數碼管動態掃描顯示
    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;
    }
}


作者: yangrui    時間: 2015-6-15 19:14
不錯,值得借鑒一下




歡迎光臨 (http://m.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 久久久久成人网 | 欧美性一区二区 | 色综合天天综合网国产成人网 | 中文字幕久久久 | 黄色a毛片 | 成人一区在线观看 | 中文字幕在线网站 | 激情视频一区 | 精品成人在线 | 天天综合久久 | 亚洲第十页 | 免费观看全黄做爰视频 | 成人精品在线观看 | 久久久久久久 | 亚洲成人a v| av免费网站 | 国产免费成人 | 91亚洲精品乱码久久久久久蜜桃 | 九九热只有精品 | 国产黄色片网站 | 久久久久久久99 | 国产麻豆91 | 黑人巨大猛烈捣出白浆 | www视频在线观看网站 | 国产又黄又猛 | 日韩一区在线播放 | 成人国产在线观看 | 亚洲综合三区 | 秋霞午夜伦理 | 国产精品一区一区三区 | 一区两区小视频 | 天天曰天天操 | 国产精品视频久久 | 欧美激情视频一区 | 国产精品久久免费 | 成人福利在线观看 | 日本精品在线视频 | 激情影院在线观看 | www.国产精品 | 日本黄色三级视频 | 成人深夜福利 |