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

標(biāo)題: 關(guān)于矩陣鍵盤代碼優(yōu)化問題 [打印本頁]

作者: yuyash    時(shí)間: 2024-11-29 13:36
標(biāo)題: 關(guān)于矩陣鍵盤代碼優(yōu)化問題
我是 51 單片機(jī)新手,在學(xué)習(xí) [bilibili 51教程[6-1] 矩陣鍵盤] (https://www.bilibili.com/video/B ... eopod.episodes&p=15) 時(shí)發(fā)現(xiàn)這段代碼有點(diǎn)冗余,可以優(yōu)化一下嗎?

原視頻代碼類似以下:

```c
# ifndef MATRIX_H
# define MATRIX_H

# include "8051.h"
# include "delay.h"

unsigned char matrix_keydown()
{
  /*
  unsigned char i;
  for (i = 3; i > 0; --i)
  {
    P1 = 0xff;
    // 我好煩啊,這個(gè)P1到底怎么回事
    P1 = P1 ^ (0x01 << i + 4);

    if (P1_7 == 0) {delay(3); while (P1_7 == 0); delay(3); return 1 + (3 - i);}
    if (P1_6 == 0) {delay(3); while (P1_6 == 0); delay(3); return 5 + (3 - i);}
    if (P1_5 == 0) {delay(3); while (P1_5 == 0); delay(3); return 9 + (3 - i);}
    if (P1_4 == 0) {delay(3); while (P1_4 == 0); delay(3); return 13 + (3 - i);}
  }
  */
  P1 = 0xff;
  P1_3 = 0;
  if (P1_7 == 0) {delay(3); while (P1_7 == 0); delay(3); return 1;}
  if (P1_6 == 0) {delay(3); while (P1_6 == 0); delay(3); return 5;}
  if (P1_5 == 0) {delay(3); while (P1_5 == 0); delay(3); return 9;}
  if (P1_4 == 0) {delay(3); while (P1_4 == 0); delay(3); return 13;}

  P1 = 0xff;
  P1_2 = 0;
  if (P1_7 == 0) {delay(3); while (P1_7 == 0); delay(3); return 2;}
  if (P1_6 == 0) {delay(3); while (P1_6 == 0); delay(3); return 6;}
  if (P1_5 == 0) {delay(3); while (P1_5 == 0); delay(3); return 10;}
  if (P1_4 == 0) {delay(3); while (P1_4 == 0); delay(3); return 14;}

  P1 = 0xff;
  P1_1 = 0;
  if (P1_7 == 0) {delay(3); while (P1_7 == 0); delay(3); return 3;}
  if (P1_6 == 0) {delay(3); while (P1_6 == 0); delay(3); return 7;}
  if (P1_5 == 0) {delay(3); while (P1_5 == 0); delay(3); return 11;}
  if (P1_4 == 0) {delay(3); while (P1_4 == 0); delay(3); return 15;}

  P1 = 0xff;
  P1_0 = 0;
  if (P1_7 == 0) {delay(3); while (P1_7 == 0); delay(3); return 4;}
  if (P1_6 == 0) {delay(3); while (P1_6 == 0); delay(3); return 8;}
  if (P1_5 == 0) {delay(3); while (P1_5 == 0); delay(3); return 12;}
  if (P1_4 == 0) {delay(3); while (P1_4 == 0); delay(3); return 16;}

  return 0;
}

# endif

```
可以看出代碼量太長了。

我想進(jìn)行優(yōu)化類似以下:
```C
# ifndef MATRIX_H
# define MATRIX_H

# include "delay.h"

unsigned char math_key()
{
  // 簡單的算法在哪里?
  // 不能將 P1 預(yù)設(shè)為 0x0f
  // 先暴力過了
  unsigned char S2, S1;
  S2 = P1 & 0x0f;
  S2 = P1 - 1 << 2 | 1;
  S1 = P1 & 0xf0 >> 4;
  return S2 + S1;
  // return ((P1 & 0x0f) - 1 << 2 | 1) + (P1 & 0xf0 >> 4);
}

unsigned char matrix_keydown()
{
  unsigned char key_number = 0;
  // 當(dāng) P1 被按下時(shí)用 math_key() 算出按鍵位置分別對應(yīng) 1-16
  if (P1 != 0xff)
  {
    delay(3);
    key_number = math_key();
  }
  return key_number;
}

# endif
```
可惜失敗了。。。
自己試錯(cuò)了許久,有點(diǎn)似懂非懂原因,覺得這個(gè)失敗有點(diǎn)知識的缺陷,可以有版友幫助解答一下嗎?
可以指點(diǎn)一下優(yōu)化的方向嗎?



作者: xiaobendan001    時(shí)間: 2024-11-29 16:14
不是有個(gè)反轉(zhuǎn)法嗎?
作者: lkc8210    時(shí)間: 2024-11-29 16:35
  1.                         switch(Keypad)
  2.                         {
  3.                                 case 0x0E:KeyVal=1;break;
  4.                                 case 0x0D:KeyVal=2;break;
  5.                                 case 0x0B:KeyVal=3;break;
  6.                                 case 0x07:KeyVal=4;break;
  7.                         }
  8.                         Keypad = 0xF0;
  9.                         _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
  10.                         switch(Keypad)
  11.                         {
  12.                                 case 0xE0:KeyVal+=0;break;
  13.                                 case 0xD0:KeyVal+=4;break;
  14.                                 case 0xB0:KeyVal+=8;break;
  15.                                 case 0x70:KeyVal+=12;break;
  16.                         }
復(fù)制代碼

作者: WL0123    時(shí)間: 2024-11-29 21:41
給你一個(gè)簡單的4*4矩陣按鍵示例參考


  1. #include <reg51.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. uchar  code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
  5. uchar KeyValue=0;//鍵值變量


  6. void delayms(uint k)
  7. {
  8.         uint i,j;
  9.         for(i=k;i>0;i--)
  10.                 for(j=115;j>0;j--);
  11. }

  12. void key_scan()                                        //按鍵掃描程序
  13. {
  14.         static bit sign=0;                        //位變量
  15.         static unsigned int count=0;//計(jì)數(shù)變量
  16.         P3=0xf0;                                        //賦值P3 1111 0000
  17.         if(P3!=0xf0)                                //檢測有按鍵按下
  18.         {
  19.                 if(++count>=20 && sign==0)//計(jì)數(shù)消抖
  20.                 {                       
  21.                         sign=1;                        //按鍵自鎖標(biāo)志置1
  22.                         switch(P3)
  23.                         {
  24.                                 case(0Xe0):KeyValue = 1;break;
  25.                                 case(0Xd0):KeyValue = 2;break;
  26.                                 case(0Xb0):KeyValue = 3;break;
  27.                                 case(0X70):KeyValue = 4;break;
  28.                         }
  29.                         P3=0x0f;                        //賦值P3 0000 1111
  30.                         switch(P3)
  31.                         {
  32.                                 case(0X0e):KeyValue+= 0;break;
  33.                                 case(0X0d):KeyValue+= 4;break;
  34.                                 case(0X0b):KeyValue+= 8;break;
  35.                                 case(0X07):KeyValue+=12;break;
  36.                         }
  37.                 }
  38.         }
  39.         else                                                //鍵抬起
  40.         {
  41.                 sign=0;                                //按鍵自鎖標(biāo)志清0
  42.                 count=0;                                //消抖計(jì)數(shù)清0
  43.         }
  44. }

  45. void display()                                        //數(shù)碼管顯示程序
  46. {
  47.         static uchar i=0;
  48.         P0=0x00;
  49.         P2=~(0x01<<i);
  50.         if(i)P0=table[KeyValue%10];
  51.         else P0=table[KeyValue/10];
  52.         i=++i%2;
  53. }

  54. void main()                                                //主函數(shù)
  55. {
  56.         while(1)
  57.         {
  58.                 key_scan();                                //按鍵掃描程序
  59.                 display();                                //數(shù)碼管顯示鍵值1~16
  60.                 delayms(1);                                //延時(shí)控制主循環(huán)周期約1ms
  61.         }
  62. }
復(fù)制代碼




作者: zpwgf    時(shí)間: 2024-12-2 09:15
#include <stdint.h>

// 假設(shè)你有一個(gè)適當(dāng)?shù)?delay 函數(shù)
void delay(uint16_t ms);

// 假設(shè) P1 和 P1_x (x = 0, 1, 2, 3, 4, 5, 6, 7) 已經(jīng)被定義并連接到相應(yīng)的硬件
#define ROW_COUNT 4
#define COL_COUNT 4

// 矩陣鍵盤掃描函數(shù)
unsigned char matrix_keydown()
{
    uint8_t row, col;
    static const uint8_t rowPins[] = {P1_0, P1_1, P1_2, P1_3};
    static const uint8_t colPins[] = {P1_4, P1_5, P1_6, P1_7};
    static const uint8_t keyMap[ROW_COUNT][COL_COUNT] = {
        {1, 5, 9, 13},
        {2, 6, 10, 14},
        {3, 7, 11, 15},
        {4, 8, 12, 16}
    };

    for (row = 0; row < ROW_COUNT; ++row)
    {
        P1 = 0xFF; // 設(shè)置所有列為高電平
        rowPins[row] = 0; // 將當(dāng)前行設(shè)為低電平

        for (col = 0; col < COL_COUNT; ++col)
        {
            if (colPins[col] == 0) // 檢查是否有列被拉低
            {
                delay(3); // 消抖
                while (colPins[col] == 0); // 等待按鍵釋放
                delay(3); // 消抖
                return keyMap[row][col]; // 返回按鍵值
            }
        }

        rowPins[row] = 1; // 恢復(fù)當(dāng)前行為高電平,為下一行做準(zhǔn)備
    }

    return 0; // 沒有按鍵被按下
}
可以嘗試一下這個(gè)方法,沒驗(yàn)證過,
作者: qinlu123    時(shí)間: 2024-12-5 13:47
代碼量長不是問題,問題是代碼里while阻塞,這樣你的單片機(jī)再跑其他任務(wù)就非常受影響
作者: zh080223    時(shí)間: 2024-12-5 18:30
#ifndef MATRIX_H
#define MATRIX_H

#include "8051.h"
#include "delay.h"

unsigned char matrix_keydown() {
    unsigned char row, col;
    unsigned char key_code = 0;

    for (row = 0; row < 4; ++row) {
        P1 = 0xff; // Set all rows high
        P1_3 = (row & 0x01) ? 1 : 0; // Select row
        P1_2 = (row & 0x02) ? 1 : 0;
        P1_1 = (row & 0x04) ? 1 : 0;
        P1_0 = (row & 0x08) ? 1 : 0;

        for (col = 0; col < 4; ++col) {
            if ((P1 >> (col + 4)) & 0x01) { // Check column
                delay(3); // Debounce
                if ((P1 >> (col + 4)) & 0x01) { // Double check
                    key_code = 1 + row * 4 + col; // Calculate key code
                    while ((P1 >> (col + 4)) & 0x01); // Wait for key release
                    delay(3); // Debounce
                    return key_code;
                }
            }
        }
    }

    return 0; // No key pressed
}

#endif
這樣會好一點(diǎn),你參考一下
作者: 空白名    時(shí)間: 2024-12-6 10:05
為什么不放在定時(shí)器里去做按鍵掃描,阻塞的程序浪費(fèi)資源啊,既然是優(yōu)化那么實(shí)時(shí)行也是程序要考慮的點(diǎn)啊,不太贊同阻塞的做法

作者: qinlu123    時(shí)間: 2024-12-7 09:44
空白名 發(fā)表于 2024-12-6 10:05
為什么不放在定時(shí)器里去做按鍵掃描,阻塞的程序浪費(fèi)資源啊,既然是優(yōu)化那么實(shí)時(shí)行也是程序要考慮的點(diǎn)啊,不 ...

小伙子我看好你




歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 日韩av.com | 精品国产乱码久久久久久中文 | 午夜一区二区三区在线观看 | 国产在线小视频 | 亚洲 日本 欧美 中文幕 | 97超碰免费 | 少妇久久久 | 国产伦精品一区二区三区精品视频 | www.9191 | 亚洲综合区| av中文字幕在线 | 国产精品福利在线观看 | 2021天天躁夜夜看 | 国产91视频免费 | 国产成人福利在线 | 久久一本 | 日韩精品一区二区三区视频播放 | 在线看亚洲 | 亚洲午夜精品 | 欧美黑人一区 | 国产欧美日韩精品一区二区三区 | 欧美日韩高清免费 | 欧美在线a | 国产精品日韩欧美 | 日韩成人在线播放 | 黑人巨大精品欧美一区二区免费 | 日韩久久久久 | 婷婷综合| 成人精品一区 | 精品久久久久久18免费网站 | 国产欧美一级 | 亚洲国产精品va在线看黑人 | 亚洲视频免费 | 视频一区二区中文字幕 | 99久久婷婷国产综合精品 | 亚洲性人人天天夜夜摸 | 久久一起草 | 国产乱码精品一区二区三区五月婷 | 国产美女一区二区 | 亚洲www啪成人一区二区 | 久久精品国产一区二区三区 |