本篇文章将从库函数的角度讲述stm32mini板按键输入,小白总结,如有错误,请大神指教。
一、硬件连接
WK UP连接的是PA0,KEY0连接的是PC5,KEY1连接的是PA15。
二、GPIO操作方法
(1)读取IO口输入电平调用库函数:
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef*GPIOx,uint16_t GPIO_Pin);
(2)读取IO口输入电平操作寄存器:GPIOx_IDR(端口输入寄存器)
(3)使用位带操作读取IO口输入电平:PEin(4)--读取GPIOE.4口电平。
三、按键输入实验
3.1按键输入实验的思路
(1)使能按键对应IO口时钟。
(2)初始化IO模式(上拉/下拉输入)。
(3)扫描IO口电平(库函数/寄存器/位操作)。
3.2按键的两种模式
(1)支持连按:
效果:只要检测到低电平即视为按键已按下。
思路:
u8 KEY_Scan(void)
{
if(KEY按下)
{
delay_ms(10);//延时10-20ms,防抖
if(KEY确实按下)
{
return KEY_Value;
}
return 无效值;
}
}
(2)不支持连按:
效果:只有按下后松开再次按下才算为有效的低电平,如果按下后不松开,则之后的低电平视为无效。(按键按下没有松开,只能算一次)。
思路:
u8 KEY_Scan(void)
{
static u8 key_up = 1;
if(key_up&&KEY按下)
{
delay_ms(10);//延时,防抖
key_up = 0;//标记这次key已经按下
if(KEY确实按下)
{
return KEY_VALUE;
}
}
else if(KEY没有按下)
{
key_up = 1;
}
return 没有按下;
}
(3)混合模式
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1;//默认刚开始为高电平
if(mode==1) key_up=1;//mode=1,支持连续按,key-up永远等于1;mode=0,则此行代码无用,不支持连续按;
if(key_up && KEY按下)
{
delay_ms(10);//延时,防抖
key_up=0;//标记这次key已经按下
if(KEY确实按下)
{
return KEY_VALUE;//识别到按下,返回KEY的真实值
}
}
else if(KEY没有按下) key_up=1;//表示没有扫描到按下,则返回 key_up=1
return 没有按下
}
3.3按键输入实验(两种方式合二为一)
先新建一个工程,工程文件如下:
main.c如下:
#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#define LED0 PAout(8) // PA8
#define LED1 PDout(2) // PD2
int main(void)
{
vu8 t;
delay_init();
LED_Init();
KEY_Init();
LED0=0;
while(1)
{
t=KEY_Scan(0);
switch(t)
{
case KEY0_PRES:
LED0=!LED0;
break;
case KEY1_PRES:
LED1=!LED1;
break;
case WKUP_PRES:
LED0=!LED0;
LED1=!LED1;
break;
default:
delay_ms(10);
}
}
}
led.c文件如下:
#include "led.h"
#include "stm32f10x.h"
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);//GPIOB
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//GPIOE
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOD,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
key.c如下:
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
#include "key.h"
#define KEY0 PCin(5) //PC5
#define KEY1 PAin(15) //PA15
#define WK_UP PAin(0) //PA0 WK_UP
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1;
if(mode)key_up=1;
if(key_up&&(KEY0==0||KEY1==0||WK_UP==1))
{
delay_ms(10);
key_up=0;
if(KEY0==0)return KEY0_PRES;
else if(KEY1==0)return KEY1_PRES;
else if(WK_UP==1)return WKUP_PRES;
}else if(KEY0==1&&KEY1==1&&WK_UP==0)key_up=1;
return 0;
}
然后在写代码的过程中还有过一个警告:warning: #1-D: last line of file ends without a newline,这个是头文件的#endif后面没有另起新行导致的。