并入传出芯片(IO口更少的情况)
行列反转方式
a. 将PA0PA3设置为上拉输入,PA4PA7设置为推挽输出(底电平) 确定列
PA3~PA0 | 效果 |
---|---|
1111(0xF) | 无 |
1110(0xE) | 第一列 |
1101(0xD) | 第二列 |
1011(0xB) | 第三列 |
0111(0x7) | 第四列 |
b. 将PA4-PA7设置为上拉输入,PA0-PA3设置为推挽输出(底电平) 确定行
PA7~PA4 | 效果 |
---|---|
1111(0xF0) | 无 |
1110(0xE0) | 第一行 |
1101(0xD0) | 第二行 |
1011(0xB0) | 第三行 |
0111(0x70) | 第四行 |
根据扫描结果来确定键值
键值 = (4 * (列数 - 1)) + 行数
// 设计一个函数,实现返回按下按键的键值
### 伪代码
1. 开启PA端口的时钟
2. 将PA0~PA3设置为上拉输入,PA4~PA7设置为推挽输出(底电平)
3. 读取PA0~PA3的电平状态
if (PA0~PA3 != 0xf)
{
// 消抖
if (PA0~PA3 != 0xf)
{
switch(PA0~PA3)
{
case 0xE: num = 0;
case 0xD: num = 4;
case 0xB: num = 8;
case 0x7: num = 12;
}
}
}
else
{
return 0;
}
4. 电平反转 将PA4-PA7设置为上拉输入,PA0-PA3设置为推挽输出(底电平)
5. 读取PA4~PA7的电平状态
if (PA4~PA7 != 0xf)
{
// 消抖
if (PA0~PA3 != 0xf)
{
switch(PA0~PA3)
{
case 0xE: num += 1;
case 0xD: num += 2;
case 0xB: num += 3;
case 0x7: num += 4;
}
}
}
else
{
return 0;
}
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 将这个放到Main中,防止重复
int Matrix_Key_Scan(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
u8 key, val = 0;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_WriteBit(GPIOA, GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7, Bit_RESET);
// GPIO_ReadOutputDataBit 库函数
if((GPIOA->IDR & 0xF) != 0xF) // 寄存器操作
{
Delay_us(1000); // 消抖
key = GPIOA->IDR & 0xF;
if(key != 0xF)
{
switch(key)
{
case 0xE: val = 0; break;
case 0xD: val = 4; break;
case 0xB: val = 8; break;
case 0x7: val = 12; break;
default: break;
}
}
else
return 0;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //修改的地方
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_WriteBit(GPIOA, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3, Bit_RESET);
if((GPIOA->IDR & 0xF0) != 0xF0)
{
Delay_us(1000);
key = GPIOA->IDR & 0xF0;
if(key != 0xF0)
{
switch(key)
{
case 0xE0: val += 1; break;
case 0xD0: val += 2; break;
case 0xB0: val += 3; break;
case 0x70: val += 4; break;
default: break;
}
}
else
return 0;
}
else
return 0;
while((GPIOA->IDR & 0xF0) != 0xF0);
return val;
}
else
return 0;
}