关于矩阵键盘IO口写法

void gpio_keypads_init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 |GPIO_Pin_6 | GPIO_Pin_7;  // KEY_1,KEY_2,KEY_3,KEY_4 列线
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  GPIO_ResetBits(GPIOA, GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 |   GPIO_Pin_2;               // KEY_5,KEY_6,KEY_7 行线
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_SetBits(GPIOB, GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2);
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //KEY_8 行线
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  GPIO_SetBits(GPIOA, GPIO_Pin_8);  

}

在这里IO口的配置没什么问题,行线是配置为推挽输出,列线都是配置为上拉输入。

void keypads_linescan_IPU()
{
  GPIO_InitTypeDef GPIO_InitStructure;
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;               // KEY_5,KEY_6,KEY_7 行线
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_SetBits(GPIOB, GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2);
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  GPIO_SetBits(GPIOA, GPIO_Pin_8); 
}
void keypads_rowscan_IPU()
{
  GPIO_InitTypeDef GPIO_InitStructure;
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 |GPIO_Pin_6 | GPIO_Pin_7;  // KEY_1,KEY_2,KEY_3,KEY_4 列线
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  GPIO_SetBits(GPIOA, GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
}
void keypads_linescan_Out_PP()
{
  GPIO_InitTypeDef GPIO_InitStructure;
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;               // KEY_5,KEY_6,KEY_7 行线
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_ResetBits(GPIOB, GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2);
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  GPIO_ResetBits(GPIOA, GPIO_Pin_8); 
}
void keypads_rowscan_Out_PP()
{
  GPIO_InitTypeDef GPIO_InitStructure;
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 |GPIO_Pin_6 | GPIO_Pin_7;  // KEY_1,KEY_2,KEY_3,KEY_4 列线
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  GPIO_ResetBits(GPIOA, GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
}

然后就是行列分别配置推挽输出和下拉输入。

int key_line = 0;
char key_val;

char keypads_scan()
{
  
  key_val = '$';
  keypads_linescan_IPU();
  keypads_rowscan_Out_PP();
    if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0) == 0){
     keypads_linescan_Out_PP();
     keypads_rowscan_IPU();
        if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4) == 0){
 key_line = 1;
 GPIO_SetBits(GPIOA, GPIO_Pin_4);
}
else if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5) == 0){
 key_line = 2;
 GPIO_SetBits(GPIOA, GPIO_Pin_5);
}
else if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6) == 0){
 key_line = 3;
 GPIO_SetBits(GPIOA, GPIO_Pin_6); 
}
else if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7) == 0){
 key_line = 4;
 GPIO_SetBits(GPIOA, GPIO_Pin_7);
}
else key_line = 0;
switch(key_line)
{
 case 1:key_val = '1';break;
 case 2:key_val = '2';break;
 case 3:key_val = '3';break;
 case 4:key_val = 'A';break;
}
key_line = 0;
keypads_linescan_IPU();
        keypads_rowscan_Out_PP();   
    }
    else if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0){
      keypads_linescan_Out_PP();
      keypads_rowscan_IPU();
   if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4) == 0){
     key_line = 1;
     GPIO_SetBits(GPIOA, GPIO_Pin_4);
   }
   else if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5) == 0){
     key_line = 2;
     GPIO_SetBits(GPIOA, GPIO_Pin_5);
   }
   else if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6) == 0){
     key_line = 3;
     GPIO_SetBits(GPIOA, GPIO_Pin_6); 
   }
   else if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7) == 0){
     key_line = 4;
     GPIO_SetBits(GPIOA, GPIO_Pin_7);
   }
   else key_line = 0;
   switch(key_line)
   {
     case 1:key_val = '4';break;
     case 2:key_val = '5';break;
     case 3:key_val = '6';break;
     case 4:key_val = 'B';break;
   }
   key_line = 0;
            keypads_linescan_IPU();
            keypads_rowscan_Out_PP();         
    }
    else if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_2) == 0){
      keypads_linescan_Out_PP();
      keypads_rowscan_IPU();
   if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4) == 0){
     key_line = 1;
     GPIO_SetBits(GPIOA, GPIO_Pin_4);
   }
   else if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5) == 0){
     key_line = 2;
     GPIO_SetBits(GPIOA, GPIO_Pin_5);
   }
   else if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6) == 0){
     key_line = 3;
     GPIO_SetBits(GPIOA, GPIO_Pin_6); 
   }
   else if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7) == 0){
     key_line = 4;
     GPIO_SetBits(GPIOA, GPIO_Pin_7);
   }
   else key_line = 0;
   switch(key_line)
   {
     case 1:key_val = '7';break;
     case 2:key_val = '8';break;
     case 3:key_val = '9';break;
     case 4:key_val = 'C';break;
   }
 key_line = 0;
          keypads_linescan_IPU();
          keypads_rowscan_Out_PP();  
    }
    else if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8) == 0){
     keypads_linescan_Out_PP();
      keypads_rowscan_IPU();
 if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4) == 0){
   key_line = 1;
   GPIO_SetBits(GPIOA, GPIO_Pin_4);
 }
 else if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5) == 0){
   key_line = 2;
   GPIO_SetBits(GPIOA, GPIO_Pin_5);
 }
 else if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6) == 0){
   key_line = 3;
   GPIO_SetBits(GPIOA, GPIO_Pin_6); 
 }
 else if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7) == 0){
   key_line = 4;
   GPIO_SetBits(GPIOA, GPIO_Pin_7);
 }
 else key_line = 0;
 switch(key_line)
 {
   case 1:key_val = '*';break;
   case 2:key_val = '0';break;
   case 3:key_val = '#';break;
   case 4:key_val = 'D';break;
 }
 key_line = 0;
          keypads_linescan_IPU();
          keypads_rowscan_Out_PP();  
    }
  return key_val;
}

之后就是键盘扫描程序,在检测到行电平之后进入switch,然后将行IO口切换为推挽输出,列IO口切换为上拉输入,这样是最简单但是是最直观的写法。

之前写的键盘扫描没有在检测的时候加入IO口类型切换,虽然测试的时候很正常,但是换了其他的条件之后(比如换了电源,换了其他电路板等情况),就变得不正常,按键在特定情况下才有输出(原因一直还没有排查清楚)。

总之,最妥善的写法还是需要加上IO口状态的切换。


你可能感兴趣的:(STM32杂记)