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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2427|回復: 3
收起左側

在書上看到的程序,總感覺它中斷里面的掃描緩存有問題,有興趣的可以看一下

[復制鏈接]
ID:204609 發表于 2017-7-14 15:00 | 顯示全部樓層 |閱讀模式
#include <reg52.h>

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

unsigned char code LedChar[] = {
    0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
    0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8e
};  //數碼管真值表

unsigned char KeySta[4][4] = {  //全部矩陣按鍵的當前狀態,默認都未按下
    {1, 1, 1, 1},      //bit類型不能定義數組,因此定義成unsigned char
    {1, 1, 1, 1},
    {1, 1, 1, 1},
    {1, 1, 1, 1}
};

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;
    ADDR0 = 0;
    ADDR1 = 0;
    ADDR2 = 0;
    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++) //i作為行循環變量
        {
            for (j=0; j<4; j++) //j作為列循環變量
            {
                if (backup[j] != KeySta[j]) //判斷按鍵動作
                {
                    if (backup[j] == 0)   //判斷按鍵彈起
                    {
                        P0 = LedChar[i*4+j]; //執行按鍵動作
                    }
                    backup[j] = KeySta[j]; //更新前一次的值
                }
            }
        }
    }
}

void InterruptTimer0() interrupt 1
{
    unsigned char i;
    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;                                                                                                   按照我們的鍵盤掃描程序應該是中斷1ms鍵值賦值一次并賦值
                                         左移4次則keyout加1轉下一列重新掃描16ms掃描完成。而此
                                         程序我發現中斷1ms雖然會有鍵值輸入緩存但他會輸入一次
                                      keyout就增加一次達不到我們所涉及的效果嗎。或許我分析的
                                        不對,就請各位看一下

    //將一行的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;  //用跟0x03做“與”的方式,實現加到4即歸零,是不是很巧妙,學會它吧
    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;
    }
}


回復

使用道具 舉報

ID:213173 發表于 2017-7-14 17:08 | 顯示全部樓層
這是哪本誤人子弟的書,這個例程不值得研究,給你推薦一個例程,程序很簡單,一眼看明白:
#include <reg52.h>                                                 //頭文件
#define uchar unsigned char                         //宏定義
#define uint unsigned int                                 //宏定義
uchar key=0;                                                        //鍵值變量

void key_scan()                                                        //矩陣鍵盤掃描函數
{
        uchar temp1,temp2,temp3;                        //臨時變量
        static bit sign=0;                                        //按鍵自鎖標志
        static uchar count=0;                                //消抖計數變量
        P3=0xf0;                                                        //先給P3賦一個初值
        if(P3!=0xf0)                                                 //判斷P3不等于所賦初值,說明有健按下
        {
                if(sign==0)                                                //如果按鍵自鎖標志為0
                {
                        count++;                                        //消抖計數
                        if(count>=100)                                //消抖計數自>=100,估算主循環周期調整
                        {                                                        //摒棄Delay延時方式,
                                count=100;                                //防止溢出
                                sign=1;                                        //按鍵自鎖標志置1,鍵不抬起,按其他鍵無效
                                temp1=P3;                                //temp1保存高4位變化
                                P3=0x0f;                                //再給P3賦值0x0f
                                temp2=P3;                                //temp2保存低4位變化
                                temp3=temp2|temp1;                //temp3=高4位+低4位
                                key=temp3;                                //保存鍵值
                        }
                }
        }
        else                                                                 //按鍵抬起
        {
                sign=0;                                                        //按鍵自鎖標志清0
                count=0;                                                //消抖計數清0
        }
}

void main()
{
        while(1)
        {
                key_scan();                                                //鍵盤掃描
                P1=key;                                                        //LED低電平亮顯示鍵值
        }                                                                               
}
回復

使用道具 舉報

ID:471066 發表于 2019-2-7 15:21 | 顯示全部樓層
同感,最不喜歡將那些變量名定的又臭又長的

評分

參與人數 7黑幣 +182 收起 理由
jinsheng7533967 + 35
zhengchong60 + 15
站著說話不腰疼 + 12
sheng7533967 + 15
shuisheng60 + 35
刀刀見紅 + 35
yoxi + 35

查看全部評分

回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 岛国毛片在线观看 | 欧美国产精品一区二区三区 | 97成人在线| 国产成人jvid在线播放 | 中文字幕一区在线观看视频 | 91私密视频 | 污视频在线免费观看 | 日韩一区二区三区在线 | 亚洲va中文字幕 | 欧美日韩综合 | 国产精品久久久久aaaa九色 | 国产精品性做久久久久久 | 人人干人人玩 | 亚洲成av人片在线观看 | 韩国电影久久 | 夜夜爽99久久国产综合精品女不卡 | 日韩不卡视频在线 | 欧美一区二区在线播放 | 久久精品欧美一区二区三区不卡 | 999精品在线| 中文字幕91av | 国产视频久久 | www.久久 | 久久精品99 | 亚洲成人精品国产 | 亚洲一区二区不卡在线观看 | 欧美一区二区三区视频 | 国产一区二区激情视频 | 国产精品久久一区二区三区 | 亚洲精品乱码久久久久久9色 | 成人午夜电影在线观看 | 国产99久久精品一区二区300 | 一区二区视频在线 | 国产精品视频网 | 天天干天天爱天天 | 成人无遮挡毛片免费看 | 亚洲国产欧美日韩 | 午夜影院中文字幕 | 亚洲色图第一页 | 欧美一级二级视频 | 黄色在线免费观看视频网站 |