问题:STM32用7个IO口控制27个按键,在KEIL调试时所有按键都能实现,但是实际中只有部分按键有效。
原理图:
key1-key7接单片机PE0-PE6。
思路:key2-7循环分别输出,其他5个IO口做检测。例:key2输出,key3-key7输入:
按下s6,key7输入高电平,其他4个IO口为低电平;
按下s11,key6输入高电平,其他4个IO口为低电平;
程序:
#include <STM32F10X_GPIO.h>
#include "stm32f10x_rcc.h"
#include "delay.h"
typedef unsigned short u16;
typedef unsigned short uint;
typedef unsigned char uchar;
typedef unsigned int uint32;
void init_key_gpio_1(void) //PE1输出,其他输入模式
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
void init_key_gpio_2(void) //PE2输出,其他输入模式
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
void init_key_gpio_3(void) //PE3输出,其他输入模式
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_3 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
void init_key_gpio_4(void) //PE4输出,其他输入模式
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_4 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_1 | GPIO_Pin_5 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
void init_key_gpio_5(void) //PE5输出,其他输入模式
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_5 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_1 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
void init_key_gpio_6(void) //PE6输出,其他输入模式
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_6 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
uchar key_scan(void)
{
uchar no=1;
u16 tem;
while(1)
{
GPIO_SetBits(GPIOE,GPIO_Pin_0); //PE0置1
GPIO_ResetBits(GPIOE,GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 ) ;//PE1-PE6置0(初始化)
switch (no)
{
case 1 :
init_key_gpio_1(); //PE1输出,其他输入模式
GPIO_SetBits(GPIOE,GPIO_Pin_1); //PE1置1
tem = (GPIO_ReadInputData(GPIOE) & 0x00FF) | 0x80 ; //读取按键
// delay(50);
while (((GPIO_ReadInputData(GPIOE) & 0x00FF) | 0x80 ) != 0x83 ){} //检测按键松开
switch(tem)
{
case 0X87:
buzz();
return '1';
case 0X86:
buzz();
return 'A';
case 0X8B:
buzz();
return '2';
case 0X8A:
buzz();
return 'B';
case 0X93:
buzz();
return '3';
case 0X92:
buzz();
return 'C';
case 0XA3:
buzz();
return '4';
case 0XA2:
buzz();
return 'D';
case 0XC3:
buzz();
return '5';
case 0XC2:
buzz();
return 'E';
default:
break;
}
break;
case 2 :
init_key_gpio_2();
GPIO_SetBits(GPIOE,GPIO_Pin_2); //PE2置1
tem = (GPIO_ReadInputData(GPIOE) & 0x00FF) | 0x80 ; //读取按键
// delay(50);
while (((GPIO_ReadInputData(GPIOE) & 0x00FF) | 0x80 ) != 0x85 ){} //检测按键松开
switch(tem)
{
case 0X87:
buzz();
return '6';
case 0X86:
buzz();
return 'J';
case 0X8D:
buzz();
return '7';
case 0X8C:
buzz();
return 'K';
case 0X95:
buzz();
return '8';
case 0X94:
buzz();
return 'L';
case 0XA5:
buzz();
return '9';
case 0XA4:
buzz();
return 'M';
case 0XC5:
buzz();
return '0';
case 0XC4:
buzz();
return 'N';
default:
break;
}
break;
case 3 :
init_key_gpio_3();
GPIO_SetBits(GPIOE,GPIO_Pin_3); //PE3置1
tem = (GPIO_ReadInputData(GPIOE) & 0x00FF) | 0x80 ; //读取按键
// delay(50);
while (((GPIO_ReadInputData(GPIOE) & 0x00FF) | 0x80 ) != 0x89 ){} //检测按键松开
switch(tem)
{
case 0X8B:
buzz();
return 'e';
case 0X8A:
buzz();
return 'F';
case 0X8D:
buzz();
return 'x';
case 0X8C:
buzz();
return 'O';
case 0X99:
buzz();
return 'c';
case 0X98:
buzz();
return 'T';
case 0XA9:
buzz();
return 's';
case 0XA8:
buzz();
return 'U';
case 0XC9:
buzz();
return 'o';
case 0XC8:
buzz();
return 'W';
default:
break;
}
break;
case 4 :
init_key_gpio_4();
GPIO_SetBits(GPIOE,GPIO_Pin_4); //PE4置1
tem = (GPIO_ReadInputData(GPIOE) & 0x00FF) | 0x80 ; //读取按键
// delay(50);
while (((GPIO_ReadInputData(GPIOE) & 0x00FF) | 0x80 ) != 0x91 ){} //检测按键松开
switch(tem)
{
case 0X93:
buzz();
return 'u';
case 0X92:
buzz();
return 'H';
case 0X95:
buzz();
return 'd';
case 0X94:
buzz();
return 'Q';
case 0X99:
buzz();
return 'l';
case 0X98:
buzz();
return 'G';
case 0XB1:
buzz();
return 'r';
case 0XB0:
buzz();
return 'I';
case 0XD1:
buzz();
return '-';
case 0XD0:
buzz();
return 'V';
default:
break;
}
break;
case 5 :
init_key_gpio_5();
GPIO_SetBits(GPIOE,GPIO_Pin_5); //PE5置1
tem = (GPIO_ReadInputData(GPIOE) & 0x00FF) | 0x80 ; //读取按键
// delay(50);
while (((GPIO_ReadInputData(GPIOE) & 0x00FF) | 0x80 ) != 0xA1 ){} //检测按键松开
switch(tem)
{
case 0XA3:
buzz();
return '.';
case 0XA2:
buzz();
return 'S';
case 0XA5:
buzz();
return 'b';
case 0XA4:
buzz();
return 'Y';
case 0XA9:
buzz();
return 'p';
case 0XA8:
buzz();
return 'P';
case 0XB1:
buzz();
return 'a';
case 0XB0:
buzz();
return 'R';
case 0XE1:
buzz();
return 'q';
case 0XE0:
buzz();
return 'X';
default:
break;
}
break;
case 6 :
init_key_gpio_6();
GPIO_SetBits(GPIOE,GPIO_Pin_6); //PE6置1
tem = (GPIO_ReadInputData(GPIOE) & 0x00FF) | 0x80 ; //读取按键
// delay(50);
while (((GPIO_ReadInputData(GPIOE) & 0x00FF) | 0x80 ) != 0xc1 ){} //检测按键松开
switch(tem)
{
case 0XC3:
buzz();
return 'm';
case 0XC2:
buzz();
return 'Z';
default:
break;
}
break;
default:
break;
}
if (no<6)
{
no++;
}
else
{
no=1;
}
}
}
|