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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4125|回復: 1
收起左側

4x4鍵盤、數碼管顯示、數組應用等練習

[復制鏈接]
ID:75246 發表于 2015-3-28 15:38 | 顯示全部樓層 |閱讀模式
//程序名稱:簡單加法
//用于練習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://www.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;
    }
}

回復

使用道具 舉報

ID:82493 發表于 2015-6-15 19:14 | 顯示全部樓層
不錯,值得借鑒一下
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品99久久久久久动医院 | 国产视频1 | 亚洲成人精品在线观看 | 国产99久久久国产精品 | 欧美午夜精品 | 国产精品美女久久久 | 国产欧美精品 | www.亚洲.com | 91麻豆精品一区二区三区 | 亚洲欧洲精品成人久久奇米网 | 最近日韩中文字幕 | 视频在线一区 | 国家一级黄色片 | 男人天堂视频在线观看 | 中文字幕在线一区 | 一区二区视频 | 精品欧美一区二区久久久伦 | h在线播放| 亚洲二区在线 | 天天看片天天干 | 国产日韩精品在线 | 黄色片网站在线观看 | 精品久久精品 | 欧美一区二区三区视频在线 | 国产精品免费视频一区 | 精品欧美一区二区三区久久久小说 | 亚洲毛片在线观看 | 一区二区三区亚洲 | 久草在线在线精品观看 | 国产精品久久国产精品 | 午夜欧美| 99精品免费 | 高清成人免费视频 | 亚洲成人精品在线观看 | 久久99精品久久久久久噜噜 | 亚洲每日更新 | 免费一级欧美在线观看视频 | 国产精品久久久久一区二区三区 | 国产精彩视频 | 国产一区二区在线观看视频 | 久国产视频 |