STM32F103 4*4薄膜键盘代码分享

本文介绍了一种基于STM32单片机的矩阵键盘实现方法,通过行扫描和列扫描确定按键状态,支持连按和非连按功能。详细介绍了引脚配置、初始化过程及代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自己找了别人的代码修改了一下,加了连按和不连续按的功能,很稳定。
原理放在代码的注释里了,就是行扫描和列扫描去确定哪个按键按下。

引脚和单片机的连线

薄膜键盘有8个脚,标好数字的。
1接 B11
2接 B10
3接 B9
4接 B8
5接 C6
6接 C7
7接 C8
8接 C9

.H文件

> #ifndef __MATRIX_KEY_H__
#define	__MATRIX_KEY_H__
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
#define		ROW_1		PCout(6)
#define		ROW_2		PCout(7)
#define		ROW_3		PCout(8)
#define		ROW_4		PCout(9)
#define		COL_1		PBout(11)
#define		COL_2		PBout(10)
#define		COL_3		PBout(9)
#define		COL_4		PBout(8)
#define		ROW1		GPIO_Pin_6
#define		ROW2		GPIO_Pin_7
#define		ROW3		GPIO_Pin_8
#define		ROW4		GPIO_Pin_9
#define		COL1		GPIO_Pin_11
#define		COL2		GPIO_Pin_10
#define		COL3		GPIO_Pin_9
#define		COL4		GPIO_Pin_8
typedef enum
{
	Column,
	Row,
	Normal
} MatirxMode;
extern void MatrixKeyConfiguration(void);
extern uint8_t GetMatrixKeyValue(void);
extern uint8_t GetMatrixKeyValue_Once(void);
#endif

.C文件

#include "matrixkey.h"

//R1,R2,R3,R4,C1,C2,C3,C4
//C6,C7,C8,C9,B11,B10,B9,B8


void MatrixKeyConfiguration(void)       //按键初始化
{
	GPIO_InitTypeDef    GPIO;

    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB |
						   RCC_APB2Periph_GPIOC, ENABLE);
    
    //Register IO 
    GPIO.GPIO_Pin   = ROW3 | ROW4 | ROW1 | ROW2;
    GPIO.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOC, &GPIO);
    GPIO.GPIO_Pin   = COL1 | COL2|COL3|COL4;
    GPIO_Init(GPIOB, &GPIO);
	
	ROW_1 = 1;
	ROW_2 = 1;
	ROW_3 = 1;
	ROW_4 = 1;
	COL_1 = 1;
	COL_2 = 1;
	COL_3 = 1;
	COL_4 = 1;
	//MatrixModeConfig(Column);
}

//R1,R2,R3,R4,C1,C2,C3,C4
//C6,C7,C8,C9,B11,B10,B9,B8
void MatrixModeConfig(MatirxMode mode)//行扫描时,需要把行对应的IO口设置成上拉输入,列设置成推挽输出并全部赋值为0。行对应的IO口检测是否有低电平的输入,从而判断是哪一行按下了。
{
	GPIO_InitTypeDef    GPIO;

    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB |
						   RCC_APB2Periph_GPIOC, ENABLE);
    
	switch(mode)
	{
		case Column:
			GPIO.GPIO_Pin   =COL1 | COL2 |COL3 |COL4;
			GPIO.GPIO_Mode  = GPIO_Mode_IPU;            
			GPIO_Init(GPIOB, &GPIO);           //列扫描模式时,列上拉输入                 
		
		
		//==============================================//
			GPIO.GPIO_Pin   = ROW1 | ROW2|ROW3|ROW4;
			GPIO.GPIO_Speed = GPIO_Speed_50MHz;
			GPIO.GPIO_Mode  = GPIO_Mode_Out_PP;
			GPIO_Init(GPIOC, &GPIO);          //行推挽输出0
		
			
			//BIT_ADDR(GPIOA_IDR_Addr,n)
		    BIT_ADDR(GPIOC_ODR_Addr,6) = 0;
			BIT_ADDR(GPIOC_ODR_Addr,7) = 0;
			BIT_ADDR(GPIOC_ODR_Addr,8) = 0;
			BIT_ADDR(GPIOC_ODR_Addr,9) = 0;

			break;
			
		case Row:
			GPIO.GPIO_Pin   = COL1 | COL2|COL3|COL4;
			GPIO.GPIO_Speed = GPIO_Speed_50MHz;
			GPIO.GPIO_Mode  = GPIO_Mode_Out_PP;
			GPIO_Init(GPIOB, &GPIO);           //行扫描模式时,行上拉,列推挽输出0
		
		
			BIT_ADDR(GPIOB_ODR_Addr,11) = 0;
			BIT_ADDR(GPIOB_ODR_Addr,10) = 0;
			BIT_ADDR(GPIOB_ODR_Addr,9) = 0;
			BIT_ADDR(GPIOB_ODR_Addr,8) = 0;
		
		
		//==============================================//
			GPIO.GPIO_Pin   =  ROW1 | ROW2|ROW3|ROW4;
			GPIO.GPIO_Mode  = GPIO_Mode_IPU;
			GPIO_Init(GPIOC, &GPIO);
			break;
	}
}


/************************************/
/*return 1 to 16 			        */
/*erturn 0 is error or not respnose */
/************************************/
//R1,R2,R3,R4,C1,C2,C3,C4
//C6,C7,C8,C9,B11,B10,B9,B8
uint8_t GetMatrixKeyValue(void)    //支持连按
{
	uint8_t value = 0;
	uint8_t Rowvalue = 0;
	


	MatrixModeConfig(Row);//行扫描
	if (BIT_ADDR(GPIOC_IDR_Addr,9) == 0)
	{
		 delay_ms(5);
		if (BIT_ADDR(GPIOC_IDR_Addr,9) == 0)
		{
			value += 0;
		}
	}
	else if (BIT_ADDR(GPIOC_IDR_Addr,8) == 0)
	{
		 delay_ms(5);
		if (BIT_ADDR(GPIOC_IDR_Addr,8) == 0)
		{
			value += 4;
		}
	}
	else if (BIT_ADDR(GPIOC_IDR_Addr,7) == 0)
	{
		 delay_ms(5);
		if (BIT_ADDR(GPIOC_IDR_Addr,7) == 0)
		{
			value += 8;
		}
	}
	else if (BIT_ADDR(GPIOC_IDR_Addr,6) == 0)
	{
		 delay_ms(5);
		if (BIT_ADDR(GPIOC_IDR_Addr,6) == 0)
		{
			value +=12;
		}
	}
	else
	{
		value = 0;
	}
	Rowvalue=value;
	
	MatrixModeConfig(Column);   //列扫描
	if (BIT_ADDR(GPIOB_IDR_Addr,8) == 0)
	{
		 delay_ms(5);
		if (BIT_ADDR(GPIOB_IDR_Addr,8) == 0)
		{
			value += 1;
		}
	}
	else if (BIT_ADDR(GPIOB_IDR_Addr,9) == 0)
	{
		 delay_ms(5);
		if (BIT_ADDR(GPIOB_IDR_Addr,9) == 0)
		{
			value += 2;
		}
	}
	else if (BIT_ADDR(GPIOB_IDR_Addr,10) == 0)
	{
		 delay_ms(5);
		if (BIT_ADDR(GPIOB_IDR_Addr,10) == 0)
		{
			value += 3;
		}
	}
	else if (BIT_ADDR(GPIOB_IDR_Addr,11) == 0)
	{
		 delay_ms(5);
		if (BIT_ADDR(GPIOB_IDR_Addr,11) == 0)
		{
			value += 4;
		}
	}
	else
	{
		value = 0;
	}
    if(value==Rowvalue){return 0;}     //说明列扫描失败,可能按键已经松开,防止行扫描成功后按键松开而导致列扫描失败的错误情况。
	return value;
}

uint8_t GetMatrixKeyValue_Once(void)   //不支持连按
{
	static u8 key_up=1;//按键按松开标志	
	u8 t;
	t=GetMatrixKeyValue();
	if(key_up&&t)
	{
		key_up=0;
		return t;
	}else if(t==0)key_up=1; 	     
	return 0;// 无按键按下
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值