4746|2

452

帖子

0

TA的资源

五彩晶圆(初级)

楼主
 

梦之旅同学松鼠1.0学习笔记(三)之矩阵键盘 [复制链接]

  这几天事情比较多,所以就一直没有更新,呵呵,今天早上没课,把之前写好代码整理一下,顺便说下思路,发上来,供大家参考参考。

  首先,本矩阵键盘硬件连接如下:

 

    思路:

  我的思路如下,首先,把纵向三线设置为推挽输出,然后把横向三线设置为下拉输入,然后读取横向三线的值,如果有接口的读数为1,说明有按键按下了,把该值与0x07相与后放到scana,然后左移4位放到result中,这之后把横向三线设置为推挽输出,纵向三线设置为下拉输入,然后读取纵向三线的值,把相应的键值保存到scanb中,然后通过移位使得低四位表示的是相应的按键所在横向的值,然后与result相或放到result的低四位,这样得到的result高四位就是按键所在纵向的值,低四位就是按键所在横向的值,由此就可以检测到那个按键被按下了。

    效果:按下相应的键盘,四个led灯会显示各种不同的状态,hoho,一共有9种状态。

    #include "stm32f10x_lib.h"
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void delay(void);
u8 KEY_GPIO_Scanning(void);

int main(void)
{
#ifdef DEBUG
  debug();
#endif
 RCC_Configuration();//配置系统时钟
 NVIC_Configuration();  //配置  NVIC 和 Vector Table
GPIO_Configuration(); //使用的GPIO口

  //主循环
  while (1)
  {
    //循环扫描按键 按键按下时 对应的LED亮
    switch ( KEY_GPIO_Scanning() )
    {
      case(0x18):
        GPIO_SetBits(GPIOB, GPIO_Pin_12);
        GPIO_ResetBits(GPIOB, GPIO_Pin_13);
        GPIO_ResetBits(GPIOB, GPIO_Pin_14);
        GPIO_ResetBits(GPIOB, GPIO_Pin_15);
        break;
      case(0x12):
        GPIO_ResetBits(GPIOB, GPIO_Pin_12);
        GPIO_SetBits(GPIOB, GPIO_Pin_13);
        GPIO_ResetBits(GPIOB, GPIO_Pin_14);
        GPIO_ResetBits(GPIOB, GPIO_Pin_15);
        break;
      case(0x14):
        GPIO_SetBits(GPIOB, GPIO_Pin_12);
        GPIO_SetBits(GPIOB, GPIO_Pin_13);
        GPIO_ResetBits(GPIOB, GPIO_Pin_14);
        GPIO_ResetBits(GPIOB, GPIO_Pin_15);
        break;
      case(0x28):
        GPIO_ResetBits(GPIOB, GPIO_Pin_12);
        GPIO_ResetBits(GPIOB, GPIO_Pin_13);
        GPIO_SetBits(GPIOB, GPIO_Pin_14);
        GPIO_ResetBits(GPIOB, GPIO_Pin_15);
        break;
      case(0x24):
        GPIO_SetBits(GPIOB, GPIO_Pin_12);
        GPIO_ResetBits(GPIOB, GPIO_Pin_13);
        GPIO_SetBits(GPIOB, GPIO_Pin_14);
        GPIO_ResetBits(GPIOB, GPIO_Pin_15);
        break;
      case(0x48):
        GPIO_SetBits(GPIOB, GPIO_Pin_12);
        GPIO_SetBits(GPIOB, GPIO_Pin_13);
        GPIO_SetBits(GPIOB, GPIO_Pin_14);
        GPIO_ResetBits(GPIOB, GPIO_Pin_15);
        break;
      case(0x42):
        GPIO_ResetBits(GPIOB, GPIO_Pin_12);
        GPIO_ResetBits(GPIOB, GPIO_Pin_13);
        GPIO_ResetBits(GPIOB, GPIO_Pin_14);
        GPIO_SetBits(GPIOB, GPIO_Pin_15);
        break;
      case(0x44):
        GPIO_SetBits(GPIOB, GPIO_Pin_12);
        GPIO_ResetBits(GPIOB, GPIO_Pin_13);
        GPIO_ResetBits(GPIOB, GPIO_Pin_14);
        GPIO_SetBits(GPIOB, GPIO_Pin_15);
        break;
      case(0x22):
        GPIO_SetBits(GPIOB, GPIO_Pin_12);
        GPIO_SetBits(GPIOB, GPIO_Pin_13);
        GPIO_SetBits(GPIOB, GPIO_Pin_14);
        GPIO_SetBits(GPIOB, GPIO_Pin_15);
        break;
    }
   
  }
}
void RCC_Configuration(void)
{
  ErrorStatus HSEStartUpStatus;
  RCC_DeInit(); //将外设 RCC寄存器重设为缺省值
  RCC_HSEConfig(RCC_HSE_ON); //设置外部高速晶振(HSE)
  HSEStartUpStatus = RCC_WaitForHSEStartUp();//等待 HSE 起振

  if(HSEStartUpStatus == SUCCESS)
  {
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//预取指缓存使能
    FLASH_SetLatency(FLASH_Latency_2);//设置代码延时值  FLASH_Latency_2  2 延时周期
    RCC_HCLKConfig(RCC_SYSCLK_Div1); //设置 AHB 时钟(HCLK) RCC_SYSCLK_Div1  AHB 时钟 =  系统时钟
    RCC_PCLK2Config(RCC_HCLK_Div2);//设置高速 AHB 时钟(PCLK2)  RCC_HCLK_Div2  APB1 时钟  = HCLK / 2 
    RCC_PCLK1Config(RCC_HCLK_Div2);   //设置低速 AHB 时钟(PCLK1)RCC_HCLK_Div2  APB1 时钟  = HCLK / 2
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); // PLLCLK = 8MHz * 9 = 72 MHz 设置 PLL 时钟源及倍频系数
    RCC_PLLCmd(ENABLE);//使能或者失能 PLL
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) //等待指定的 RCC 标志位设置成功 等待PLL初始化成功
    {
    }
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//设置系统时钟(SYSCLK) 设置PLL为系统时钟源
    while(RCC_GetSYSCLKSource() != 0x08)  //等待PLL成功用作于系统时钟的时钟源 0x00:HSI 作为系统时钟  0x04:HSE作为系统时钟   0x08:PLL作为系统时钟 
    {
    }
  }
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能或者失能 APB2 外设时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
}
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15 ;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  //LED端口设置为 推挽输出
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  //键盘 横向 三线
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 ;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  //键盘 纵向 三线
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
 
}

void GPIO_Reconfiguration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  //键盘 横向 三线
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 ;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  //键盘 纵向 三线
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
 
}


/*******************************************************************************
* Function Name  : KEY_GPIO_Scanning
* Description    : 依次扫描4个按键 使用一个u8变量的低4位存储扫描结果
* Input          : None
* Output         : None
* Return         : 扫描的结果 有效数据是低4位
*******************************************************************************/
u8 KEY_GPIO_Scanning(void)
{
 u8 result;
 u8 scana;  //单个按键扫描变量
       u8 scanb;  //四个按键总的情况变量 scan_sum低四位的每一位对应一个按键

 scana = 0;
        scanb = 0;

 result = 0;
 
 GPIO_SetBits( GPIOA, GPIO_Pin_3);
 GPIO_SetBits( GPIOB, GPIO_Pin_1);
 GPIO_SetBits( GPIOB, GPIO_Pin_2);
 

        //扫描按键
 scana = GPIO_ReadInputData(GPIOA);
 scana = scana &  0x07;
 
        //如果按键按下 则延迟 再扫描 然后根据判断处理
  if(scana)
   {
   delay();
  scana = GPIO_ReadInputData(GPIOA);
  scana = scana &  0x07;

  //翻转,二次读取

  GPIO_Reconfiguration();
  GPIO_SetBits( GPIOA, GPIO_Pin_0);
  GPIO_SetBits( GPIOA, GPIO_Pin_1);
  GPIO_SetBits( GPIOA, GPIO_Pin_2);
                GPIO_ResetBits( GPIOA, GPIO_Pin_3);
                GPIO_ResetBits( GPIOB, GPIO_Pin_1);
                GPIO_ResetBits( GPIOB, GPIO_Pin_2);

  scanb = GPIO_ReadInputData(GPIOA);
  scanb = scanb &  (1<<3);

  scanb |= ( GPIO_ReadInputData(GPIOB) & ( (1<<1) | (1<<2) ) ) ;

  result = scana << 4;
  result |= scanb;

  GPIO_Configuration();
  
   }
 return result;
}

void NVIC_Configuration(void)
{
#ifdef  VECT_TAB_RAM
  /* Set the Vector Table base location at 0x20000000 */
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else  /* VECT_TAB_FLASH  */
  /* Set the Vector Table base location at 0x08000000 */
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
}


void delay()
{
  int i;
  for (i=0; i<0xffff; i++)
    ;
}

#ifdef  DEBUG
void assert_failed(u8* file, u32 line)
{
  while (1)
  {
  }
}
#endif

 

此帖出自stm32/stm8论坛

最新回复

   详情 回复 发表于 2012-3-1 15:03
点赞 关注
个人签名人生苦短,何必为声名所累,放开自己心态,去追求自己想要的梦想去吧!http://pytech-inc.taobao.com/
 

回复
举报

1059

帖子

0

TA的资源

纯净的硅(高级)

沙发
 
嘿嘿 顶一下~好久没有折腾STM32了 有啥好玩的程序分享下啊~
此帖出自stm32/stm8论坛
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
 
此帖出自stm32/stm8论坛
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表