STM32学习笔记--按键输入实验

基于正点原子miniSTM32开发板、STM32RCT6、库函数

目录:

  • 一、硬件原理
  • 二、软件设计

一、硬件原理

按键 KEY0连接在 PC5 上、KEY1 连接在 PA15 上、WK_UP 连接在 PA0 上。KEY0 和 KEY1 是低电平有效的,而 WK_UP 是高电平有效的,除了KEY1 有上拉电阻,其他两个都没有上下拉电阻,所以,需要在 STM32 内部设置上下拉。
STM32学习笔记--按键输入实验_第1张图片

二、软件设计

1、static变量
(1)static申明的是局部变量,存储在静态存储区。
(2)它在函数调用结束后不会被释放,值会一直被保留下来
(3)用static申明的变量具有记忆功能。
2、KEY.H

#ifndef __KEY_H
#define __KEY_H

#include 

#define KEY0  GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)
#define KEY1  GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)
#define WK_UP   GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)

#define KEY0_PRES	1		//KEY0  
#define KEY1_PRES	2		//KEY1 
#define WKUP_PRES	3		//WK_UP

void KEY_Init(void);
u8 KEY_Scan(u8 mode);

#endif

KEY0、 KEY1、WK_UP3个宏定义用于申明他们所对应的IO口的位;KEY0_PRES、 KEY1_PRES 、WKUP_PRES 3 个宏定义用于申明他们所对应的按键按下时KEY_Scan所返回的值。
3、KEY.C

#include 
#include 

void KEY_Init(void)
{
     
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC,ENABLE);
	
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_15;//PA15
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 
 	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_5;//PC5
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 
 	GPIO_Init(GPIOC, &GPIO_InitStructure);
 
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;//PA0
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;  
	GPIO_Init(GPIOA, &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;
}

(1)KEY_Init 是用来初始化按键输入的 IO 口的, PA0、PA15 和 PC5 输入设置,GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);这个函数,用于禁止 JTAG,开启 SWD,因为 PA15 占用了 JTAG 的一个 IO,所以要禁止 JTAG,从而让 PA15 用作普通 IO输入。
(2)KEY_Scan 函数,则是用来扫描这 3 个 IO 口是否有按键按下。KEY_Scan 函数,支持两种扫描方式,通过 mode 参数来设置。
  1).当 mode 为 0 的时候,KEY_Scan 函数将不支持连续按,扫描某个按键,该按键按下之后必须要松开,才能第二次触发,否则不会再响应这个按键,这样的好处就是可以防止按一次多次触发,而坏处就是在需要长按的时候就不合适了。
  2).当 mode 为 1 的时候,KEY_Scan 函数将支持连续按,如果某个按键一直按下,则会一直返回这个按键的键值,这样可以方便的实现长按检测。
  因为该函数里面有 static 变量,所以该函数不是一个可重入函数,该函数的按键扫描是有优先级的,最优先的是 KEY0,第二优先的是 KEY1,最后是 WK_UP 按键。该函数有返回值,如果有按键按下,则返回相应的值,如果没有或者按键不正确,则返回 0。
4、main.c

#include 
#include "delay.h"
#include "sys.h"
#include "KEY.H"
int main(void)
 {
     	
	u8 t=0;	  
	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);	
		} 
	}		 
}

先点亮LED0,按键扫面方式采用不支持连续按模式;当KEY0按下时,LED0取反, KEY1按下时LED1取反, WKUP按下时LED0,LED1同时取反。

你可能感兴趣的:(单片机,STM32,嵌入式,stm32,单片机,嵌入式,gpio)