找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5874|回復(fù): 11
收起左側(cè)

51單片機(jī)不同的IO口如何組成類似數(shù)組的形式

[復(fù)制鏈接]
ID:188773 發(fā)表于 2020-4-28 09:22 | 顯示全部樓層 |閱讀模式
現(xiàn)在有12個(gè)IO口作為輸入,接的是自鎖按鍵。程序需要掃描這12個(gè)IO口的高低狀態(tài)來執(zhí)行后續(xù)操作,最簡單的寫法就是定義每個(gè)IO口然后直接去一一掃描。如下代碼:
sbit keyin1 = P3^4;                        //自鎖按鍵,0按下
sbit keyin2 = P3^5;
sbit keyin3 = P3^0;
sbit keyin4 = P3^1;
sbit keyin5 = P3^2;
sbit keyin6 = P3^3;
sbit keyin7 = P2^0;
sbit keyin8 = P2^1;
sbit keyin9 = P2^2;
sbit keyin10 = P2^7;
sbit test   = P3^6;
sbit mute   = P3^7;                        //輕觸按鍵,0按下


void KeyScanf()
{
        if(keyin1==0)                  //按鍵1按下
                 ....
         else            //按鍵1未按下
                 .....

        if(keyin2==0)                  
         ....
         else           
         ......

        if(keyin3==0)                  
                 .....
         else           
                 .....

但是這樣感覺代碼特別冗余,想問問有沒有辦法將keyin1-keyin12放到一個(gè)數(shù)組之類的結(jié)構(gòu)里面,方便進(jìn)行for循環(huán),減少代碼的數(shù)量,如下代碼KEY[]中裝著所有的IO口。
for(n=0;n<13,n++)
                {
                        if(KEY[n]==0)                  //按鍵1按下
                        ....
                        else            //按鍵1未按下
                        .....                               
                }




回復(fù)

使用道具 舉報(bào)

ID:584814 發(fā)表于 2020-4-28 09:41 | 顯示全部樓層
想法灰常地好,你能確定每個(gè)按鍵按下和不按下的功能一樣的話直接并上去就好。
當(dāng)然你也可以做個(gè)函數(shù)模塊,對每個(gè)按鍵進(jìn)行賦值方便調(diào)用。
回復(fù)

使用道具 舉報(bào)

ID:213173 發(fā)表于 2020-4-28 11:12 | 顯示全部樓層
宏定義端口組即可

#include <reg51.h>

#define Merge_key ((P2>>4&0x08)|(P2&0x07))<<8|P3

void main(void)
{
        unsigned int num;
        while(1)
        {
                num=Merge_key;
                if(num!=0x0fff)
                {
                        switch(num)
                        {
                                case 0x0ffe: /*任務(wù) 1*/ break;
                                case 0x0ffd: /*任務(wù) 2*/ break;
                                case 0x0ffb: /*任務(wù) 3*/ break;
                                case 0x0ff7: /*任務(wù) 4*/ break;
                                case 0x0fef: /*任務(wù) 5*/ break;
                                case 0x0fdf: /*任務(wù) 6*/ break;
                                case 0x0fbf: /*任務(wù) 7*/ break;
                                case 0x0f7f: /*任務(wù) 8*/ break;
                                case 0x0eff: /*任務(wù) 9*/ break;
                                case 0x0dff: /*任務(wù)10*/ break;
                                case 0x0bff: /*任務(wù)11*/ break;
                                case 0x07ff: /*任務(wù)12*/ break;
                                //其它N組合    任務(wù)N
                                //......
                                default: break;
                        }       
                }
        }
}
回復(fù)

使用道具 舉報(bào)

ID:188773 發(fā)表于 2020-4-28 14:08 | 顯示全部樓層
man1234567 發(fā)表于 2020-4-28 09:41
想法灰常地好,你能確定每個(gè)按鍵按下和不按下的功能一樣的話直接并上去就好。
當(dāng)然你也可以做個(gè)函數(shù)模塊, ...

好像C51沒有位數(shù)組,所以很疑惑能不能這樣做
回復(fù)

使用道具 舉報(bào)

ID:188773 發(fā)表于 2020-4-28 16:29 | 顯示全部樓層
wulin 發(fā)表于 2020-4-28 11:12
宏定義端口組即可

#include

您這是個(gè)很好的思路,我試試宏定義把不同端口放在一起,但是還是要去檢測每一位,因?yàn)榘存I是自鎖的,可能出現(xiàn)同時(shí)1個(gè)、2個(gè)甚至12個(gè)同時(shí)按下的情況,switch列舉太麻煩了。
回復(fù)

使用道具 舉報(bào)

ID:213173 發(fā)表于 2020-4-28 17:56 | 顯示全部樓層
guan1989 發(fā)表于 2020-4-28 16:29
您這是個(gè)很好的思路,我試試宏定義把不同端口放在一起,但是還是要去檢測每一位,因?yàn)榘存I是自鎖的,可能 ...

可以把鍵態(tài)列一個(gè)unsigned int 數(shù)組用查表法。
回復(fù)

使用道具 舉報(bào)

ID:328014 發(fā)表于 2020-4-28 18:23 | 顯示全部樓層
回復(fù)

使用道具 舉報(bào)

ID:332444 發(fā)表于 2020-4-28 20:30 | 顯示全部樓層
12個(gè)按鍵,用8個(gè)IO口能組成矩陣16個(gè)按鍵。
回復(fù)

使用道具 舉報(bào)

ID:188773 發(fā)表于 2020-4-28 20:58 | 顯示全部樓層
51hei團(tuán)團(tuán) 發(fā)表于 2020-4-28 18:23
類似問題的解決方案:http://www.torrancerestoration.com/bbs/dpj-186076-1.html

位結(jié)構(gòu)體和聯(lián)合體不能用于循環(huán)減少代碼的長度吧?我的初衷是減少代碼長度。
回復(fù)

使用道具 舉報(bào)

ID:188773 發(fā)表于 2020-4-28 22:57 | 顯示全部樓層
這是我修改后的代碼,實(shí)現(xiàn)了十二個(gè)按鍵的循環(huán)掃描,試運(yùn)行了下基本邏輯是對的,希望大家?guī)臀铱纯从惺裁葱枰倪M(jìn)的,初學(xué)者還有很多不懂的。

#include<reg52.h>
#define bitRead(Y,X) ( ~Y & (1 << (X-1)) )                                                   // 讀取 Y 的X位,其他位屏蔽為0,Y的X位為0則X位置為1,否則置位0
#define bitSet(Y,X) Y |= (1 << (X-1))                // Y的X位置1
#define bitClear(Y,X) Y &= ~(1 << (X-1))              // Y的X位置0
#define Merge_key         ((P2>>4&0x08)|(P2&0x07))<<8|P3                 //16位從高位到低位排序位:0 0 0 0 / P2.7        P2.2        P2.1        P2.0        /        P3.7        P3.6        P3.5        P3.4        /        P3.3        P3.2        P3.1        P3.0
/*------------------------------------------------
函數(shù)名稱:  KEY_Initialise()
函數(shù)功能:         按鍵初始化
入口參數(shù):        
出口參數(shù):         無
備 注:
------------------------------------------------*/
uint data key_alarm=0xff; //按鍵按下是否生效標(biāo)志位:LED1,LED2,...lLED10,test,mute,null,null,null,null
uint data key_value=0x00; //實(shí)時(shí)存儲(chǔ)按鍵按下標(biāo)志位:LED1,LED2,LED3...LED10,test,mute,LED_ALARM,buzzer,null,null;用于顯示和通訊

void KEY_Initialise()                         //KEY1-KEY10,TEST,MUTE
        {
        static uint KEY        ;
        static uchar uckey_num ;
        static uint code KEY_transient[]={0x0001,0x0002,0x0004,0x0008,                //P3.0  P3.1  P3.2  P3.3
                                                                                                                         0x0010,0x0020,0x0040,0x080,                //P3.4  P3.5  P3.6  P3.7
                                                                                                                         0x0100,0x0200,0x0400,0x0800};        //P2.0  P2.1  P2.2  P2.7
        static uchar data keytime_Y[12]={0,0,0,0,0,0,0,0,0,0,0,0};//timeY按下計(jì)時(shí)消抖 LED1,LED2,...lLED10,test,mute
        static uchar data keytime_N[12]={0,0,0,0,0,0,0,0,0,0,0,0};//timeN未按下計(jì)時(shí)消抖LED1,LED2,...lLED10,test,mute
        static uchar code Const_Keysnake_time=200;
                                                                                                                         
       
                KEY = Merge_key ;
                if ( KEY != 0X0FFF )
                {
                        for ( uckey_num = 0 ; uckey_num < 13 ; uckey_num ++ )
                        {        uint abc=bitRead ( KEY,uckey_num+1);
                                if ( bitRead ( KEY,uckey_num+1 ) == KEY_transient[uckey_num] )//函數(shù)邏輯不對,需確定
                                {
                                        keytime_Y[uckey_num]++;        //按下消抖計(jì)時(shí)加1
                                        keytime_N[uckey_num]=0;        //未按下消抖計(jì)時(shí)清零       
                                        if(keytime_Y[uckey_num]>Const_Keysnake_time) //消抖濾波 ,受程序循環(huán)影響延時(shí)時(shí)間,需要程序完成后校準(zhǔn)Const_Keysnake_time值
                                                {
                                                keytime_Y[uckey_num]=0;         //按下消抖計(jì)時(shí)清零
                                                bitSet(key_value,uckey_num+1);        //是否按下標(biāo)志位
                                                }
                                        }
                                else            //按鍵1未按下
                                        {
                                        keytime_N[uckey_num]++;                //未按下消抖計(jì)時(shí)加1
                                        keytime_Y[uckey_num]=0;          //按下消抖計(jì)時(shí)清零
                                                if(keytime_N[uckey_num]>Const_Keysnake_time)
                                                {
                                                keytime_N[uckey_num]=0;
                                                bitClear(key_value,uckey_num+1);
                                                }
                                        }
                        }
                }
                }
回復(fù)

使用道具 舉報(bào)

ID:188773 發(fā)表于 2020-4-28 22:58 | 顯示全部樓層
xianfajushi 發(fā)表于 2020-4-28 20:30
12個(gè)按鍵,用8個(gè)IO口能組成矩陣16個(gè)按鍵。

我的是自鎖按鍵,矩陣按鍵在同時(shí)按下時(shí)偵測不了吧
回復(fù)

使用道具 舉報(bào)

ID:188773 發(fā)表于 2020-4-28 22:59 | 顯示全部樓層
wulin 發(fā)表于 2020-4-28 17:56
可以把鍵態(tài)列一個(gè)unsigned int 數(shù)組用查表法。

我按這個(gè)思路寫了個(gè),能否幫我看下有沒有什么要改的(代碼規(guī)范,標(biāo)準(zhǔn),邏輯都可以)
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

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