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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1691|回復: 28
打印 上一主題 下一主題
收起左側

請教51單片機矩陣鍵盤反轉法掃描遇到的無法解決的問題

[復制鏈接]
跳轉到指定樓層
樓主
ID:349276 發表于 2024-10-30 17:06 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
mcu 是stc8a8k64s4a12單片機,矩陣鍵盤是帶上拉電阻的真實鍵盤,P1口連接,采用反轉法掃描。1.必須設置成開漏模式才能采集到數據。其它模式都不行,不知道啥原因。2.第一次置P1=0xf0,可以正確設置,且能正確采集回按鍵情況;第二次反轉 設置P1=0x0f,然后采集p1口的數據完全是錯的,比如只采集p1一次,得到的數據是第一次(反轉設置之前)的數據;比如重復寫一次采集數據(連續采集兩次),得到的數據跟采集一次的又完全不同,且還發現低電平被拉高了(本來應該是高電平被拉低)。
沒招數了。請大神指點下迷津。

P1為KEY_ScanPort  要設置這個 初始化 P1M1=0xff;P1M0=0xff;才能讀回數據

        
        KEY_ScanPort=0xF0;                 //列線為輸入,行線為輸出,并置行線輸出全為0
        temp=KEY_ScanPort;                 //讀P1口       能正確得到數據
        temp=temp&0xF0;
        temp=~((temp>>4)|0xF0);
        if(temp==1)
                key=0;
        else if(temp==2)
                key=1;
        else if(temp==4)
                key=2;
        else if(temp==8)
                key=3;
        KEY_ScanPort=0xFF;//for read  這一句可有可不有,但proteus里那鍵盤keypad仿真必須得有這個,否則無法采集
        KEY_ScanPort=0x0F;                 //設置反轉,行線為輸入,列線為輸出,并置列線輸出全為0
        MDelay(3);        //懷疑引腳電平反轉起效果時有一個較長的時間延遲
        temp=KEY_ScanPort;                 //讀P1口 讀出來跟沒有反轉之前的采集情況一樣,就是高四位有3個1
        temp=KEY_ScanPort;                //重復采集一下發現低四位有4個1 高四位有1~2個1,低電平反而被拉高了。
       temp=KEY_ScanPort;                //再重復采集一下發現低四位有4個1,高四位是4個0,不動了,按鍵沒效果。反正反轉后無法采集到正確信息
        temp=temp&0x0F;
        temp=~(temp|0xF0);        
        if(temp==1)
                key=key+0;
        else if(temp==2)
                key=key+4;
        else if(temp==4)
                key=key+8;
        else if(temp==8)
                key=key+12;
                             

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:1109793 發表于 2024-10-30 19:07 | 只看該作者
矩陣怎么接的?4*4的?一次拉低4個IO,怎么判斷是那個IO上的KEY?
回復

使用道具 舉報

板凳
ID:446156 發表于 2024-10-31 09:44 | 只看該作者
反轉法矩陣掃描當然要配置成開漏模式啦必須所有用到的IO都是開漏才行,這樣你讓IO輸出高電平的時候該IO可以被外界信號拉低或者拉高方便你檢測,這和IIC的SDA要配置成開漏一個原理。我沒看明白你是開漏模式下完全正常還是開漏模式下也存在問題。還有設置完IO口狀態再去讀取IO口電平時中間要間隔一段時間一般情況下1ms完全夠了,因為電路存在寄生電容,開漏模式下IO狀態從低到高需要上拉電阻給寄生電容充電需要時間不會瞬間變化的。
回復

使用道具 舉報

地板
ID:446156 發表于 2024-10-31 09:46 | 只看該作者
xiaobendan001 發表于 2024-10-30 19:07
矩陣怎么接的?4*4的?一次拉低4個IO,怎么判斷是那個IO上的KEY?

反轉法,先把四個列線拉低檢測4個行線電平,然后把4個行線拉低去檢測4個列線電平。把兩次檢測結果或在一起就能知道是哪個按鍵被按下了
回復

使用道具 舉報

5#
ID:619259 發表于 2024-10-31 10:25 | 只看該作者
矩陣鍵盤反轉法掃描實例,以 P1口為例。
1.拉低P1低4位;
2.若P1高4位出現低電平,則讀P1的值;
3.反轉,釋放P1低4位,拉低P1高4位;
4.讀P1的值;
5.將步驟2和4的值或運算;
6.對步驟5的值進行判斷或查表,執行給定任務。
回復

使用道具 舉報

6#
ID:1109793 發表于 2024-10-31 12:51 | 只看該作者
cy009 發表于 2024-10-31 10:25
矩陣鍵盤反轉法掃描實例,以 P1口為例。
1.拉低P1低4位;
2.若P1高4位出現低電平,則讀P1的值;

這樣就是需要都設置標準IO才行吧,設置開漏就是沒有上拉電阻,那么高電平由誰提供?
我還真沒試過這種,都是一個IO一個IO的拉低,然后檢測另外四個的電平變化。
回復

使用道具 舉報

7#
ID:446156 發表于 2024-10-31 14:05 | 只看該作者
xiaobendan001 發表于 2024-10-31 12:51
這樣就是需要都設置標準IO才行吧,設置開漏就是沒有上拉電阻,那么高電平由誰提供?
我還真沒試過這種, ...

外部上拉電阻提供高電平啊,所有的按鍵電路無論矩陣也好獨立按鍵也好不都得配上拉電阻嗎?
回復

使用道具 舉報

8#
ID:161164 發表于 2024-10-31 14:57 | 只看該作者
上拉電阻阻值多大?
回復

使用道具 舉報

9#
ID:349276 發表于 2024-10-31 15:44 | 只看該作者
xiaobendan001 發表于 2024-10-30 19:07
矩陣怎么接的?4*4的?一次拉低4個IO,怎么判斷是那個IO上的KEY?

4*4的,p1低四位接行,高四位接列。每條線都有上拉電阻,上拉電阻電路是放矩陣鍵盤里面的。反轉法是f0   再0f的,按鍵按下,只會有一個高電平會被拉低的。原理上來說。仿真都沒有問題的。就是實際這個鍵盤,反轉后采集不回來數據。
回復

使用道具 舉報

10#
ID:349276 發表于 2024-10-31 15:45 | 只看該作者
qinlu123 發表于 2024-10-31 09:46
反轉法,先把四個列線拉低檢測4個行線電平,然后把4個行線拉低去檢測4個列線電平。把兩次檢測結果或在一 ...

就是行線拉低,采集不回數據。
回復

使用道具 舉報

11#
ID:1133081 發表于 2024-10-31 15:45 | 只看該作者
給你一個4*4矩陣按鍵示例,端口設置為準雙向模式。有無外置上拉電阻無所謂。程序放在主函數里查詢。key初值為0,鍵值輸出1~16,使用后可以清0.
void keyscan()                                        //按鍵掃描程序
{
        static bit sign=0;                        //按鍵狀態標志
        static int count=0;                        //消抖計數變量                       
        unsigned char temp=0;                //臨時變量
        P1=0xf0;                                        //賦值P1 1111 0000
        if(P1!=0xf0)                                //檢測有按鍵按下
        {
                count++;                                //消抖計數
                if(count>=100 && sign==0)//根據主程序查詢周期調整count大小,約10~20ms防抖即可
                {                       
                        sign=1;                                //按鍵狀態標志置1
                        temp=P1;                        //保存P1值xxxx 0000,x為0或1
                        temp|=0x0f;                        //保存temp按位或0x0f值xxxx 1111
                        P1=temp;                        //賦值P1 xxxx 1111
                        switch(P1)
                        {
                                case 0xee: key= 1; break;
                                case 0xde: key= 2; break;
                                case 0xbe: key= 3; break;
                                case 0x7e: key= 4; break;
                                case 0xed: key= 5; break;
                                case 0xdd: key= 6; break;
                                case 0xbd: key= 7; break;
                                case 0x7d: key= 8; break;
                                case 0xeb: key= 9; break;
                                case 0xdb: key=10; break;
                                case 0xbb: key=11; break;
                                case 0x7b: key=12; break;
                                case 0xe7: key=13; break;
                                case 0xd7: key=14; break;
                                case 0xb7: key=15; break;
                                case 0x77: key=16; break;
                        }
                }
        }
        else                                                //鍵抬起
        {
                sign=0;                                        //按鍵狀態標志清0
                count=0;                                //消抖計數清0
        }
}
回復

使用道具 舉報

12#
ID:349276 發表于 2024-10-31 15:46 | 只看該作者
qinlu123 發表于 2024-10-31 09:44
反轉法矩陣掃描當然要配置成開漏模式啦必須所有用到的IO都是開漏才行,這樣你讓IO輸出高電平的時候該IO可以 ...

我明天試試,延遲1ms后再采集試試。
回復

使用道具 舉報

13#
ID:349276 發表于 2024-10-31 15:50 | 只看該作者
cy009 發表于 2024-10-31 10:25
矩陣鍵盤反轉法掃描實例,以 P1口為例。
1.拉低P1低4位;
2.若P1高4位出現低電平,則讀P1的值;

您這步驟完全正確。就是第三步,代碼直接用  P1=0x0f,起不了作用。您所謂 釋放p1低四位,拉低p1高四位,是不是不使用的P1=0x0f語句?如不使,應該怎么用?
回復

使用道具 舉報

14#
ID:349276 發表于 2024-10-31 15:51 | 只看該作者
xiaobendan001 發表于 2024-10-31 12:51
這樣就是需要都設置標準IO才行吧,設置開漏就是沒有上拉電阻,那么高電平由誰提供?
我還真沒試過這種, ...

鍵盤上提供了上拉結構的,高電平有鍵盤提供。開漏是可以的。
回復

使用道具 舉報

15#
ID:1109793 發表于 2024-10-31 16:39 | 只看該作者
qinlu123 發表于 2024-10-31 14:05
外部上拉電阻提供高電平啊,所有的按鍵電路無論矩陣也好獨立按鍵也好不都得配上拉電阻嗎?

既然要用外部上拉,為何還要關閉內部上拉?還是說這種接法和讀取方法需要非常精確的上拉,內部因為制造工藝問題誤差太大不能用?那么多少才最好用?
回復

使用道具 舉報

16#
ID:349276 發表于 2024-10-31 23:25 來自手機 | 只看該作者
WL0123 發表于 2024-10-31 15:45
給你一個4*4矩陣按鍵示例,端口設置為準雙向模式。有無外置上拉電阻無所謂。程序放在主函數里查詢。key初值 ...

這代碼也許不錯,第二次只有一個低電平線。明天試試效果。
回復

使用道具 舉報

17#
ID:349276 發表于 2024-10-31 23:30 來自手機 | 只看該作者
xiaobendan001 發表于 2024-10-31 16:39
既然要用外部上拉,為何還要關閉內部上拉?還是說這種接法和讀取方法需要非常精確的上拉,內部因為制造工 ...

是這樣的,設置為其它模式,一次數據都讀不回來。設置為開漏,立刻就讀回來了。原因我不會分析。另外查到stm32,如果是開漏模式,還有幾個寄存器要聯合配置,比如有個配置低電平究竟是哪個范圍,范圍不對采集的數據可能會錯。不知道是不是因為沒配置的原因?我不知道stc8有沒有這些寄存器。沒看它的說明書。
回復

使用道具 舉報

18#
ID:579397 發表于 2024-11-1 00:48 | 只看該作者
        KEY_ScanPort=0xF0;
******
        KEY_ScanPort=0xFF;//for read  這一句可有可不有,但proteus里那鍵盤keypad仿真必須得有這個,否則無法采集

這里加一個延時試試,我解釋不了,但我這樣做就正常了
        KEY_ScanPort=0x0F;                 //設置反轉,行線為輸入,列線為輸出,并置列線輸出全為0
回復

使用道具 舉報

19#
ID:446156 發表于 2024-11-1 08:12 | 只看該作者
xiaobendan001 發表于 2024-10-31 16:39
既然要用外部上拉,為何還要關閉內部上拉?還是說這種接法和讀取方法需要非常精確的上拉,內部因為制造工 ...

習慣問題吧,我很少用單片機的內部上拉,51多年不用了不了解,stm32的內部上拉電阻太大很多場合都不合適。看了下51IO設置結合我之前做51時候的經歷把IO配置成準雙向IO也行即M1=0;M0=0
回復

使用道具 舉報

20#
ID:446156 發表于 2024-11-1 08:15 | 只看該作者
萬家燈火51 發表于 2024-10-31 15:45
就是行線拉低,采集不回數據。

你先檢查IO輸入檢測有沒有問題,把8和IO都輸出0讀一下IO狀態然后都輸出1再讀一下狀態。用萬用表量一量是不是對
回復

使用道具 舉報

21#
ID:192020 發表于 2024-11-1 14:21 | 只看該作者
temp=KEY_ScanPort;                 //讀P1口 讀出來跟沒有反轉之前的采集情況一樣,就是高四位有3個1
不知道你是用什么方法來讀temp值的?這時候萬用表量一下高低電平是不是和讀的符合,感覺大概率硬件問題
回復

使用道具 舉報

22#
ID:349276 發表于 2024-11-1 18:47 來自手機 | 只看該作者
問題解決!!首先非常感謝各位大佬積極出主意和提供經驗。看到您們的回復,一下子覺得很踏實。困惑幾周的問題,綜合大家的想法突然有了思路。問題出在兩個地方:一個是沒有等待按鍵釋放就退出掃描,代碼又重復進入掃描覆蓋了前一次的數據。這個是看到上面大佬代碼里搞那么多狀態標記驚醒了我。第二個問題是,開漏輸出,電平上拉全靠外電路,電阻值大小和是否有旁路電容等,這個拉高過程有點長。電路理論里的三要素法,大致可以判斷,時間常數在毫秒級。線反轉法第一次設置后,要延時1毫秒,反轉后要延時2毫秒再采集數據,就完全正確了。非常感謝大家之外,有幾點感觸。1是謝謝大家技術上的開放心態。。特別鄙視xxxx,看兩句話就要收錢要么就是各種坑各種牛皮。,知識都被鎖。2.是遇到問題不要輕易懷疑芯片不可靠,是自己不可靠。3是這個論壇能查到真東西,能解決真問題。到搜這個論壇很難搜到,全是冒充51黑的網站。網絡生態太惡心。。廣告了
回復

使用道具 舉報

23#
ID:1109793 發表于 2024-11-2 07:19 | 只看該作者
萬家燈火51 發表于 2024-11-1 18:47
問題解決!!首先非常感謝各位大佬積極出主意和提供經驗。看到您們的回復,一下子覺得很踏實。困惑幾周的問 ...

不用開漏用標準IO不行嗎?要等2MS,這太浪費時間了吧。2US還行
回復

使用道具 舉報

24#
ID:349276 發表于 2024-11-2 12:14 來自手機 | 只看該作者
xiaobendan001 發表于 2024-11-2 07:19
不用開漏用標準IO不行嗎?要等2MS,這太浪費時間了吧。2US還行

標準口,沒有用延時等待不行。改天測一下用了延時,行不行。一般用鍵盤,按鍵都要延時5-10毫秒消抖的,正好掃描占用3毫秒,延時消抖3毫秒,效果很好。能滿足常規要求。
回復

使用道具 舉報

25#
ID:349276 發表于 2024-11-2 12:18 來自手機 | 只看該作者
Graves 發表于 2024-11-1 14:21
temp=KEY_ScanPort;                 //讀P1口 讀出來跟沒有反轉之前的采集情況一樣,就是高四位有3個1
不 ...

查出來原因了。應該是反復進入掃描循環,等待時間不夠,引腳反復處于高低電平變換造成的。
回復

使用道具 舉報

26#
ID:349276 發表于 2024-11-2 12:21 來自手機 | 只看該作者
405616736 發表于 2024-11-1 00:48
KEY_ScanPort=0xF0;
******
        KEY_ScanPort=0xFF;//for read  這一句可有可不有,但prote ...

你提醒了我。應該就是延時等待電平穩定。這一句與讀準備沒關系。就是起了延時作用。
回復

使用道具 舉報

27#
ID:1132991 發表于 2024-11-2 13:33 | 只看該作者
萬家燈火51 發表于 2024-11-1 18:47
問題解決!!首先非常感謝各位大佬積極出主意和提供經驗。看到您們的回復,一下子覺得很踏實。困惑幾周的問 ...

當時是搜A2開發板仿真電路才搜到的這個論壇
回復

使用道具 舉報

28#
ID:349276 發表于 2024-11-2 23:05 | 只看該作者
hxy52zero 發表于 2024-11-2 13:33
當時是搜A2開發板仿真電路才搜到的這個論壇

用百度白天搜 51黑電子論壇  就能搜到,晚上用這個關鍵詞搜,會出來一堆顏色相關的,且翻幾頁都找不到這個論壇。我并且截圖留證了。百度惡心得很,想搜時又搜不到。
回復

使用道具 舉報

29#
ID:446156 發表于 2024-11-4 08:04 | 只看該作者
xiaobendan001 發表于 2024-11-2 07:19
不用開漏用標準IO不行嗎?要等2MS,這太浪費時間了吧。2US還行

用我的驅動就不用擔心浪費時間,建議樓主如果做項目的話還是用我的驅動吧,平常玩玩就無所謂了。還有樓主借鑒的程序也不咋地找個好點的用。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产成人精品久久二区二区91 | 91麻豆精品国产91久久久久久久久 | 国产av毛片 | 欧美在线观看免费观看视频 | 亚洲欧美成人在线 | 黄色免费看| 欧美在线视频网 | 九九99九九精彩46 | 国产精品一区在线 | 日本高清aⅴ毛片免费 | 天天拍夜夜爽 | 国产精品2| 97超碰在线播放 | 色综合99| 日本不卡视频在线播放 | 五月香婷婷 | 欧美日韩中文字幕在线播放 | 日韩中文字幕 | 精品福利在线 | 国产乱码精品一区二区三区中文 | 91看片官网 | 羞羞视频免费在线 | 日本网站免费观看 | 欧美国产91 | 国产精品看片 | 一区二区三区四区免费视频 | 亚洲三区在线 | 91精品国产美女在线观看 | 精品国产一二三区 | 超碰在线人| av片毛片 | 久久久久精 | 久久高清精品 | 中文字幕国产精品 | 在线国产视频 | 亚洲国产欧美日韩 | 午夜精品影院 | 亚洲精品精品 | 久久国产亚洲 | 亚洲综合精品 | 免费天天干|