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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2740|回復: 38
收起左側

單片機矩陣按鍵不靈敏有什么好辦法?

  [復制鏈接]
回帖獎勵 5 黑幣 回復本帖可獲得 5 黑幣獎勵! 每人限 1 次
ID:298743 發表于 2024-5-11 15:54 | 顯示全部樓層 |閱讀模式
我做的是數碼管顯示時間的定時器,用的芯片是STC8H,我有15個按鍵,開了兩個中斷了,第一個定時器0給了時鐘計時,定時器1給了數碼管刷新,按鍵檢測一直放在主函數循環,嘗試過開多一個定時器2給按鍵掃描,但是還是不靈敏,效果不太明顯。懷疑是延時的問題,但是又想不出什么好辦法解決,畢竟怎么也要消抖,還有給io口反應的時間。看看各位大佬有什么好的意見。

單片機源程序如下:
#include "key.h"
#include "delay.h"
#include "intrins.h"
void IO_delay(void)
{
_nop_();
_nop_();
_nop_();
}

unsigned char key_scan()
{
unsigned char temp = 0;
KEY_MATRIX_PORT=0x56;//P1口第四位輸出低電平,即行值設為全0
IO_delay();
if((KEY_MATRIX_PORT&0x56)!=0x56)
{//列值不全為高電平
IO_delay();//去抖動
temp=KEY_MATRIX_PORT&0x56;//讀入列值
KEY_MATRIX_PORT=0xA9;//列值設為低電平
IO_delay();//去抖動
temp |= (KEY_MATRIX_PORT&0xA9);//把行值(第四位)和列值(高四位)位或得到唯一指向按鍵的鍵碼
while(KEY_MATRIX_PORT!=0xA9);
}
return temp;
}



主函數部分:(在16樓)
回復

使用道具 舉報

ID:1109793 發表于 2024-5-11 17:32 | 顯示全部樓層
在一個定時器里面,做個計時,做個顯示,做個按鍵,不行嗎?怎么還要這么多定時器啊?
回復

使用道具 舉報

ID:123289 發表于 2024-5-11 20:46 | 顯示全部樓層
中斷服務程序運行時,占用了你的掃描時間,感覺上按鍵不靈敏。是你的時序按排不合理!
如果你寫程序能夠設法不用DELAY()函數就可以了。DELAY是最低級初級編程學者用的函數。可用定時器做延時啊,用DELAY是浪費CPU資源。
回復

使用道具 舉報

ID:298743 發表于 2024-5-12 16:23 | 顯示全部樓層
xiaobendan001 發表于 2024-5-11 17:32
在一個定時器里面,做個計時,做個顯示,做個按鍵,不行嗎?怎么還要這么多定時器啊?

顯示和計時一起在同一個定時器,顯示程序執行得多,會導致計時誤差大吧
回復

使用道具 舉報

ID:1109793 發表于 2024-5-12 16:31 | 顯示全部樓層
asdadqw2 發表于 2024-5-12 16:23
顯示和計時一起在同一個定時器,顯示程序執行得多,會導致計時誤差大吧

只要你在定時器中斷時間里面做完這些事情就不會影響精度,比如2ms,2ms可以做很多事情了,只要你不用那該死的DELAY
回復

使用道具 舉報

ID:1034262 發表于 2024-5-12 18:39 | 顯示全部樓層
20ms掃描一次按鍵,快到飛起。
回復

使用道具 舉報

ID:1109793 發表于 2024-5-13 07:30 | 顯示全部樓層
coody_sz 發表于 2024-5-12 18:39
20ms掃描一次按鍵,快到飛起。

20ms太長了吧,我都是用1ms定時掃描
回復

使用道具 舉報

ID:161164 發表于 2024-5-13 10:03 | 顯示全部樓層
代碼不全
你只貼了按鍵掃描,沒貼主循環
盲猜主循環有大量代碼
阻塞了按鍵的反應
回復

使用道具 舉報

ID:298743 發表于 2024-5-13 13:52 | 顯示全部樓層
lkc8210 發表于 2024-5-13 10:03
代碼不全
你只貼了按鍵掃描,沒貼主循環
盲猜主循環有大量代碼

主循環有點長,有兩個swich判斷,主要是判斷按鍵返回值的
回復

使用道具 舉報

ID:298743 發表于 2024-5-13 13:54 | 顯示全部樓層
yzwzfyz 發表于 2024-5-11 20:46
中斷服務程序運行時,占用了你的掃描時間,感覺上按鍵不靈敏。是你的時序按排不合理!
如果你寫程序能夠設 ...

怎么用定時器做延時,這個想法不太懂
回復

使用道具 舉報

ID:1120495 發表于 2024-5-13 14:32 | 顯示全部樓層
xiaobendan001 發表于 2024-5-13 07:30
20ms太長了吧,我都是用1ms定時掃描

10ms我覺得差不多
回復

使用道具 舉報

ID:161164 發表于 2024-5-13 14:38 | 顯示全部樓層
asdadqw2 發表于 2024-5-13 13:54
怎么用定時器做延時,這個想法不太懂

你不弄短主循環的耗時,用定時器、中斷也解決不了不靈敏的問題
回復

使用道具 舉報

ID:1120546 發表于 2024-5-13 16:41 | 顯示全部樓層
掃描時間太長了吧
回復

使用道具 舉報

ID:195496 發表于 2024-5-13 16:53 | 顯示全部樓層
程序思路問題,要改進
回復

使用道具 舉報

ID:844772 發表于 2024-5-13 17:13 | 顯示全部樓層
12樓說的對,你就不是延時的問題,你那點延時也去不了抖動。
回復

使用道具 舉報

ID:298743 發表于 2024-5-13 18:23 | 顯示全部樓層
  1. while(1)
  2. {
  3. int temp;
  4. SixCountdown();
  5. ForeAlarm();
  6. temp = key_scan();
  7. ShowTemp();
  8. switch(state)
  9. {
  10. case 0:FlagClear();led_hc595_drive(0xff,0xff,0xff,0xff,0x00);break;
  11. case 1:ShowNormal(); EA=1; break;
  12. case 2:ShowSetHMorMS(); DigdotClose(); EA=1; break;
  13. case 3:ShowEnd(); EA=1; break;
  14. case 4:ShowVolume(); EA=1; break;
  15. case 5:ShowAlarm(); EA=1; break;
  16. default:break;

  17. }

  18. switch(temp)
  19. {
  20. case 0x7D: //1 計時器1 SW1
  21. KeySwitch(0); //按鍵判斷
  22. break;

  23. case 0x3F: //2 計時器3 SW3
  24. KeySwitch(2); //按鍵判斷
  25. break;

  26. case 0xF5: //3 計時器5 SW5
  27. KeySwitch(4); //按鍵判斷
  28. break;

  29. case 0xFC: //4 溫控設置鍵 SW13
  30. break;

  31. case 0xCF: //5 溫度增加 SW12
  32. break;

  33. case 0x7B: //6 計時器2 SW2
  34. KeySwitch(1); //按鍵判斷
  35. break;

  36. case 0x6F: //7 計時器4 SW4
  37. KeySwitch(3); //按鍵判斷
  38. break;

  39. case 0xF3: //8 計時器6 SW6
  40. KeySwitch(5); //按鍵判斷
  41. break;

  42. case 0xFA: //9 除冰 SW14
  43. break;

  44. case 0xBE: //10 溫度減少 SW15
  45. break;

  46. case 0xB7: //11 TIME SW7
  47. timer++;
  48. if((timer==1)&&(ONOFF==0)) //設置時間顯示模式
  49. {
  50. state=2;

  51. }
  52. if((timer==1)&&(ONOFF==1)) //設置時間界面End
  53. {
  54. DigdotClose();
  55. state=3;
  56. }
  57. if(timer==2) //關閉顯示
  58. {
  59. if(state==3)
  60. {
  61. NumExchange(Hset,Mset,H,M);
  62. }
  63. state=0;
  64. timer =0;
  65. }
  66. break;


  67. case 0xE7: //12 REMINDER SW8
  68. alarm++;
  69. DigdotClose();
  70. BlinkClose();
  71. SetTimerClose();
  72. setHM=0;
  73. if(alarm==1)
  74. {
  75. state=5;
  76. }
  77. if(alarm==2)
  78. {
  79. NumExchange(Halarm1,Malarm1,H,M);
  80. }
  81. if(alarm==3)
  82. {
  83. NumExchange(Halarm2,Malarm2,H,M);
  84. }
  85. if(alarm==4)
  86. {
  87. NumExchange(Halarm3,Malarm3,H,M);
  88. alarm=0;
  89. state=0;
  90. }
  91. break;

  92. case 0xDD: //13 ON/OFF SW9

  93. state1=(state1?0:1);
  94. ONOFF++;
  95. state++;

  96. if(ONOFF==1)
  97. {
  98. state=1;
  99. }

  100. if(ONOFF==2)
  101. {
  102. state=0;
  103. ONOFF=0;
  104. }
  105. break;

  106. case 0xDB: //14 INCREASE SW
  107. increase++;
  108. switch(alarm)
  109. {
  110. case 1: adjustAlarm(Halarm1, Malarm1, Blink, SetTimer, 1); break;
  111. case 2: adjustAlarm(Halarm2, Malarm2, Blink, SetTimer, 1); break;
  112. case 3: adjustAlarm(Halarm3, Malarm3, Blink, SetTimer, 1); break;
  113. default: adjustAlarm(H, M, Blink, SetTimer, 1); break;
  114. }
  115. break;
  116. case 0x9F: //15 DECREASE SW11
  117. decrease++;
  118. switch(alarm)
  119. {
  120. case 1: adjustAlarm(Halarm1, Malarm1, Blink, SetTimer, -1); break;
  121. case 2: adjustAlarm(Halarm2, Malarm2, Blink, SetTimer, -1); break;
  122. case 3: adjustAlarm(Halarm3, Malarm3, Blink, SetTimer, -1); break;
  123. default: adjustAlarm(H, M, Blink, SetTimer, -1); break;
  124. }
  125. break;

  126. default:break;
  127. }
復制代碼
回復

使用道具 舉報

ID:298743 發表于 2024-5-13 18:25 | 顯示全部樓層
lkc8210 發表于 2024-5-13 14:38
你不弄短主循環的耗時,用定時器、中斷也解決不了不靈敏的問題

我上傳了主循環的代碼,但是我覺得我的主循環繁瑣,但是執行效率應該不低,switch語句不是用空間換效率的嗎?望各位大佬解答
回復

使用道具 舉報

ID:1109793 發表于 2024-5-13 19:25 | 顯示全部樓層
asdadqw2 發表于 2024-5-13 18:25
我上傳了主循環的代碼,但是我覺得我的主循環繁瑣,但是執行效率應該不低,switch語句不是用空間換效率的 ...

在哪兒?
回復

使用道具 舉報

ID:298743 發表于 2024-5-13 20:11 | 顯示全部樓層

好像還沒審核,我再上傳一次看看
回復

使用道具 舉報

ID:844772 發表于 2024-5-14 09:28 | 顯示全部樓層
Switch沒耗費多少時間,但我看不到你的子程序,你算算這個 ShowTemp(); 要用多少時間。
回復

使用道具 舉報

ID:23640 發表于 2024-5-14 09:39 | 顯示全部樓層
while(KEY_MATRIX_PORT!=0xA9);既然都知道用定時器了,為什么還用這樣的死循環?不理解
回復

使用道具 舉報

ID:1109793 發表于 2024-5-14 13:28 | 顯示全部樓層
可是調用不少子程序呢,包括顯示,所以都加一起就慢了,還有樓上說的死循環
回復

使用道具 舉報

ID:298743 發表于 2024-5-14 22:23 | 顯示全部樓層
yaosongjin 發表于 2024-5-14 09:39
while(KEY_MATRIX_PORT!=0xA9);既然都知道用定時器了,為什么還用這樣的死循環?不理解

那這里應該怎么編寫,真的不太懂,想不明白
回復

使用道具 舉報

ID:298743 發表于 2024-5-14 22:25 | 顯示全部樓層
glinfei 發表于 2024-5-14 09:28
Switch沒耗費多少時間,但我看不到你的子程序,你算算這個 ShowTemp(); 要用多少時間。

void ShowNormal()
{
    unsigned char i,temp1,temp2;
    for (i = 0; i<6; i++)
        {
                if(AlarmOut==1)
                {
                LEDBuf[i * 4] = 17;
                LEDBuf[i * 4 + 1] = 18;
                LEDBuf[i * 4 + 2] = 10;
                LEDBuf[i * 4 + 3] = alarm;
                }else{
                temp1 = UnitSwitch ? M : H;
                temp2 = UnitSwitch ? S : M;
       
                LEDBuf[i * 4] = temp1 / 10;
                LEDBuf[i * 4 + 1] = temp1 % 10;
                LEDBuf[i * 4 + 2] = temp2 / 10;
                LEDBuf[i * 4 + 3] = temp2 % 10;
                        }
    }

}
有show的都是這樣的程序,最多就循環6次
回復

使用道具 舉報

ID:1109793 發表于 2024-5-15 08:59 | 顯示全部樓層
asdadqw2 發表于 2024-5-14 22:25
void ShowNormal()
{
    unsigned char i,temp1,temp2;

LEDbuf為啥這么大?
為啥喜歡大小寫混用?
回復

使用道具 舉報

ID:23640 發表于 2024-5-15 11:39 | 顯示全部樓層
asdadqw2 發表于 2024-5-14 22:23
那這里應該怎么編寫,真的不太懂,想不明白

用if判斷按鍵有沒有松開呀,掃描按鍵可以放在定時器里面,每20MS執行一次
回復

使用道具 舉報

ID:1121518 發表于 2024-5-20 13:02 | 顯示全部樓層
用延遲1ms就很靈敏
回復

使用道具 舉報

ID:1121431 發表于 2024-5-21 00:16 | 顯示全部樓層
減少定時掃描周期
回復

使用道具 舉報

ID:1121431 發表于 2024-5-21 00:22 | 顯示全部樓層
ShowTemp(); 確實一個都花了這么多時間了
回復

使用道具 舉報

ID:161164 發表于 2024-5-22 11:06 | 顯示全部樓層
asdadqw2 發表于 2024-5-13 18:25
我上傳了主循環的代碼,但是我覺得我的主循環繁瑣,但是執行效率應該不低,switch語句不是用空間換效率的 ...

直接在主循環結尾加個引腳取反
用邏輯分析儀或示波器看看取反周期
回復

使用道具 舉報

ID:1121849 發表于 2024-5-22 15:16 | 顯示全部樓層
調整下觸發周期或者就把延遲設置在1ms試試呢
回復

使用道具 舉報

ID:1121518 發表于 2024-5-23 22:08 來自手機 | 顯示全部樓層
中斷可以用少點,因為會占用時間
回復

使用道具 舉報

ID:1123566 發表于 2024-6-3 18:59 | 顯示全部樓層
調整中斷時間
回復

使用道具 舉報

ID:925236 發表于 2024-6-4 19:49 | 顯示全部樓層
你這個如果是數碼管實時顯示的話是會有這個問題,解決辦法低級一點就是把數碼管消抖延時改小,高級一點就不能用延時函數,用時間片輪詢
回復

使用道具 舉報

ID:1125852 發表于 2024-6-18 16:03 | 顯示全部樓層
調整下延遲
回復

使用道具 舉報

ID:1125957 發表于 2024-6-19 09:00 | 顯示全部樓層
八成代碼不對,運行時出錯,重新編程一下代碼
回復

使用道具 舉報

ID:332444 發表于 2024-6-19 10:28 | 顯示全部樓層
  1. if(!k1&&!++Xd)
  2.                 {
  3.                         CKF('S');
  4.                         while(!k1);
  5.                 }
  6.                 if(!k2&&!++Xd)
  7.                 {
  8.                         CKF('X');
  9.                         while(!k2);
  10.                 }
  11.                 if(!k3&&!++Xd)
  12.                 {
  13.                         CKF('L');
  14.                         while(!k3);
  15.                 }
  16.                 if(k1&&k2&&k3)Xd=0;//綜合消抖處理
  17.                         
  18. <span style="background-color: rgb(255, 255, 255);">這樣的消抖處理夠快?代碼是否符合邏輯?</span>
復制代碼

回復

使用道具 舉報

ID:1121811 發表于 2024-6-19 11:08 | 顯示全部樓層
感覺你程序的主循環里東西太多了
回復

使用道具 舉報

ID:1121811 發表于 2024-6-19 11:09 | 顯示全部樓層
主循環內東西太多了吧
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美极品少妇xxxxⅹ免费视频 | 久久久久久久久久久久久久国产 | 精品96久久久久久中文字幕无 | 欧美日韩专区 | 亚洲电影专区 | 日韩在线免费 | 视频一区在线观看 | 国产不卡在线观看 | 精品国产一区二区在线 | 国产一级在线 | 欧美成人免费 | 色一级| 久久久精 | 欧美久久一区二区 | 一级欧美一级日韩片免费观看 | 中文字幕第7页 | 91免费版在线| av入口| 日韩美女一区二区三区在线观看 | 成人高潮片免费视频欧美 | 日韩国产精品一区二区三区 | 91日韩| 日日摸夜夜添夜夜添精品视频 | 欧美视频一区二区三区 | 国产精品成人一区二区 | 国产精品毛片久久久久久久 | www久久久 | 欧美理论片在线 | 亚洲va国产日韩欧美精品色婷婷 | 97精品国产97久久久久久免费 | 成人a在线 | 日韩在线观看中文字幕 | 久久高清 | 999视频| 九九热国产精品视频 | 国产精品一卡 | 国产精品网页 | 天天色官网 | 久久久久国产精品 | 91一区二区三区 | 91精品久久久久久久久久 |