STM32F103ZET6学习记录-按键实验部分

1.开发板原理图

STM32F103ZET6学习记录-按键实验部分_第1张图片

STM32F103ZET6学习记录-按键实验部分_第2张图片

 

从原理图中我们可以看出,上键是默认低电平,与GPIOA相连,而其余三个按键都是于GPIOE相连,默认高电平。所以在初始化按键的时候要分开。上键单独初始化,另外三个可以一起初始化。初始化时GPIOA和GPIOE都要进行初始化操作。因为两个I/O口都包含了按键。

STM32F103ZET6学习记录-按键实验部分_第3张图片

void KEY_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin=KEY_UP_Pin;	   //选择你要设置的IO口
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;//下拉输入  
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;	   //设置传输速率
	GPIO_Init(KEY_UP_Port,&GPIO_InitStructure);		  /* 初始化GPIO */
	
	GPIO_InitStructure.GPIO_Pin=KEY_DOWN_Pin|KEY_LEFT_Pin|KEY_RIGHT_Pin;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;	//上拉输入
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(KEY_Port,&GPIO_InitStructure);
}

为了方便管理,创建一个当前目录下的KEY文件夹,将按键相关的文件都放到该文件夹下。(记得在魔术棒中配置相关的编译路径)。

通过宏定义,改善代码的可移植性和可维护性。

STM32F103ZET6学习记录-按键实验部分_第4张图片

#ifndef _key_H
#define _key_H


#include "system.h"
 
#define KEY_LEFT_Pin    GPIO_Pin_2    //定义K_LEFT管脚
#define KEY_DOWN_Pin    GPIO_Pin_3    //定义K_DOWN管脚
#define KEY_RIGHT_Pin   GPIO_Pin_4   //定义K_RIGHT管脚
#define KEY_UP_Pin      GPIO_Pin_0  //定义KEY_UP管脚

#define KEY_Port (GPIOE) //定义端口
#define KEY_UP_Port (GPIOA) //定义端口


//使用位操作定义
#define K_UP PAin(0)
#define K_DOWN PEin(3)
#define K_LEFT PEin(2)
#define K_RIGHT PEin(4)

//使用读取管脚状态库函数定义 
//#define K_UP      GPIO_ReadInputDataBit(KEY_UP_Port,KEY_UP_Pin)
//#define K_DOWN    GPIO_ReadInputDataBit(KEY_Port,KEY_DOWN_Pin)
//#define K_LEFT    GPIO_ReadInputDataBit(KEY_Port,KEY_LEFT_Pin)
//#define K_RIGHT   GPIO_ReadInputDataBit(KEY_Port,KEY_RIGHT_Pin)


//定义各个按键值  
#define KEY_UP 1
#define KEY_DOWN 2
#define KEY_LEFT 3
#define KEY_RIGHT 4  



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

为每个按键宏定义一个值用于扫描函数返回,用于判断是哪个按键按下。

2.扫描按键。

对于上键,按下的时候它会和一个电源相连,从默认的低电平变为高电平,从而产生一个上升沿信号。另外三个按键则是从高电平,产生一个低电平,产生一个下降沿信号。

所以我们的程序就应该如下编写。

u8 KEY_Scan(u8 mode)
{
	static u8 key=1;
	if(key==1&&(K_UP==1||K_DOWN==0||K_LEFT==0||K_RIGHT==0)) //任意一个按键按下
	{
		delay_ms(10);  //消抖
		key=0;
		if(K_UP==1)
		{
			return KEY_UP; 
		}
		else if(K_DOWN==0)
		{
			return KEY_DOWN; 
		}
		else if(K_LEFT==0)
		{
			return KEY_LEFT; 
		}
		else
		{
			return KEY_RIGHT;
		}
	}
	else if(K_UP==0&&K_DOWN==1&&K_LEFT==1&&K_RIGHT==1)    //无按键按下
	{
		key=1;
	}
	if(mode==1) //连续按键按下
	{
		key=1;
	}
	return 0;
}

/************************************************************/

/****************下面是完整工程**************************/

/************************************************************/

key.c文件

#include "key.h"
#include "SysTick.h"

/*******************************************************************************
* 函 数 名         : KEY_Init
* 函数功能		   : 按键初始化
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void KEY_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin=KEY_UP_Pin;	   //选择你要设置的IO口
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;//下拉输入  
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;	   //设置传输速率
	GPIO_Init(KEY_UP_Port,&GPIO_InitStructure);		  /* 初始化GPIO */
	
	GPIO_InitStructure.GPIO_Pin=KEY_DOWN_Pin|KEY_LEFT_Pin|KEY_RIGHT_Pin;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;	//上拉输入
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(KEY_Port,&GPIO_InitStructure);
}


u8 KEY_Scan(u8 mode)
{
	static u8 key=1;
	if(key==1&&(K_UP==1||K_DOWN==0||K_LEFT==0||K_RIGHT==0)) //任意一个按键按下
	{
		delay_ms(10);  //消抖
		key=0;
		if(K_UP==1)
		{
			return KEY_UP; 
		}
		else if(K_DOWN==0)
		{
			return KEY_DOWN; 
		}
		else if(K_LEFT==0)
		{
			return KEY_LEFT; 
		}
		else
		{
			return KEY_RIGHT;
		}
	}
	else if(K_UP==0&&K_DOWN==1&&K_LEFT==1&&K_RIGHT==1)    //无按键按下
	{
		key=1;
	}
	if(mode==1) //连续按键按下
	{
		key=1;
	}
	return 0;
}

 key.h文件

#ifndef _key_H
#define _key_H


#include "system.h"
 
#define KEY_LEFT_Pin    GPIO_Pin_2    //定义K_LEFT管脚
#define KEY_DOWN_Pin    GPIO_Pin_3    //定义K_DOWN管脚
#define KEY_RIGHT_Pin   GPIO_Pin_4   //定义K_RIGHT管脚
#define KEY_UP_Pin      GPIO_Pin_0  //定义KEY_UP管脚

#define KEY_Port (GPIOE) //定义端口
#define KEY_UP_Port (GPIOA) //定义端口


//使用位操作定义
#define K_UP PAin(0)
#define K_DOWN PEin(3)
#define K_LEFT PEin(2)
#define K_RIGHT PEin(4)

//使用读取管脚状态库函数定义 
//#define K_UP      GPIO_ReadInputDataBit(KEY_UP_Port,KEY_UP_Pin)
//#define K_DOWN    GPIO_ReadInputDataBit(KEY_Port,KEY_DOWN_Pin)
//#define K_LEFT    GPIO_ReadInputDataBit(KEY_Port,KEY_LEFT_Pin)
//#define K_RIGHT   GPIO_ReadInputDataBit(KEY_Port,KEY_RIGHT_Pin)


//定义各个按键值  
#define KEY_UP 1
#define KEY_DOWN 2
#define KEY_LEFT 3
#define KEY_RIGHT 4  



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

main.c文件



#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"


int main()
{
	u8 key,i;
	SysTick_Init(72);
	LED_Init();
	KEY_Init();
	
	while(1)
	{
		key=KEY_Scan(0);   //扫描按键
		switch(key)
		{
			case KEY_UP: led2=0;break;      //按下K_UP按键    点亮D2指示灯
			case KEY_DOWN: led2=1;break;    //按下K_DOWN按键  熄灭D2指示灯
			case KEY_LEFT: led3=1;break;    //按下K_LEFT按键  点亮D3指示灯
			case KEY_RIGHT: led3=0;break;   //按下K_RIGHT按键 熄灭D3指示灯
		}
		i++;
		if(i%20==0)
		{
			led1=!led1;      //LED1状态取反
		}
		delay_ms(10);	
	}
}

用按键实现灯的有序亮\灭,则将main.c替换为下面的代码



#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "smg.h"
#include "key.h"

unsigned int  Number[]=
{
    0x3f,//0 --- 0011 1111
    0x06,//1 --- 0000 0110
    0x5b,//2 --- 0101 1011
    0x4f,//3 --- 0100 1111
    0x66,//4 --- 0110 0110
    0x6d,//5 --- 0110 1101
    0x7d,//6 --- 0111 1101
    0x07,//7 --- 0000 0111
    0x7f,//8 --- 0111 1111
    0x6f,//9 --- 0110 1111
    0x77,//a --- 0111 0111
    0x7c,//b --- 0111 1100
    0x39,//c --- 0011 1001
    0x5e,//d --- 0101 1110
    0x79,//e --- 0111 1001
    0x71 //f --- 0111 0001
};

int main()
{
    u8 i=0,key;
		u16 light = 0xffff;
    SysTick_Init(72);
    LED_Init();
    SMG_Init();
    KEY_init();
    while(1)
    {
        key=KEY_Scan(1);
        switch(key)
        {
        case KEY_UP:
            i++;
            break;      //每次按下K_UP按键   多点亮一个指示灯
        case KEY_DOWN:
            i--;
            break;    //按下K_DOWN按键  熄灭一个指示灯
        case KEY_LEFT:
           i+=2;
            break;    //按下K_LEFT按键  点亮两个指示灯
        case KEY_RIGHT:
            i-=2;
            break;   //按下K_RIGHT按键 熄灭两个指示灯
        }
				if(i>8)
					i=7;
				if(i<=0)
					i=0;
				GPIO_Write(GPIOC,light<

 

你可能感兴趣的:(STM32学习记录)