微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 我刚刚写了个STM32矩阵按键扫描程序 ,理论上没问题了 就是不正确 请大家指导一下

我刚刚写了个STM32矩阵按键扫描程序 ,理论上没问题了 就是不正确 请大家指导一下

时间:10-02 整理:3721RD 点击:
这是按键初始化  和按键扫描程序

void KEY_Init()
{
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
        GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
       
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_8;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
       
       
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
       
       
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
       
       
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
          
               
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_12;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_ResetBits(GPIOB,GPIO_Pin_12);
               
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_13;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_ResetBits(GPIOB,GPIO_Pin_13);
               
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_14;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_ResetBits(GPIOB,GPIO_Pin_14);       
               
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_15;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_ResetBits(GPIOB,GPIO_Pin_15);
       
       
       
       
       
       
       
       
}


void KEY_Scan(void)
{       
       
           GPIOB->ODR=0x0F18;
           if(GPIOB->IDR!=0x0F18)
                 {
                          delay_ms(50);
                         if(GPIOB->IDR!=0x0F18)
                         {
         
         
         GPIOB->ODR=0X0100;
                           switch(GPIOB->IDR&0XF000)
                                 {
                                         case 0x1000 :  KeyValue=0;break;
                                         case 0x2000 :  KeyValue=1;break;
                                         case 0x4000 :  KeyValue=2;break;
                                         case 0x8000 :  KeyValue=3;break;
                                         default :break;
                                 }
                           GPIOB->ODR=0X0200;
                                 switch(GPIOB->IDR&0XF000)
                                 {
                 case 0x1000 :  KeyValue=4;break;
                                         case 0x2000 :  KeyValue=5;break;
                                         case 0x4000 :  KeyValue=6;break;
                                         case 0x8000 :  KeyValue=7;break;
                                         default :break;
                                 }
       
                                  GPIOB->ODR=0X0400;
                                 switch(GPIOB->IDR&0XF000)
                                 {
                 case 0x1000 :  KeyValue=8;break;
                                         case 0x2000 :  KeyValue=9;break;
                                         case 0x4000 :  KeyValue=10;break;
                                         case 0x8000 :  KeyValue=11;break;
                                         default :break;
                                 }
                                 
                                   GPIOB->ODR=0X0800;
                                 switch(GPIOB->IDR&0XF000)
                                 {
                 case 0x1000 :  KeyValue=12;break;
                                         case 0x2000 :  KeyValue=13;break;
                                         case 0x4000 :  KeyValue=14;break;
                                         case 0x8000 :  KeyValue=15;break;
                                         default :break;
                                 }
                         }
                 }
         }
               

stm32f103zct6的PA12 13等几个IO在MCU复位后默认为JTAG复用模式,不能当做普通IO来用,需要关闭复用时钟,你的代码里是开启的,这样PA12这几个口就不能用,还有,按键扫描的输入口要设置为IPU(上拉输入),因为浮空输入的电平值不确定,不能通过扫描其值来确认按键是否按下,供参考!

不好意思,我看错了,你的JTAG关闭了。你要检查两个方面:1.JTAG是否关闭成功;2.设置为浮空输入是否能达到要求

我都试过了,按下的时候  设置为浮空输入的IO口的电平会被拉高。现在我怀疑是   读取  IO口状态   那块有问题

你这一会儿库函数一会寄存器的,我看着有点头晕,用寄存器还要一个个位去看设置的对不对,用库函数不是更好?可以让别人看得不那么费劲,自己查原因也快点儿啊。当然,寄存器也要懂,我觉得用库函数方便一点

理论上没问题  那就是没问题了

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top