設置 | 登錄 | 註冊

目前共有8篇帖子。

【STM32入門級程序12】矩陣鍵盤——行掃描法

1樓 巨大八爪鱼 2016-7-1 10:38

【接線】

2樓 巨大八爪鱼 2016-7-1 10:39
【程序】
#include <stm32f10x.h>
// 共陽數碼管段碼表
unsigned char table[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e, 0xbf};
// 用於按鍵延時
void delay(void)
{
 uint16_t i;
 for (i = 0; i < 20000; i++);
}
// 在數碼管上顯示指定段碼
void display(uint8_t n)
{
 GPIO_ResetBits(GPIOB, 0xff00);
 GPIO_SetBits(GPIOB, n << 8);
}
int main(void)
{
 GPIO_InitTypeDef init;
 uint8_t i, temp;
 uint8_t keycode;
 
 // 同時開啟PA和PB的時鐘
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
 
 // PB8~15用作數碼管顯示,為輸出
 init.GPIO_Mode = GPIO_Mode_Out_PP;
 init.GPIO_Pin = 0xff00;
 init.GPIO_Speed = GPIO_Speed_2MHz;
 GPIO_Init(GPIOB, &init);
 
 // PA0~7用作矩陣鍵盤
 init.GPIO_Pin = 0x0f;
 GPIO_Init(GPIOA, &init); // 行線為輸出
 init.GPIO_Mode = GPIO_Mode_IPU; // 沒有信號輸入時,視為輸入了高電平
 init.GPIO_Pin = 0xf0;
 GPIO_Init(GPIOA, &init); // 列線為輸入
 
 display(0xbf); // 默認顯示'-'
 while (1)
 {
  GPIO_ResetBits(GPIOA, 0x0f); // 行線輸出0
  temp = GPIO_ReadInputData(GPIOA) & 0xf0; // 讀列線。如果按鍵沒有按下,則沒有信號輸入(引腳懸空);如果有按鍵按下,則輸入的是按鍵對面輸出的0
  
  // 如果讀出來列線中有為0的位,則表明有按鍵按下
  if (temp != 0xf0)
  {
   // 按鍵消抖
   delay();
   temp = GPIO_ReadInputData(GPIOA) & 0xf0;
   if (temp != 0xf0)
   {
    // 如果確實按下了按鍵
    
    // 行掃描
    for (i = 0; i < 4; i++)
    {
     GPIO_SetBits(GPIOA, 0x0f); // 行線全設為1
     GPIO_ResetBits(GPIOA, 1 << i); // 將要檢查的行設為0
     temp = GPIO_ReadInputData(GPIOA) & 0xf0; // 按同樣的方法讀列線
     if (temp != 0xf0) // 如果不全為1, 則表明該行有按鍵按下
     {
      // 根據temp和i的值計算鍵碼
      temp = ~temp >> 4 & 0x0f;
      keycode = i * 4;
      if (temp == 8)
       keycode += 3;
      else
       keycode += temp >> 1;
      
      // keycode為最終計算出來的鍵碼, 取值範圍是0~15
      // 可在這裡進行按鍵處理
      
      // 顯示鍵碼並退出行掃描
      display(table[keycode]);
      break;
     }
    }
    
    // 等待按鍵釋放
    while ((GPIO_ReadInputData(GPIOA) & 0xf0) != 0xf0);
   }
  }
 }
}

3樓 巨大八爪鱼 2016-7-1 10:40
【講解】
與GPIO操作有關的8個庫函數
https://zh.arslanbar.net/post.php?t=24223
4樓 巨大八爪鱼 2016-7-1 10:40
【電路圖】

5樓 巨大八爪鱼 2016-7-1 10:43
【原理講解】
6樓 巨大八爪鱼 2016-7-1 10:45
7樓 巨大八爪鱼 2016-7-1 10:48
8樓 巨大八爪鱼 2016-7-1 11:09

在行掃描循環中,當1 << i == 二進位的1101時,i = 2
此時讀列線為二進位的1101????,取反後右移四位並屏蔽掉高4位:
temp = ~temp >> 4 & 0x0f;

得:temp = 二進位00000010 = 2

keycode = i * 4 + (temp >> 1) = 8 + 1 = 9

因此按下的鍵為9

內容轉換:

回覆帖子
內容:
用戶名: 您目前是匿名發表。
驗證碼:
看不清?換一張
©2010-2025 Purasbar Ver3.0 [手機版] [桌面版]
除非另有聲明,本站採用知識共享署名-相同方式共享 3.0 Unported許可協議進行許可。