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

QQ登錄

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

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

四位二進(jìn)制如何取16個(gè)鍵值?附51單片機(jī)程序

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:76027 發(fā)表于 2024-5-2 10:01 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
請(qǐng)教各位大佬,四位二進(jìn)制如何取16個(gè)鍵值。用的是STC8H1K08的MCU,P1口設(shè)置為準(zhǔn)雙向口。

單片機(jī)源程序如下:
sbit d0 = P1^2;
sbit d1 = P1^3;
sbit d2 = P1^4;
sbit d3 = P1^5;
unsigned char MatrixKey()

{        unsigned char k=0;

  if(d0==1 && d1==0 &&d2==0 && d3==0) k=1;

         else if(d0==0 && d1==1 && d2==0 && d3==0) k=2;

        else if(d0==1 && d1==1 && d2==0 && d3==0) k=3;

        else if(d0==0 && d1==0 && d2==0 && d3==1) k=4;

        else if(d0==1 && d1==0 && d2==1 && d3==0) k=5;

        else if(d0==0 && d1==1 && d2==1 && d3==0) k=6;

        else if(d0==1 && d1==1 && d2==1 && d3==0) k=7;

        else if(d0==0 && d1==0 && d2==0 && d3==1) k=8;

        else if(d0==1 && d1==0 && d2==0 && d3==1) k=9;

        else if(d0==0 && d1==1 && d2==0 && d3==1) k=0;

        else if(d0==1 && d1==1 && d2==0 && d3==1) k='*';

        else if(d0==0 && d1==0 && d2==1 && d3==1) k='#';

        else if(d0==1 && d1==0 && d2==1 && d3==1) k='A';

        else if(d0==0 && d1==1 && d2==1 && d3==1) k='B';

        else if(d0==1 && d1==1 && d2==1 && d3==1) k='C';

        else if(d0==0 && d1==0 && d2==0 && d3==0) k='D';
return k;
}

新手,請(qǐng)各位大佬多多指教!
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:526108 發(fā)表于 2024-5-2 11:01 | 只看該作者
k=P1&0x3C
回復(fù)

使用道具 舉報(bào)

板凳
ID:235200 發(fā)表于 2024-5-2 11:43 | 只看該作者
前面加一個(gè)16至4位二進(jìn)制的編碼電路,不過(guò)這樣電路復(fù)雜了,不如用8個(gè)端口組成行列按鍵,或者用18個(gè)電阻串聯(lián)分壓電路構(gòu)成16級(jí)電壓,用ADC識(shí)別作為16個(gè)按鍵
回復(fù)

使用道具 舉報(bào)

地板
ID:161164 發(fā)表于 2024-5-2 13:13 | 只看該作者
  1. unsigned char MatrixKey()
  2. {
  3.         unsigned char k=0;
  4.         unsigned char Temp = (P1>>2) & 0x0F;
  5.         switch(Temp)
  6.         {
  7.                 case 10:k=0;break;
  8.                 case 11:k='*';break;
  9.                 case 12:k='#';break;
  10.                 case 13:k='A';break;
  11.                 case 14:k='B';break;
  12.                 case 15:k='C';break;
  13.                 case 0:k='D';break;
  14.                 default:k=Temp;break;
  15.         }
  16.         return k;
  17. }
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

5#
ID:624769 發(fā)表于 2024-5-2 13:16 | 只看該作者

unsigned char MatrixKey()
{
        unsigned char k=0;
        switch((P2>>2)&0x0f)
        {
                case        0x01:        k=1;        break;
                case        0x02:        k=2;        break;
                case        0x03:        k=3;        break;
                case        0x08:        k=4;        break;        //我也不知道為什么你會(huì)有兩個(gè)相同的按鍵狀態(tài)
                case        0x05:        k=5;        break;
                case        0x06:        k=6;        break;
                case        0x07:        k=7;        break;
                case        0x08:        k=8;        break;
                case        0x09:        k=9;        break;
                case        0x0A:        k=0;        break;
                case        0x0B:        k='*';        break;
                case        0x0C:        k='#';        break;
                case        0x0D:        k='A';        break;
                case        0x0E:        k='B';        break;
                case        0x0F:        k='C';        break;
                case        0x00:        k='D';        break;
                default:        k=0xff;        break;
        }
        return k;
}
回復(fù)

使用道具 舉報(bào)

6#
ID:76027 發(fā)表于 2024-5-2 14:47 | 只看該作者
csmyldl 發(fā)表于 2024-5-2 11:43
前面加一個(gè)16至4位二進(jìn)制的編碼電路,不過(guò)這樣電路復(fù)雜了,不如用8個(gè)端口組成行列按鍵,或者用18個(gè)電阻串聯(lián) ...

這是一個(gè)DTMF接收輸入的二進(jìn)制碼。
回復(fù)

使用道具 舉報(bào)

7#
ID:76027 發(fā)表于 2024-5-2 14:49 | 只看該作者
188610329 發(fā)表于 2024-5-2 13:16
unsigned char MatrixKey()
{
        unsigned char k=0;

新手,沒(méi)注意,復(fù)制后沒(méi)改過(guò)來(lái)。
回復(fù)

使用道具 舉報(bào)

8#
ID:883242 發(fā)表于 2024-5-2 15:01 | 只看該作者


但是你的數(shù)據(jù)跟DTMF矩陣完全對(duì)不上號(hào)。
回復(fù)

使用道具 舉報(bào)

9#
ID:76027 發(fā)表于 2024-5-2 15:17 | 只看該作者
Hephaestus 發(fā)表于 2024-5-2 15:01
但是你的數(shù)據(jù)跟DTMF矩陣完全對(duì)不上號(hào)。

我這是DTMF解碼芯片MT8870 D1-D3輸出的數(shù)據(jù)
回復(fù)

使用道具 舉報(bào)

10#
ID:76027 發(fā)表于 2024-5-2 15:21 | 只看該作者
這是DTMF的編解碼表
回復(fù)

使用道具 舉報(bào)

11#
ID:1109793 發(fā)表于 2024-5-2 15:29 | 只看該作者
取鍵值的意義是?直接右移2位,不就得電這個(gè)4位的數(shù)據(jù)了嗎?然后該干啥干啥唄
回復(fù)

使用道具 舉報(bào)

12#
ID:76027 發(fā)表于 2024-5-2 15:35 | 只看該作者
unsigned char k=0;
        switch((P2>>2)&0x0f)     K=0,那0的鍵值是不是無(wú)法提取出來(lái)。
回復(fù)

使用道具 舉報(bào)

13#
ID:1109793 發(fā)表于 2024-5-2 16:26 | 只看該作者
bd5fna 發(fā)表于 2024-5-2 15:35
unsigned char k=0;
        switch((P2>>2)&0x0f)     K=0,那0的鍵值是不是無(wú)法提取出來(lái)。

4位不就是最多16個(gè)啊,看樓上的真值表,0也是有用的,很明顯要有一個(gè)別的什么信號(hào)來(lái)確定是不是有按鍵按下去。
回復(fù)

使用道具 舉報(bào)

14#
ID:1119107 發(fā)表于 2024-5-2 16:37 | 只看該作者
是不是按鍵檢測(cè)識(shí)別有問(wèn)題
回復(fù)

使用道具 舉報(bào)

15#
ID:69038 發(fā)表于 2024-5-2 16:42 | 只看該作者
你這個(gè)是在同一個(gè)端口,要取數(shù)簡(jiǎn)直沒(méi)有更方便了!你參考一下:
temp=P1; //讀P1口數(shù)據(jù)值
temp=temp>>2; //數(shù)據(jù)值移位,匹配硬件端口:P1^2345
temp=temp & 0x0f; //屏蔽高4位
temp=“0123456789ABCDEF”[temp];//查表
return (temp); //返回鍵名ASC碼
回復(fù)

使用道具 舉報(bào)

16#
ID:76027 發(fā)表于 2024-5-2 16:49 | 只看該作者
xiaobendan001 發(fā)表于 2024-5-2 16:26
4位不就是最多16個(gè)啊,看樓上的真值表,0也是有用的,很明顯要有一個(gè)別的什么信號(hào)來(lái)確定是不是有按鍵按下 ...

芯片上有一個(gè)STD信號(hào)在有按鍵按下時(shí)產(chǎn)生高電平。
回復(fù)

使用道具 舉報(bào)

17#
ID:69038 發(fā)表于 2024-5-2 17:13 | 只看該作者
bd5fna 發(fā)表于 2024-5-2 16:49
芯片上有一個(gè)STD信號(hào)在有按鍵按下時(shí)產(chǎn)生高電平。

對(duì)啊,標(biāo)準(zhǔn)的DTMF鍵盤是16鍵的。
只有解碼成功,STD才有高電平輸出。
這個(gè)我以前用的很多,用在報(bào)警器上,一個(gè)發(fā),一個(gè)收:
HT-9200.pdf (284.66 KB, 下載次數(shù): 2) DTMF編碼器
HT9170.pdf (111.75 KB, 下載次數(shù): 1) DTMF解碼器


回復(fù)

使用道具 舉報(bào)

18#
ID:332444 發(fā)表于 2024-5-2 17:53 | 只看該作者
按題主思路就是按16進(jìn)制的組合按鍵,不用定義直接讀取組的值即可獲得,很簡(jiǎn)單的,不用寫那么多代碼。8421即1=1按鍵2=2按鍵3=1+2按鍵0就是沒(méi)按鍵15就是所有按鍵。
回復(fù)

使用道具 舉報(bào)

19#
ID:883242 發(fā)表于 2024-5-2 18:51 | 只看該作者
zhuls 發(fā)表于 2024-5-2 16:42
你這個(gè)是在同一個(gè)端口,要取數(shù)簡(jiǎn)直沒(méi)懈獎(jiǎng)懔!你参考一蠑n�
temp=P1; //讀P1口數(shù)據(jù)值
temp=temp>>2; / ...

return("1234567890.#ABCD"[(P1>>2)&0xf]);

就一句話的事情,寫那么多干什么。
回復(fù)

使用道具 舉報(bào)

20#
ID:1109793 發(fā)表于 2024-5-2 19:06 | 只看該作者
Hephaestus 發(fā)表于 2024-5-2 18:51
return("1234567890.#ABCD"[(P1>>2)&0xf]);

就一句話的事情,寫那么多干什么。

精辟,總工就是總工
回復(fù)

使用道具 舉報(bào)

21#
ID:69038 發(fā)表于 2024-5-2 20:57 | 只看該作者
Hephaestus 發(fā)表于 2024-5-2 18:51
return("1234567890.#ABCD"[(P1>>2)&0xf]);

就一句話的事情,寫那么多干什么。

你看的懂,不代表天下人都看的懂
回復(fù)

使用道具 舉報(bào)

22#
ID:624769 發(fā)表于 2024-5-2 23:13 | 只看該作者
zhuls 發(fā)表于 2024-5-2 20:57
你看的懂,不代表天下人都看的懂

確實(shí),就一句話都還能寫錯(cuò)……,還不如人家寫復(fù)雜一點(diǎn)的…… 至少能保證對(duì)。
回復(fù)

使用道具 舉報(bào)

23#
ID:161164 發(fā)表于 2024-5-3 10:25 | 只看該作者
Hephaestus 發(fā)表于 2024-5-2 18:51
return("1234567890.#ABCD"[(P1>>2)&0xf]);

就一句話的事情,寫那么多干什么。

雖然精妙,可惜樓主的0到9不是ASCII
回復(fù)

使用道具 舉報(bào)

24#
ID:76027 發(fā)表于 2024-5-3 10:25 | 只看該作者
請(qǐng)各位大佬再幫忙看看,輸入密碼時(shí)任何鍵都不會(huì)顯示,只有按下確認(rèn)鍵會(huì)顯示錯(cuò)誤(任意鍵做確認(rèn)鍵都會(huì)顯示錯(cuò)誤),這可以確定按鍵解碼是成功的。#include <STC8.H>//#include <string.h>
//#include <EEPROM.h>
#include <LCD1602.h>
#define     MAIN_Fosc       24000000L   //定義主時(shí)鐘

sbit ALAM = P3^4;                //報(bào)警       
sbit KEY = P3^2;                //開(kāi)鎖
//sbit dtmf_ok = P1^1; //雙音頻接收
sbit d0 = P1^2;
sbit d1 = P1^3;
sbit d2 = P1^4;
sbit d3 = P1^5;

unsigned char KeyNum,Count=0;
unsigned int Password=0;

unsigned char code initpassword[4]={5,6,7,8};                      //初始密碼

/***************************************************************************
函數(shù): unsigned char MatrixKey()
描述: dtmf取值函數(shù)
參數(shù): 將DTMF解碼數(shù)據(jù)編碼為數(shù)值
返回: K
版本: VER1.0
日期: 2024-4-23
備注:
***************************************************************************/

unsigned char MatrixKey()
{
          unsigned char k=0;
        switch((P1>>2)&0x0f)
        {
                case        0x01:        k=1;        break;
                case        0x02:        k=2;        break;
                case        0x03:        k=3;        break;
                case        0x04:        k=4;        break;        
                case        0x05:        k=5;        break;
                case        0x06:        k=6;        break;
                case        0x07:        k=7;        break;
                case        0x08:        k=8;        break;
                case        0x09:        k=9;        break;
                case        0x0A:        k=0;        break;
                case        0x0B:        k='*';        break;
                case        0x0C:        k='#';        break;
                case        0x0D:        k='A';        break;
                case        0x0E:        k='B';        break;
                case        0x0F:        k='C';        break;
                case        0x00:        k='D';        break;
                default:        k=0xff;        break;
        }
        return k;
       
}

void main()
{
        P1M0 &= ~0x3f;
        P1M1 &= ~0x3f;
        P3M0 &= ~0xfc;
        P3M1 &= ~0xfc;
  //P1=0xff;
        LCD_Init();
        LCD_ShowString(1,1,"Password:");
        while(1)
        {
                KeyNum=MatrixKey();
                if(KeyNum)
                {
                        if(KeyNum<=10)        //如果S1~S10按鍵按下,輸入密碼
                        {
                                if(Count<4)        //如果輸入次數(shù)小于4
                                {
                                        Password*=10;                                //密碼左移一位
                                        Password+=KeyNum%10;                //獲取一位密碼
                                        Count++;        //計(jì)次加一
                                }
                                LCD_ShowNum(2,1,Password,4);        //更新顯示
                        }
                        if(KeyNum=='#')        //如果#按鍵按下,確認(rèn)   任意鍵都可以
                        {
                                if(Password==initpassword[4])        //如果密碼等于正確密碼
                                {
                                        LCD_ShowString(1,11,"PassOK ");        //顯示OK
                                         KEY=~KEY;                                                                                //打開(kāi)繼電器
                                        Password=0;                //密碼清零
                                        Count=0;                //計(jì)次清零
                                        LCD_ShowNum(2,1,Password,4);        //更新顯示
                                }
                                else                                //否則
                                {
                                        LCD_ShowString(1,12,"error");        //顯示ERR
                                        Password=0;                //密碼清零
                                        Count=0;                //計(jì)次清零
                                        LCD_ShowNum(2,1,Password,4);        //更新顯示
                                }
                        }
                        if(KeyNum=='*')        //如果*按鍵按下,取消
                        {
                                Password=0;                //密碼清零
                                Count=0;                //計(jì)次清零
                                LCD_ShowNum(2,1,Password,4);        //更新顯示
                        }
                }
        }
}



回復(fù)

使用道具 舉報(bào)

25#
ID:883242 發(fā)表于 2024-5-3 11:32 | 只看該作者
188610329 發(fā)表于 2024-5-2 23:13
確實(shí),就一句話都還能寫錯(cuò)……,還不如人家寫復(fù)雜一點(diǎn)的…… 至少能保證對(duì)。

是你寫錯(cuò)了。
回復(fù)

使用道具 舉報(bào)

26#
ID:161164 發(fā)表于 2024-5-3 14:48 | 只看該作者
bd5fna 發(fā)表于 2024-5-3 10:25
請(qǐng)各位大佬再幫忙看看,輸入密碼時(shí)任何鍵都不會(huì)顯示,只有按下確認(rèn)鍵會(huì)顯示錯(cuò)誤(任意鍵做確認(rèn)鍵都會(huì)顯示錯(cuò) ...

STD 信號(hào)呢?
回復(fù)

使用道具 舉報(bào)

27#
ID:883242 發(fā)表于 2024-5-3 15:13 | 只看該作者
lkc8210 發(fā)表于 2024-5-3 10:25
雖然精妙,可惜樓主的0到9不是ASCII

我回復(fù)15樓,你的問(wèn)題找15樓說(shuō)去,別在我的帖子里面插嘴。
回復(fù)

使用道具 舉報(bào)

28#
ID:76027 發(fā)表于 2024-5-3 15:22 | 只看該作者

if(dtmf_ok==1)再檢測(cè)按鍵也一樣,不行。
回復(fù)

使用道具 舉報(bào)

29#
ID:161164 發(fā)表于 2024-5-3 15:53 | 只看該作者
Hephaestus 發(fā)表于 2024-5-3 15:13
我回復(fù)15樓,你的問(wèn)題找15樓說(shuō)去,別在我的帖子里面插嘴。

了解。。。。
回復(fù)

使用道具 舉報(bào)

30#
ID:161164 發(fā)表于 2024-5-3 15:53 | 只看該作者
bd5fna 發(fā)表于 2024-5-3 15:22
if(dtmf_ok==1)再檢測(cè)按鍵也一樣,不行。

咋加的?
回復(fù)

使用道具 舉報(bào)

31#
ID:69038 發(fā)表于 2024-5-3 17:08 | 只看該作者
Hephaestus 發(fā)表于 2024-5-3 15:13
我回復(fù)15樓,你的問(wèn)題找15樓說(shuō)去,別在我的帖子里面插嘴。

我是15樓的。
你這是咋啦??
論壇本就是公開(kāi)的,有事論事,有什么插不插嘴?看到有不同意見(jiàn)的都可以說(shuō)的。不然要這論壇何用?
回復(fù)

使用道具 舉報(bào)

32#
ID:76027 發(fā)表于 2024-5-3 18:56 | 只看該作者

while(1)
        {
                KeyNum=MatrixKey();
                if(dtmf_ok==1)
                {
                        if(KeyNum<=10)        //如果S1~S10按鍵按下,輸入密碼
                        {
                                if(Count<4)        //如果輸入次數(shù)小于4
                                {
                                        Password*=10;                                //密碼左移一位
                                        Password+=KeyNum%10;                //獲取一位密碼
                                        Count++;        //計(jì)次加一
                                }
                                LCD_ShowNum(2,1,Password,4);        //更新顯示
                        }
                        if(KeyNum=='#')        //如果#按鍵按下,確認(rèn)
                        {
                                if(Password==initpassword[4])        //如果密碼等于正確密碼
                                {
                                        LCD_ShowString(1,11,"PassOK ");        //顯示OK
                                         KEY=~KEY;                                                                                //打開(kāi)繼電器
                                        Password=0;                //密碼清零
                                        Count=0;                //計(jì)次清零
                                        LCD_ShowNum(2,1,Password,4);        //更新顯示
                                }
                                else                                //否則
                                {
                                        LCD_ShowString(1,12,"error");        //顯示ERR
                                        Password=0;                //密碼清零
                                        Count=0;                //計(jì)次清零
                                        LCD_ShowNum(2,1,Password,4);        //更新顯示
                                }
                        }
                        if(KeyNum=='*')        //如果*按鍵按下,取消
                        {
                                Password=0;                //密碼清零
                                Count=0;                //計(jì)次清零
                                LCD_ShowNum(2,1,Password,4);        //更新顯示
                        }
                }
        }
}

回復(fù)

使用道具 舉報(bào)

33#
ID:624769 發(fā)表于 2024-5-3 22:31 | 只看該作者

永遠(yuǎn)自信滿滿的樣子,希望你能保持。自己看看你寫的什么東西,返回值是什么再說(shuō)吧
回復(fù)

使用道具 舉報(bào)

34#
ID:76027 發(fā)表于 2024-5-4 09:59 | 只看該作者
向各位大佬匯報(bào)一下目前的情況:用下面的代碼,在不接入任何輸入的情況下,開(kāi)機(jī)就顯示滿屏的“0”,按鍵按下,顯示一大串對(duì)應(yīng)的鍵值而不是單個(gè)鍵值。注釋掉按鍵代碼,顯示一大串字符。請(qǐng)教一下各位大佬,這個(gè)如何解?
#include <STC8.H>
//#include <string.h>
//#include <EEPROM.h>
#include <LCD1602.h>
#define     MAIN_Fosc       24000000L   //定義主時(shí)鐘

sbit ALAM = P3^4;                //報(bào)警        
sbit KEY = P3^2;                //開(kāi)鎖
sbit dtmf_ok = P1^1; //雙音頻接收
sbit d0 = P1^2;
sbit d1 = P1^3;
sbit d2 = P1^4;
sbit d3 = P1^5;

unsigned char KeyNum,Count=0;
unsigned int Password=0;

unsigned char code initpassword[4]={5,6,7,8};                      //初始密碼
unsigned char dat[]="0123456789*#ABCD";
/***************************************************************************
函數(shù): unsigned char MatrixKey()
描述: dtmf取值函數(shù)
參數(shù): 將DTMF解碼數(shù)據(jù)編碼為數(shù)值
返回: K
版本: VER1.0
日期: 2024-4-23
備注:
***************************************************************************/

unsigned char MatrixKey()
{
        unsigned char k=0;
  unsigned char Temp = (P1>>2) & 0x0F;
if(dtmf_ok==1)
{
   switch(Temp)
         
        {

                case        0x01:        k=1;        break;
                case        0x02:        k=2;        break;
                case        0x03:        k=3;        break;
                case        0x04:        k=4;        break;        
                case        0x05:        k=5;        break;
                case        0x06:        k=6;        break;
                case        0x07:        k=7;        break;
                case        0x08:        k=8;        break;
                case        0x09:        k=9;        break;
                case        0x0A:        k=0;        break;
                case        0x0B:        k='*';        break;
                case        0x0C:        k='#';        break;
                case        0x0D:        k='A';        break;
                case        0x0E:        k='B';        break;
                case        0x0F:        k='C';        break;
                                                                case        0x00:        k='D';        break;
               default:        k=0xff;        break;
        }
       }
                                return k;
                        
}

void main()
{
        P1M0 &= ~0x3f;
        P1M1 &= ~0x3f;
  P3M0 &= ~0xfc;
        P3M1 &= ~0xfc;
  //P1=0xff;
        LCD_Init();
        LCD_ShowString(1,1,"Password:");
        while(1)
        {
                KeyNum=MatrixKey();

                LCD_WriteData(dat[KeyNum]);
               
                /*if(KeyNum)
                {
                        if(KeyNum<=10)        //如果0-9按鍵按下,輸入密碼
                        {
                                if(Count<4)        //如果輸入次數(shù)小于4
                                {
                                        Password*=10;                                //密碼左移一位
                                        Password+=KeyNum%10;                //獲取一位密碼
                                        Count++;        //計(jì)次加一
                                }
                                LCD_ShowNum(2,1,Password,4);        //更新顯示
                        }
                        if(KeyNum=='#')        //如果#按鍵按下,確認(rèn)
                        {
                                if(Password==initpassword[4])        //如果密碼等于正確密碼
                                {
                                        LCD_ShowString(1,11,"PassOK ");        //顯示OK
                                         KEY=~KEY;                                                                                //打開(kāi)繼電器
                                        Password=0;                //密碼清零
                                        Count=0;                //計(jì)次清零
                                        LCD_ShowNum(2,1,Password,4);        //更新顯示
                                }
                                else                                //否則
                                {
                                        LCD_ShowString(1,12,"error");        //顯示ERR
                                        Password=0;                //密碼清零
                                        Count=0;                //計(jì)次清零
                                        LCD_ShowNum(2,1,Password,4);        //更新顯示
                                }
                        }
                        if(KeyNum=='*')        //如果*按鍵按下,取消
                        {
                                Password=0;                //密碼清零
                                Count=0;                //計(jì)次清零
                                LCD_ShowNum(2,1,Password,4);        //更新顯示
                        }
                }*/
        }
}


回復(fù)

使用道具 舉報(bào)

35#
ID:76027 發(fā)表于 2024-5-5 12:35 | 只看該作者
已經(jīng)改用下降沿觸發(fā)檢測(cè)按鍵,但還是開(kāi)機(jī)滿屏的‘0’。
回復(fù)

使用道具 舉報(bào)

36#
ID:69038 發(fā)表于 2024-5-6 16:26 | 只看該作者
沒(méi)有原理圖,我就腦補(bǔ)且認(rèn)為你這個(gè)是DTMF解碼、從8870的D0-D3口接P1^2-P1^5,獲取數(shù)據(jù)的吧。如果不是,那我這個(gè)回復(fù)貼就是廢話,無(wú)視之!unsigned char MatrixKey()
{
  unsigned char k=0;
  unsigned char Temp = (P1>>2) & 0x0F; //你在這邊已賦值給temp了!不管有沒(méi)有STD來(lái),都是一個(gè)值。。  //改成unsigned char Temp;
if(dtmf_ok==1) //因?yàn)榍斑叺膯?wèn)題,這個(gè)判斷已無(wú)意義
{
   //如果8870/9170DTMF解碼,OE腳要置高,D0-D3腳才有電平出來(lái),你可以在硬件上把OE與STD直連,并下拉一個(gè)幾十K。
   //此處插入 讀值D0-D3:(P1>>2) & 0x0F
   switch(Temp)
        {
                case        0x01:        k=1;        break;   //此分支返回,就是0x01, 直接ASC改成'1'
                case        0x02:        k=2;        break;  //0x02,
                case        0x03:        k=3;        break;//.
                case        0x04:        k=4;        break;    //    .
                case        0x05:        k=5;        break;//.
                case        0x06:        k=6;        break;//.
                case        0x07:        k=7;        break;//.
                case        0x08:        k=8;        break;//.
                case        0x09:        k=9;        break;//.
                case        0x0A:        k=0;        break;//此分支返回,就是0x00
                case        0x0B:        k='*';        break;//此分支返回,0x2A, 而你接下要用到的dat[]成員數(shù)才16個(gè)!
                case        0x0C:        k='#';        break;//此分支返回,0x23!!!
                case        0x0D:        k='A';        break;//此分支返回,0x41!!!
                case        0x0E:        k='B';        break;//此分支返回,0x42!!!
                case        0x0F:        k='C';        break;//此分支返回,0x43!!!
                case        0x00:        k='D';        break;//此分支返回,0x44!!!
               default:        k=0xff;        break;           
        }
       }
  return k;
}


你這段代碼switch(Temp)是分支篩選,與接下來(lái)的LCD_WriteData(dat[KeyNum]);這行也是分支篩選,功能重復(fù)了,為什么要2次?
直接把 case        0x01:        k=1;        break;  改成 case        0x01:        k=‘1’;        break;  一直改到‘0’這行。直接調(diào)用顯示就OK了:
LCD_WriteData(k);
總之:數(shù)值套娃,還是套到錯(cuò)的數(shù)值。





回復(fù)

使用道具 舉報(bào)

37#
ID:1073352 發(fā)表于 2024-5-6 16:38 | 只看該作者

unsigned char MatrixKey()
{
        unsigned char k=0;
        switch((P2>>2)&0x0f)
        {
                case        0x01:        k=1;        break;
                case        0x02:        k=2;        break;
                case        0x03:        k=3;        break;
                case        0x08:        k=4;        break;        //我也不知道為什么你會(huì)有兩個(gè)相同的按鍵狀態(tài)
                case        0x05:        k=5;        break;
                case        0x06:        k=6;        break;
                case        0x07:        k=7;        break;
                case        0x08:        k=8;        break;
                case        0x09:        k=9;        break;
                case        0x0A:        k=0;        break;
                case        0x0B:        k='*';        break;
                case        0x0C:        k='#';        break;
                case        0x0D:        k='A';        break;
                case        0x0E:        k='B';        break;
                case        0x0F:        k='C';        break;
                case        0x00:        k='D';        break;
                default:        k=0xff;        break;
        }
        return k;
}
回復(fù)

使用道具 舉報(bào)

38#
ID:69038 發(fā)表于 2024-5-6 16:44 | 只看該作者
bd5fna 發(fā)表于 2024-5-5 12:35
已經(jīng)改用下降沿觸發(fā)檢測(cè)按鍵,但還是開(kāi)機(jī)滿屏的‘0’。

你要確認(rèn),DTMF解碼是否正常!d0-d3是否有輸出!
把STD接個(gè)電阻串個(gè)LED,再把OE接到STD,看看每按一次鍵,led是否會(huì)閃亮一下。
回復(fù)

使用道具 舉報(bào)

39#
ID:76027 發(fā)表于 2024-5-6 19:52 | 只看該作者
zhuls 發(fā)表于 2024-5-6 16:44
你要確認(rèn),DTMF解碼是否正常!d0-d3是否有輸出!
把STD接個(gè)電阻串個(gè)LED,再把OE接到STD,看看每按一次鍵 ...

DTMF解碼正常!d0-d3有輸出!每按一次鍵,led會(huì)閃,STD輸出高電平。用的是這種模塊
回復(fù)

使用道具 舉報(bào)

40#
ID:76027 發(fā)表于 2024-5-6 21:02 | 只看該作者
本帖最后由 bd5fna 于 2024-5-7 09:37 編輯

目前的情況給各位大佬匯報(bào)一下:
void main()
{
        P1M0 &= ~0x3f;
        P1M1 &= ~0x3f;
  P3M0 &= ~0xfc;
        P3M1 &= ~0xfc;
  //P1=0xff;
        Timer0_Init();
        LCD_Init();
        UART_InitConfig();
        LCD_ShowString(1,1,"Password:");
        TI = 1;                                                                                                         //使用printf()函數(shù)時(shí),TI必須為1
        while(1)
        {
                printf("%d ",k);
                LCD_WriteData(k);   這里可顯示解碼出來(lái)的鍵值,有一個(gè)現(xiàn)象,比如按下“1”鍵,顯示的是一排16個(gè)“1”,不是單個(gè)。
               
                        if(k<=9)        //如果0-9按鍵按下,輸入密碼
                        {
                                if(Count<4)        //如果輸入次數(shù)小于4
                                {
                                        Password*=10;                                //密碼左移一位
                                        Password+=k%10;                //獲取一位密碼
                                        Count++;        //計(jì)次加一
                                }
                                LCD_ShowNum(2,1,Password,4);        //更新顯示    注釋掉   LCD_WriteData(k); 這里顯示不了輸入的鍵值。
                        
                                printf("%d ",Password);
                        }
                        if(k=='#')        //如果#按鍵按下,確認(rèn)         按下“#”鍵后,顯示“error”
                        {
                                if(Password==initpassword[4])        //如果密碼等于正確密碼
                                {
                                        LCD_ShowString(1,11,"PassOK ");        //顯示OK
                                         jdq=~jdq;                                                                                //打開(kāi)繼電器
                                        Password=0;                //密碼清零
                                        Count=0;                //計(jì)次清零
                                        LCD_ShowNum(2,1,Password,4);        //更新顯示
                                }
                                else                                //否則
                                {
                                        LCD_ShowString(1,12,"error");        //顯示ERR
                                        Password=0;                //密碼清零
                                        Count=0;                //計(jì)次清零
                                        LCD_ShowNum(2,1,Password,4);        //更新顯示
                                }
                        }
                        if(k=='*')        //如果*按鍵按下,取消   按“*”返回沒(méi)有效果
                        {
                                Password=0;                //密碼清零
                                Count=0;                //計(jì)次清零
                                LCD_ShowNum(2,1,Password,4);        //更新顯示
                        }
        }
}

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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