1. Hardware design
The hardware resources used in this experiment are:
1
) Indicator lights
DS0
,
DS1
2
)
3
buttons:
KEY0
,
KEY1
and
KEY_UP
.
The connection of DS0
,
DS1
and
STM32
has been introduced in the previous chapter
. The button KEY0 on the
MiniSTM32
development board is
connected to
PC5
,
KEY1 is
connected to
PA15
, and
WK_UP is
connected to
PA0
. As
shown in Figure
7.2.1
:
Figure
7.2.1
Schematic diagram of the connection between
buttons and
STM32
It should be noted here:
KEY0
and
KEY1
are active at low level, while
WK_UP
is active at high level. Except that KEY1
has a pull-up resistor (
shared with
JTDI
), the other two do not have a pull-up resistor, so you need to
STM32
internal arranged
opposite the drop-down.
2. Software design
1. Open the key.c file first , the code is as follows:
#include "key.h"
#include "delay.h"
//按键初始化函数
//PA15 和 PC5 设置成输入
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC,
ENABLE);//使能 PORTA,PORTC 时钟
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
//关闭 jtag,使能 SWD,可以用 SWD 模式调试
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;//PA15
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化 GPIOA15
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//PC5
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化 GPIOC5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//PA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 设置成输入,默认下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化 GPIOA.0
}
//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//返回值:
//0,没有任何按键按下
//KEY0_PRES,KEY0 按下
//KEY1_PRES,KEY1 按下
//WKUP_PRES,WK_UP 按下
//注意此函数有响应优先级,KEY0>KEY1>WK_UP!!
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;// 无按键按下
}
This code contains
2
functions,
void KEY_Init(void)
and
u8 KEY_Scan(u8 mode)
.
KEY_Init
is used to initialize the
IO
port of the
key input . To achieve the input settings of
PA0
,
PA15
and
PC5
, note that this calls:
GPIO_PinRemapConfig (GPIO_Remap_SWJ_JTAGDisable, ENABLE);
this function is used to disable
JTAG
,
open
SWD
, because
PA15
occupies a
JTAG
one
IO
, so to prohibit
JTAG
, so that
PA15
used as a normal
IO
input.
KEY_Scan
function, is used to scan it
. 3
th
IO
whether opening button is pressed.
KEY_Scan
function, support two
scan mode, the
mode
to set parameters.
When the
mode
is
0
, the
KEY_Scan
function will not support continuous pressing and scanning a certain key. After the key is pressed, it must be released before it can be triggered for the second time. Otherwise, it will not respond to this key again. This has the advantage of preventing Press once many times
Trigger, but the disadvantage is that it is not suitable when you need to long press.
When the
mode
is
1
, the
KEY_Scan
function will support continuous pressing. If a certain button is kept pressed, it will always return to the key value of this button, which can easily realize the long-press detection.
With the
mode
parameter, you can choose different methods according to your needs.
Here to remind you,
because the function inside
static
variable, the function is not a reentrant function, there is in
OS
under the circumstances, that we
should pay attention to the next. At the same time, it should be noted that the key scan of this function has priority, the first priority is
KEY0
, the
second priority is
KEY1
, and the last is
WK_UP
key. This function has a return value, if a key is pressed, it returns non-
zero
Value, if there is no or the key is incorrect,
0
is returned
.
2. Next, let's look at the code in the header file key.h
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
#define KEY0 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)//读取按键 0
#define KEY1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)//读取按键 1
#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//读取按键 2
#define KEY0_PRES 1 //KEY0
#define KEY1_PRES 2 //KEY1
#define WKUP_PRES 3 //WK_UP
void KEY_Init(void);//IO 初始化
u8 KEY_Scan(u8 mode); //按键扫描函数
#endif The
most important thing in this code is
3
macro definitions:
#define KEY0 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)//读取按键 0
#define KEY1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)//读取按键 1
#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//读取按键 2
The previous marquee experiment used bit band operation to set
the bit of a certain
IO
port. Here we take the library function to read
the value of the
IO
port. Of course, the above functions can also be simply realized through bitband operations:
//#define KEY0 PCin(5)
//#define KEY1 PAin(15)
//#define WK_UP PAin(0)
3. Finally, let's take a look at the main function code written in main.c as follows:
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "key.h"
int main(void)
{
u8 t;
delay_init(); //延时函数初始化
LED_Init(); //初始化与 LED 连接的硬件接口
KEY_Init(); //初始化与按键连接的硬件接口
LED0=0; //点亮 LED
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);
}
} }
Compilation result: