我刚刚写了个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;
}
}
}
}
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口状态 那块有问题
你这一会儿库函数一会寄存器的,我看着有点头晕,用寄存器还要一个个位去看设置的对不对,用库函数不是更好?可以让别人看得不那么费劲,自己查原因也快点儿啊。当然,寄存器也要懂,我觉得用库函数方便一点
理论上没问题 那就是没问题了