(二)按键驱动<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
一、 本课内容概述
这一课的主要内容是STM32按键驱动的相关程序。 一般来说,键盘可以有独立键盘,矩阵键盘两种,而程序分为扫描和中断两种,这一课主要讲解独立键盘的扫描方式程序。万利实验板上有两个独立点触按键和一个摇杆按键,不过器硬件实现方式都一样,都是通过检测接地低电平信号实现。
二、 相关程序
(1) 创建key.h文件
/******************** (C) COPYRIGHT 2009 MEA https://static.assets-stash.eet-china.com/album/old-resources/2009/9/27/fa1b3b35-0d84-4cbd-a3e1-8bad377e5e4b.rar" target=_blank>***********************************
* File Name : key.h
* Author : 邓天坚
* Version : V1.0
* Date : 26/09/2009
* Description : define of key
********************************************************************************/
/* Includes ------------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* IO definition -----------------------------------------------------------*/
#define KEY_PORT GPIOD
#define JOY_UP GPIO_Pin_14 /* PD.14 */
#define JOY_DOWN GPIO_Pin_15 /* PD.15 */
#define JOY_LEFT GPIO_Pin_13 /* PD.13 */
#define JOY_RIGHT GPIO_Pin_12 /* PD.12 */
#define JOY_SELECT GPIO_Pin_11 /* PD.11 */
#define KEYLEFT GPIO_Pin_3 /* PD.3 */
#define KEYRIGHT GPIO_Pin_4 /* PD.4 */
/* basic IO operation-------------------------------------------------------*/
#define KEY1_R GPIO_ReadInputDataBit(KEY_PORT, KEY1);
#define KEY2_R GPIO_ReadInputDataBit(KEY_PORT, KEY2);
#define KEY_R GPIO_ReadInputData(KEY_PORT);
/* Private macro -------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
extern void KeyInit(void);
extern u8 JoyState(void);
extern u8 KeyScan(void);
/******************* (C) COPYRIGHT 2009 MEA *****END OF FILE****/
(2) 创建key.c文件
/******************** (C) COPYRIGHT 2009 MEA ***********************************
* File Name : key.c
* Author : 邓天坚
* Version : V1.0
* Date : 26/09/2009
* Description : key
********************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "systemInit.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
//宏定义键值
#define RIGHT 2
#define LEFT 1
#define UP 3
#define DOWN 4
#define SELECT 5
#define LEFTKEY 6
#define RIGHTKEY 7
/* Private macro -------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
void KeyInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure the JoyStick IOs */
/* Key (up + down + left + right */
GPIO_InitStructure.GPIO_Pin = JOY_UP | JOY_DOWN |JOY_LEFT | JOY_RIGHT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(KEY_PORT, &GPIO_InitStructure);
}
//不包含软件延时防抖的按键扫描程序
/*******************************************************************************
* Function Name : JoyState.
* Description : Decodes the Joystick direction.
* Input : None.
* Output : None.
* Return value : The direction value.
*******************************************************************************/
u8 JoyState(void)
{
/* "right" key is pressed */
if (!GPIO_ReadInputDataBit(KEY_PORT, JOY_RIGHT))
{
return RIGHT;
}
/* "left" key is pressed */
if (!GPIO_ReadInputDataBit(KEY_PORT, JOY_LEFT))
{
return LEFT;
}
/* "up" key is pressed */
if (!GPIO_ReadInputDataBit(KEY_PORT, JOY_UP))
{
return UP;
}
/* "down" key is pressed */
if (!GPIO_ReadInputDataBit(KEY_PORT, JOY_DOWN))
{
return DOWN;
}
/* "select" key is pressed */
if (!GPIO_ReadInputDataBit(KEY_PORT, JOY_SELECT))
{
return SELECT;
}
/* No key is pressed */
if(!GPIO_ReadInputDataBit(KEY_PORT, KEYLEFT))
{
return LEFTKEY;
}
if(!GPIO_ReadInputDataBit(KEY_PORT, KEYRIGHT))
{
return RIGHTKEY;
}
else
{
return 0;
}
}
//包含软件延时防抖的按键扫描程序
/*******************************************************************************
* Function Name : KeyScan.
* Description : Decodes the Key, with delay, 去抖。
* Input : None.
* Output : None.
* Return value : The pressed key value.
*******************************************************************************/
u8 KeyScan(void)
{
u16 i;
static u16 j;//按键记录
i=KEY_R;
i=i&0xf818;//使检测变量高四位无关位置零
delay_nms(10);//延时防抖
j=KEY_R;
j=j&0xf818;//读进按键记录变量j检查是否真的出发按键
if(i==j)
{
switch(i)
{
case 0xf818:return 0x00;
case 0xd818:return LEFT;
case 0xe818:return RIGHT;
case 0xb818:return UP;
case 0x7818:return DOWN;
case 0xf018:return SELECT;
case 0xf810:return LEFTKEY;
case 0xf808:return RIGHTKEY;
default:return 0x00;
}
}
else return 0;
}
/******************* (C) COPYRIGHT 2009 MEA *****END OF FILE****/
(3) 修改系统初始化程序以及配置文件
在systemInit.c里面修改RCC_Configuration()函数,打开按键相应GPIO的管脚时钟。
/* Enable GPIOD clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);不要忘了
另外也要紧记在stm32f10x_conf.h文件里面去掉按键相应GPIO的注释,打开相关文件编译。
(4) 修改主函数
系统总初始化程序中加入按键初始化的程序:
void System_Init(void)
{
#ifdef DEBUG
debug();
#endif
/* Configure the system clocks */
RCC_Configuration();
/* GPIO ports pins Configuration */
GPIO_Configuration();
/* NVIC Configuration */
NVIC_Configuration();
KeyInit();//按键初始化
}
适当修改main函数,实现需要的功能。以下是例程:
/*******************************************************************************
* Function Name : main
* Description : Main program.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
int main(void)
{
System_Init();
while (1)
{
if(KeyScan()==UP)
{
LED1_H;
delay_nms(200);
LED1_L;
}
if(KeyScan()==DOWN)
{
LED2_H;
delay_nms(200);
LED2_L;
}
if(KeyScan()==LEFT)
{
LED3_H;
delay_nms(200);
LED3_L;
}
if(KeyScan()==RIGHT)
{
LED4_H;
delay_nms(200);
LED4_L;
}
if(KeyScan()==SELECT)
{
LED1_H;
LED2_H;
LED3_H;
LED4_H;
delay_nms(200);
LED1_L;
LED2_L;
LED3_L;
LED4_L;
}
}
}
工程文件:PDF教程:
Crystal_oscillator 2011-7-5 07:30