設置 | 登錄 | 註冊

作者共發了4篇帖子。

【STM32入門級程序13】矩陣鍵盤——線反轉法

1樓 巨大八爪鱼 2016-7-1 11:57
線反轉法也是識別閉合鍵的一種常用方法,該法比行掃描速度快。
先將行線作為輸出線,列線作為輸入線,行線輸出全0信號,讀入列線的值,那麼在閉合鍵所在的列線上的值必為0;然後從列線輸出全0信號,再讀取行線的輸入值,閉合鍵所在的行線值必為0。這樣,當一個鍵被按下時,必定可讀到一對唯一的行列值。再由這一對行列值可以求出閉合鍵所在的位置。


2樓 巨大八爪鱼 2016-7-1 11:57
3樓 巨大八爪鱼 2016-7-1 11:58
【程序】
#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 in, out;
 uint8_t col, row;
 uint8_t i, keycode;
 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
 
 // 默認輸入/輸出模式
 in.GPIO_Mode = GPIO_Mode_IPU;
 out.GPIO_Mode = GPIO_Mode_Out_PP;
 out.GPIO_Speed = GPIO_Speed_2MHz;
 
 // PB8~15用作數碼管顯示,為輸出
 out.GPIO_Pin = 0xff00;
 GPIO_Init(GPIOB, &out);
 
 display(0xbf); // 默認顯示'-'
 while (1)
 {
  // 第一步:和行掃描法一樣,先將行線作為輸出線, 列線作為輸入線
  out.GPIO_Pin = 0x0f;
  GPIO_Init(GPIOA, &out);
  in.GPIO_Pin = 0xf0;
  GPIO_Init(GPIOA, &in);
  GPIO_ResetBits(GPIOA, 0x0f); // 行線全輸出0
  col = GPIO_ReadInputData(GPIOA) & 0xf0; // 讀取列線的值
  
  // 按鍵消抖
  if (col != 0xf0)
  {
   delay();
   col = GPIO_ReadInputData(GPIOA) & 0xf0;
   if (col != 0xf0)
   {
    // 第二步:從列線輸出全0信號,再讀取行線的輸入值
    out.GPIO_Pin = 0xf0;
    GPIO_Init(GPIOA, &out);
    in.GPIO_Pin = 0x0f;
    GPIO_Init(GPIOA, &in);
    GPIO_ResetBits(GPIOA, 0xf0);
    row = GPIO_ReadInputData(GPIOA) & 0x0f;
    
    // 行線有非1值的情況下才繼續
    // 防止出現按下了6顯示的卻是2的錯誤情況
    if (row != 0x0f)
    {
     // 第三步:計算鍵碼
     row = ~row & 0x0f;
     col = ~col >> 4 & 0x0f;
     keycode = 0;
     for (i = 0; i < 4; i++)
     {
      if (row & 1)
      {
       keycode = i * 4;
       break;
      }
      row >>= 1;
     }
     for (i = 0; i < 4; i++)
     {
      if (col & 1)
      {
       keycode += i;
       break;
      }
      col >>= 1;
     }
     display(table[keycode]);
     
     while ((GPIO_ReadInputData(GPIOA) & 0x0f) != 0x0f);
    }
   }
  }
 }
}

4樓 巨大八爪鱼 2016-7-1 12:02

【技巧】
為了方便進行I/O口輸入輸出的切換,可以定義兩個GPIO_InitTypeDef結構體類型的變量:in和out,並給speed和mode成員賦初值。


普中開發板中自帶的矩陣鍵盤例程就顯得非常繁瑣:

內容轉換:

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