目前共有4篇帖子。 內容轉換:不轉換▼
 
點擊 回復
311 3
【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成员赋初值。


普中开发板中自带的矩阵键盘例程就显得非常繁琐:

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
(快捷鍵:Ctrl+Enter)
 

本帖信息

點擊數:311 回複數:3
評論數: ?
作者: 巨大八爪鱼
最後回復:巨大八爪鱼
最後回復時間:2016-7-1 12:02
 
©2010-2024 Arslanbar Ver2.0
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。