欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2524|回復: 17
收起左側

C51單片機鍵盤掃描程序異常,一次按下被判定為多次

[復制鏈接]
ID:1094415 發表于 2023-9-24 17:26 | 顯示全部樓層 |閱讀模式
這是單片機實驗,在這里我想用全局變量count來控制顯示,但是一次按下后就被判定為按下了多次,而且行掃描停止了,大佬求教,代碼還是電路哪里有問題,電路圖用的是proteus。真心求教,看了一下午還是沒找出問題。

單片機源程序如下:
  1. #include <reg51.h>
  2. #include <intrins.h>

  3. sbit P2_1=P2^1;
  4. sbit P2_0=P2^0;
  5. unsigned char discontrol[]={0xfe,0xfd,0xfb,0xf7};
  6. unsigned int buffer[]={-1,-1,-1,-1};
  7. unsigned code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
  8. int count=0;

  9. void Delay(unsigned int x){
  10.         unsigned char t;
  11.         while(x--){
  12.         for(t=0;t<60;t++);
  13.         }
  14.         
  15. }





  16. unsigned char Keyscan(void){
  17.   int i,tmp,num=16;
  18.         unsigned char cflag=1;//cycling flag
  19.         for(i=0;i<4;i++){
  20.                 if(!cflag)
  21.                         break;
  22.          P1=_crol_(0xfe,i);
  23.          tmp=P1;
  24.          tmp=tmp&0xf0;
  25.                 if(tmp!=0xf0){
  26.                                 Delay(50);//prevent keyboard quiver
  27.                                 tmp=P1;
  28.                           tmp=tmp&0xf0;
  29.                                 if(tmp!=0xf0){//check angin
  30.                                         tmp=P1;
  31.                                         switch(tmp){
  32.                                                 case 0xee:num=0;break;
  33.                                                 case 0xde:num=1;break;
  34.                                                 case 0xbe:num=2;break;
  35.                                                 case 0x7e:num=3;break;
  36.                                                 case 0xed:num=4;break;
  37.                                                 case 0xdd:num=5;break;
  38.                                                 case 0xbd:num=6;break;
  39.                                                 case 0x7d:num=7;break;
  40.                                                 case 0xeb:num=8;break;
  41.                                                 case 0xdb:num=9;break;
  42.                                                 case 0xbb:num=10;break;
  43.                                                 case 0x7b:num=11;break;
  44.                                                 case 0xe7:num=12;break;
  45.                                                 case 0xd7:num=13;break;
  46.                                                 case 0xb7:num=14;break;
  47.                                                 case 0x77:num=15;break;
  48.                                                 default:break;
  49.                                 }
  50.                                         cflag=0;
  51.                                         while((tmp&0xf0)!=0xf0){//judge the up
  52.                                                 tmp=P1;
  53.                                         }
  54.                                 }
  55.                         
  56.                 }
  57.         }
  58. return num;
  59. }



  60. void main(){

  61.    int num,i;        
  62.         while(1){
  63.                 num=keyscan();
  64.                 if(num<16){
  65.                    if(count<4)//update count number
  66.                      count++;
  67.                         for( i=count-1;i>0;i--){//update buffer
  68.                                         buffer[i]=buffer[i-1];
  69.                                 }
  70.                    buffer[0]=num;
  71.                 }
  72.                 for( i=0;i<count;i++){//display
  73.                   P2=discontrol[i];//the outport set 0,other set 1
  74.                         P0=table[0];
  75.                         Delay(500);
  76.                 }

  77.         }
  78.         

  79. }

復制代碼


exp2.rar

18.28 KB, 下載次數: 3

電路圖,Proteus

回復

使用道具 舉報

ID:1094415 發表于 2023-9-24 19:00 | 顯示全部樓層
本來在main函數中,調用keyscan后返回一次有效值,也就是按下一次按鍵后,count才會加一,但實際情況卻是,按下一次后,count直接加1,加1,加1,變成了4
回復

使用道具 舉報

ID:1094415 發表于 2023-9-24 19:03 | 顯示全部樓層
異常情況描述,本來在main函數中,調用一次keyscan,只有當返回有效值,也就是按鍵按下后松開,count才會加1,但實際情況卻是按下一次按鍵后,main函數中的while(1)循環進行了4次。keyscan中有通過延時進行鍵盤防抖,也有一個循環進行按鍵松開的檢測,但就是不正常,我才疏學淺,找不出問題,請各位指教
回復

使用道具 舉報

ID:235200 發表于 2023-9-24 19:14 | 顯示全部樓層
最好是把電路圖和工程文件全部打包發上來,并說明PROTEUS使用的是哪個版本
回復

使用道具 舉報

ID:1094415 發表于 2023-9-24 20:08 | 顯示全部樓層
這是全部文件,使用的是Proteus 8 Professional和Keil uVision5。

EXP2.rar

81.87 KB, 下載次數: 1

回復

使用道具 舉報

ID:1094415 發表于 2023-9-24 20:13 | 顯示全部樓層
csmyldl 發表于 2023-9-24 19:14
最好是把電路圖和工程文件全部打包發上來,并說明PROTEUS使用的是哪個版本

發在樓下了,  如果您有時間,能勞煩你指教
回復

使用道具 舉報

ID:1045456 發表于 2023-9-24 21:31 | 顯示全部樓層
  P3=0xf0;
   time(10);
   if (P3==0xf0) SB=0;
   else
   {
    time(5);
    Beep = 0;
        SB=P3;
    P3=0x0f;
        time(5);
    if (P3==0x0f) SB=0;
    else
        {
    time(5);
    SB=SB|P3;
    time(5);
        }
        P3=0xf0;
     
         time(5);
        while (P3!=0xf0);
                switch (SB)
        {
     case 0xee : SB=1; break;
         case 0xde : SB=2; break;
         case 0xbe : SB=3; break;
     case 0x7e : SB=4; break;
         case 0xed : SB=5; break;
         case 0xdd : SB=6; break;
         case 0xbd : SB=7; break;
         case 0x7d : SB=8; break;
         case 0xeb : SB=9; break;
         case 0xdb : SB=10; break;
         case 0xbb : SB=11; break;
         case 0x7b : SB=12; break;
         case 0xe7 : SB=13; break;
         case 0xd7 : SB=14; break;
         case 0xb7 : SB=15; break;
         case 0x77 : SB=16; break;
     default:  ;
           }       


試一試以上代碼
回復

使用道具 舉報

ID:1094415 發表于 2023-9-24 21:39 | 顯示全部樓層
吳征 發表于 2023-9-24 21:31
P3=0xf0;
   time(10);
   if (P3==0xf0) SB=0;

請問不去要對按鍵抬起做判斷嗎,這樣的話不會一次按下被多次判定嗎
回復

使用道具 舉報

ID:1045456 發表于 2023-9-24 21:44 | 顯示全部樓層
這個就是按鍵抬起做判斷
回復

使用道具 舉報

ID:1045456 發表于 2023-9-24 21:46 | 顯示全部樓層
        time(5);
        while (P3!=0xf0);


這個就是按鍵抬起做判斷
回復

使用道具 舉報

ID:1045456 發表于 2023-9-24 21:49 | 顯示全部樓層
半步成 發表于 2023-9-24 21:39
請問不去要對按鍵抬起做判斷嗎,這樣的話不會一次按下被多次判定嗎

       P3=0xf0;
     
         time(5);
        while (P3!=0xf0);
     
這個就是抬起判斷

回復

使用道具 舉報

ID:1094415 發表于 2023-9-24 22:07 | 顯示全部樓層
吳征 發表于 2023-9-24 21:49
P3=0xf0;
     
         time(5);

我試著替換了我的掃描函數,但還是不行,一次按鍵按下后,count就加到了4,我覺得應該不是掃描函數的問題,我這部分代碼的邏輯和你差不多。最后還是謝謝你的幫助
回復

使用道具 舉報

ID:1094415 發表于 2023-9-24 22:20 | 顯示全部樓層
吳征 發表于 2023-9-24 21:49
P3=0xf0;
     
         time(5);

問題解決了,鍵盤抬起也需要延時防抖,在抬起判斷中,加入延時后就正常了
回復

使用道具 舉報

ID:1094415 發表于 2023-9-24 22:20 | 顯示全部樓層
csmyldl 發表于 2023-9-24 19:14
最好是把電路圖和工程文件全部打包發上來,并說明PROTEUS使用的是哪個版本

謝謝您的幫助,問題解決了,鍵盤抬起也需要延時防抖,在抬起判斷中,加入延時后就正常了
回復

使用道具 舉報

ID:1094415 發表于 2023-9-24 22:20 | 顯示全部樓層
吳征 發表于 2023-9-24 21:49
P3=0xf0;
     
         time(5);

還有,謝謝您的幫助
回復

使用道具 舉報

ID:1045456 發表于 2023-9-24 22:39 | 顯示全部樓層
半步成 發表于 2023-9-24 22:20
還有,謝謝您的幫助

unsigned char Keyscan(void)
{
        unsigned char tmp,num=16;//cycling flag
         P1=_0xf0;
         Delay(50);//prevent keyboard quiver
         if(P1!=0xf0)
                 {
             tmp=P1;
             P1=_0x0f;
             Delay(50);//prevent keyboard quiver
             if(P1!=0x0f)   tmp |= P1;
             P1=_0xf0;
             Delay(50);//prevent keyboard quiver
             while (P1!=0xf0);
             switch(tmp)
                         {
                     case 0xee:num=0;break;
                     case 0xde:num=1;break;
                     case 0xbe:num=2;break;
                     case 0x7e:num=3;break;
                     case 0xed:num=4;break;
                     case 0xdd:num=5;break;
                     case 0xbd:num=6;break;
                     case 0x7d:num=7;break;
                     case 0xeb:num=8;break;
                     case 0xdb:num=9;break;
                     case 0xbb:num=10;break;
                     case 0x7b:num=11;break;
                     case 0xe7:num=12;break;
                     case 0xd7:num=13;break;
                     case 0xb7:num=14;break;
                     case 0x77:num=15;break;
                     default:break;
              }
        }
return num;
}


你試一試這個用你的原程誠序改的
回復

使用道具 舉報

ID:1094811 發表于 2023-9-29 11:50 | 顯示全部樓層
建議用狀態機的方式檢測按鍵:(switch)
狀態1-----有按鍵,轉到2,無按鍵,等待
狀態2-----判斷按鍵是否穩定,穩定,到3,不穩定,回到1
狀態3-----記錄按下的時間,并檢測松手,如果時間小于2-3秒檢測到松手,到4,如果大于2-3秒,輸出長按按鍵值,到4
狀態4-----按鍵穩定松手,如果時間是短按的時間,清除記錄的時間,輸出短按按鍵值,回到1。如果是長按時間,回到1。按鍵如果是抖動,回到3.
回復

使用道具 舉報

ID:1097455 發表于 2023-10-27 13:42 | 顯示全部樓層
按鍵消抖方式不對
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表