您好,欢迎来到爱go旅游网。
搜索
您的当前位置:首页基于STM32的_矩阵键盘_驱动(中断方式)

基于STM32的_矩阵键盘_驱动(中断方式)

来源:爱go旅游网


//==========================Keyboard.h===============================//

/*----------------------------------------------

本程序实现4*5键盘的扫描

从左到右,从上到下,键值

依次为1-20

------------------------------------------------*/

#ifndef __KEYBOARD_H

#define __KEYBOARD_H

#include \"stm32f10x_lib.h\"

//选择扫描模式

#define Interrupt_Scan //中断扫描模式 ,要在NVIC在中打开对应中断

/*可以自己定义其它扫描方式*/

#define DELAY_COUNT 0x0FFFF

/* 键盘控制引脚定义 */

#define Keyboard_Control_Port GPIOD

#define Keyboard_Line_1 GPIO_Pin_0

#define Keyboard_Line_2 GPIO_Pin_1

#define Keyboard_Line_3 GPIO_Pin_2

#define Keyboard_Line_4 GPIO_Pin_3

#define Keyboard_Line_5 GPIO_Pin_4

#define Keyboard_Row_1 GPIO_Pin_5

#define Keyboard_Row_2 GPIO_Pin_6

#define Keyboard_Row_3 GPIO_Pin_7

#define Keyboard_Row_4 GPIO_Pin_8

#define Keyboard_LineBase Keyboard_Line_1

#define Keyboard_RowBase Keyboard_Row_1

#define Keyboard_Line (Keyboard_Line_1 | Keyboard_Line_2 | Keyboard_Line_3 | Keyboard_Line_4 | Keyboard_Line_5)

#define Keyboard_Row (Keyboard_Row_1 | Keyboard_Row_2 | Keyboard_Row_3 | Keyboard_Row_4)

#ifdef Interrupt_Scan /* 中断扫描模式宏定义 */

#define Keyboard_EXTI_Row1 EXTI_Line5

#define Keyboard_EXTI_Row2 EXTI_Line6

#define Keyboard_EXTI_Row3 EXTI_Line7

#define Keyboard_EXTI_Row4 EXTI_Line8

#define Keyboard_EXTI_PortSource GPIO_PortSourceGPIOD

#define Keyboard_EXTI_PinSource1 GPIO_PinSource5

#define Keyboard_EXTI_PinSource2 GPIO_PinSource6

#define Keyboard_EXTI_PinSource3 GPIO_PinSource7

#define Keyboard_EXTI_PinSource4 GPIO_PinSource8

#define Keyboard_IRQ_Channel EXTI9_5_IRQChannel

#define Keyboard_EXTI_Line (Keyboard_EXTI_Row1 | Keyboard_EXTI_Row2 | Keyboard_EXTI_Row3 | Keyboard_EXTI_Row4)

#endif /* 中断扫描模式宏定义 */

/* 键盘全局变量声明 */

extern unsigned int Keyboard_Val ; //当前键值

extern unsigned char Keyboard_Change_Flag ; //键值改变标志,读取新的键值后由主程序清零

/* 键盘接口函数声明 */

#ifdef Interrupt_Scan

extern void Init_Keyboard_Interrupt(void) ;//键盘初始化为键盘扫描模式

#endif

extern void Delay(vu32 nCount) ; //用于延时消抖

#endif /* KEYBOARD_H */

//=================================================================//

//============================Keyboard.c=============================//

#include \"stm32f10x_lib.h\"

#include \"Keyboard.h\"

unsigned int Keyboard_Val = 0 ; //保存键值

unsigned char Keyboard_Change_Flag = 0 ; //键值改变标志,读取键值后清零

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

函数名称: Init_Keyboard_Interrupt

功 能: 键盘初始化为中断扫描模式

初始化键盘需要的IO,Line1-Line5设为输出低

Row1-Row4 接上拉电阻,使能下降沿中断

参 数: 无

返回值 : 无

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

void Init_Keyboard_Interrupt(void)

{

GPIO_InitTypeDef GPIO_InitStructure ;

EXTI_InitTypeDef EXTI_InitStructure ;

EXTI_DeInit() ;

//Line1-Line5设为输出高

GPIO_InitStructure.GPIO_Pin = Keyboard_Line ;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;

GPIO_Init(Keyboard_Control_Port ,&GPIO_InitStructure) ;

GPIO_SetBits(Keyboard_Control_Port ,Keyboard_Line) ;

//Row1-Row4设置为下拉输入,用来接收上升沿中断

GPIO_InitStructure.GPIO_Pin = Keyboard_Row;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD ; //下拉输入

GPIO_Init(Keyboard_Control_Port ,&GPIO_InitStructure) ;

EXTI_ClearITPendingBit(Keyboard_EXTI_Row1) ; //清除中断标志位

GPIO_EXTILineConfig(Keyboard_EXTI_PortSource ,Keyboard_EXTI_PinSource1 ); //Pinsource不能取或

EXTI_ClearITPendingBit(Keyboard_EXTI_Row2) ; //清除中断标志位

GPIO_EXTILineConfig(Keyboard_EXTI_PortSource ,Keyboard_EXTI_PinSource2 );

EXTI_ClearITPendingBit(Keyboard_EXTI_Row3) ; //清除中断标志位

GPIO_EXTILineConfig(Keyboard_EXTI_PortSource ,Keyboard_EXTI_PinSource3 );

EXTI_ClearITPendingBit(Keyboard_EXTI_Row4) ; //清除中断标志位

GPIO_EXTILineConfig(Keyboard_EXTI_PortSource ,Keyboard_EXTI_PinSource4

);

//设置Row1-Row4为上升沿中断

EXTI_InitStructure.EXTI_Line = Keyboard_EXTI_Line;

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt ;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising ;

EXTI_InitStructure.EXTI_LineCmd = ENABLE ;

EXTI_Init(&EXTI_InitStructure) ;

}

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

函数名称: Delay

功 能: 在扫描按键时,用于延时消抖

参 数: nCount -- 延时长度

返回值 : 无

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

void Delay(vu32 nCount)

{

for(; nCount!= 0;nCount--);

}

//==============================================================//

//=========================stm32f10x_it.c============================//

void EXTI9_5_IRQHandler(void)

{

unsigned long tmpFlag=0 ; //保存需要的中断标志位

unsigned char i = 0 ; //循环标量

tmpFlag = EXTI->PR & Keyboard_EXTI_Line ; //只取设定过的标志位

EXTI->PR = tmpFlag ;

switch(tmpFlag) //判断是哪个标志位置位

{

case Keyboard_EXTI_Row1:

GPIO_ResetBits(Keyboard_Control_Port ,Keyboard_Line) ;

for(i=0 ;i<5 ;i++) //扫描方式判断按键

{

GPIO_SetBits(Keyboard_Control_Port ,(Keyboard_LineBase<if(GPIO_ReadInputDataBit(Keyboard_Control_Port ,Keyboard_Row_1))

{

Delay(DELAY_COUNT) ; //延时消抖

if(GPIO_ReadInputDataBit(Keyboard_Control_Port ,Keyboard_Row_1))

{

Keyboard_Val = 1+i ;

Keyboard_Change_Flag = 1 ;

break ;

}

}

}

GPIO_SetBits(Keyboard_Control_Port ,Keyboard_Line) ;

EXTI->PR = Keyboard_EXTI_Row1 ; //清除中断标志

break ;

case Keyboard_EXTI_Row2:

GPIO_ResetBits(Keyboard_Control_Port ,Keyboard_Line) ;

for(i=0 ;i<5 ;i++)//扫描方式判断按键

{

GPIO_SetBits(Keyboard_Control_Port ,(Keyboard_LineBase<if(GPIO_ReadInputDataBit(Keyboard_Control_Port ,Keyboard_Row_2))

{

Delay(DELAY_COUNT) ; //延时消抖

if(GPIO_ReadInputDataBit(Keyboard_Control_Port ,Keyboard_Row_2))

{

Keyboard_Val = 6+i ;

Keyboard_Change_Flag = 1 ;

break ;

}

}

}

GPIO_SetBits(Keyboard_Control_Port ,Keyboard_Line) ;

EXTI->PR = Keyboard_EXTI_Row2 ; //清除中断标志

break ;

case Keyboard_EXTI_Row3:

GPIO_ResetBits(Keyboard_Control_Port ,Keyboard_Line) ;

for(i=0 ;i<5 ;i++) //扫描方式判断按键

{

GPIO_SetBits(Keyboard_Control_Port ,(Keyboard_LineBase<if(GPIO_ReadInputDataBit(Keyboard_Control_Port ,Keyboard_Row_3))

{

Delay(DELAY_COUNT) ; //延时消抖

if(GPIO_ReadInputDataBit(Keyboard_Control_Port ,Keyboard_Row_3))

{

Keyboard_Val = 11+i ;

Keyboard_Change_Flag = 1 ;

break ;

}

}

}

GPIO_SetBits(Keyboard_Control_Port ,Keyboard_Line) ;

EXTI->PR = Keyboard_EXTI_Row3 ; //清除中断标志

break ;

case Keyboard_EXTI_Row4:

GPIO_ResetBits(Keyboard_Control_Port ,Keyboard_Line) ;

for(i=0 ;i<5 ;i++) //扫描方式判断按键

{

GPIO_SetBits(Keyboard_Control_Port ,(Keyboard_LineBase<if(GPIO_ReadInputDataBit(Keyboard_Control_Port ,Keyboard_Row_4))

{

Delay(DELAY_COUNT) ; //延时消抖

if(GPIO_ReadInputDataBit(Keyboard_Control_Port ,Keyboard_Row_4))

{

Keyboard_Val = 16+i ;

Keyboard_Change_Flag = 1 ;

break ;

}

}

}

GPIO_SetBits(Keyboard_Control_Port ,Keyboard_Line) ;

EXTI->PR = Keyboard_EXTI_Row4 ; //清除中断标志

break ;

default:

break ;

}

}

//注:使用时要使能AFIO时钟和EXTI9_5IRQ //

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- igat.cn 版权所有

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务