薄膜键盘驱动(STM32)

一、前期准备
单片机:STM32F103ZET6
开发环境:MDK5.14
固件库:标准库 V3.5
薄膜开关:淘宝上很多,价格便宜

这里写图片描述
薄膜开关原理图:
这里写图片描述

二、实验效果
串口配置:
这里写图片描述
开机欢迎信息:
这里写图片描述
实验效果:
这里写图片描述

三、驱动原理
如原理图所示,薄膜开关分为行和列,只要分别对其进行扫描便可以得出是哪一个按键按下的了。行扫描时,需要把行对应的IO口设置成上拉输入,列设置成推挽输出并全部赋值为0。行对应的IO口检测是否有低电平的输入,从而判断是哪一行按下了。列扫描与行扫描一样,只不过对应的IO状态不一样,具体的见
驱动代码。需要完整工程或者有问题的请加QQ:1002521871,验证:呵呵。

四、驱动代码
MatrixKey.h

#ifndef __MATRIX_KEY_H__
#define	__MATRIX_KEY_H__
#include "stm32f10x.h"
#include "gpio.h"
#include "delay.h"

//C0,C2,A0,A2,A4,A6,C4,B0

#define		ROW_1		PCout(0)
#define		ROW_2		PCout(2)
#define		ROW_3		PAout(0)
#define		ROW_4		PAout(2)

#define		COL_1		PAout(4)
#define		COL_2		PAout(6)
#define		COL_3		PCout(4)
#define		COL_4		PBout(0)


#define		ROW1		GPIO_Pin_0
#define		ROW2		GPIO_Pin_2
#define		ROW3		GPIO_Pin_0
#define		ROW4		GPIO_Pin_2
#define		COL1		GPIO_Pin_4
#define		COL2		GPIO_Pin_6
#define		COL3		GPIO_Pin_4
#define		COL4		GPIO_Pin_0

typedef enum
{
	Column,
	Row,
	Normal
} MatirxMode;

extern void MatrixKeyConfiguration(void);
extern uint8_t GetMatrixKeyValue(void);
#endif


MatrixKey.c

#include "matrixkey.h"

//R1,R2,R3,R4,C1,C2,C3,C4
//C0,C2,A0,A2,A4,A6,C4,B0
void MatrixModeConfig(MatirxMode mode);

void MatrixKeyConfiguration(void)
{
	GPIO_InitTypeDef    GPIO;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
						   RCC_APB2Periph_GPIOC, ENABLE);
    
    //Register IO 
    GPIO.GPIO_Pin   = ROW3 | ROW4 | COL1 | COL2;
    GPIO.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOA, &GPIO);
	
	GPIO.GPIO_Pin   = COL4;
	GPIO_Init(GPIOB, &GPIO);
	
	GPIO.GPIO_Pin   = ROW1 | ROW2 | COL3;
	GPIO_Init(GPIOC, &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
//C0,C2,A0,A2,A4,A6,C4,B0
void MatrixModeConfig(MatirxMode mode)
{
	GPIO_InitTypeDef    GPIO;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
						   RCC_APB2Periph_GPIOC, ENABLE);
    
	switch(mode)
	{
		case Column:
			GPIO.GPIO_Pin   = ROW1 | ROW2;
			GPIO.GPIO_Mode  = GPIO_Mode_IPU;
			GPIO_Init(GPIOC, &GPIO);
		
			GPIO.GPIO_Pin   = ROW3 | ROW4;
			GPIO_Init(GPIOA, &GPIO);
		//==============================================//
			GPIO.GPIO_Pin   = COL1 | COL2;
			GPIO.GPIO_Speed = GPIO_Speed_50MHz;
			GPIO.GPIO_Mode  = GPIO_Mode_Out_PP;
			GPIO_Init(GPIOA, &GPIO);
		
			GPIO.GPIO_Pin   = COL3;
			GPIO_Init(GPIOC, &GPIO);
		
			GPIO.GPIO_Pin   = COL4;
			GPIO_Init(GPIOB, &GPIO);
			
			//BIT_ADDR(GPIOA_IDR_Addr,n)
			BIT_ADDR(GPIOA_ODR_Addr,4) = 0;
			BIT_ADDR(GPIOA_ODR_Addr,6) = 0;
			BIT_ADDR(GPIOC_ODR_Addr,4) = 0;
			BIT_ADDR(GPIOB_ODR_Addr,0) = 0;
			break;
			
		case Row:
			GPIO.GPIO_Pin   = ROW1 | ROW2;
			GPIO.GPIO_Speed = GPIO_Speed_50MHz;
			GPIO.GPIO_Mode  = GPIO_Mode_Out_PP;
			GPIO_Init(GPIOC, &GPIO);
		
			GPIO.GPIO_Pin   = ROW3 | ROW4;
			GPIO_Init(GPIOA, &GPIO);
		//==============================================//
			GPIO.GPIO_Pin   = COL1 | COL2;
			GPIO.GPIO_Mode  = GPIO_Mode_IPU;
			GPIO_Init(GPIOA, &GPIO);
		
			GPIO.GPIO_Pin   = COL3;
			GPIO_Init(GPIOC, &GPIO);
		
			GPIO.GPIO_Pin   = COL4;
			GPIO_Init(GPIOB, &GPIO);
		
			BIT_ADDR(GPIOC_ODR_Addr,0) = 0;
			BIT_ADDR(GPIOC_ODR_Addr,2) = 0;
			BIT_ADDR(GPIOA_ODR_Addr,0) = 0;
			BIT_ADDR(GPIOA_ODR_Addr,2) = 0;
			break;
	}
}


/************************************/
/*return 1 to 16 			        */
/*erturn 0 is error or not respnose */
/************************************/
uint8_t GetMatrixKeyValue(void)
{
	uint8_t value = 0;
	
	MatrixModeConfig(Column);
	if (BIT_ADDR(GPIOC_IDR_Addr,0) == 0)
	{
		DelayMs(5);
		if (BIT_ADDR(GPIOC_IDR_Addr,0) == 0)
		{
			value += 0;
		}
	}
	else if (BIT_ADDR(GPIOC_IDR_Addr,2) == 0)
	{
		DelayMs(5);
		if (BIT_ADDR(GPIOC_IDR_Addr,2) == 0)
		{
			value += 4;
		}
	}
	else if (BIT_ADDR(GPIOA_IDR_Addr,0) == 0)
	{
		DelayMs(5);
		if (BIT_ADDR(GPIOA_IDR_Addr,0) == 0)
		{
			value += 8;
		}
	}
	else if (BIT_ADDR(GPIOA_IDR_Addr,2) == 0)
	{
		DelayMs(5);
		if (BIT_ADDR(GPIOA_IDR_Addr,2) == 0)
		{
			value += 12;
		}
	}
	else
	{
		value = 0;
	}
	
	MatrixModeConfig(Row);
	if (BIT_ADDR(GPIOA_IDR_Addr,4) == 0)
	{
		DelayMs(5);
		if (BIT_ADDR(GPIOA_IDR_Addr,4) == 0)
		{
			value += 1;
		}
	}
	else if (BIT_ADDR(GPIOA_IDR_Addr,6) == 0)
	{
		DelayMs(5);
		if (BIT_ADDR(GPIOA_IDR_Addr,6) == 0)
		{
			value += 2;
		}
	}
	else if (BIT_ADDR(GPIOC_IDR_Addr,4) == 0)
	{
		DelayMs(5);
		if (BIT_ADDR(GPIOC_IDR_Addr,4) == 0)
		{
			value += 3;
		}
	}
	else if (BIT_ADDR(GPIOB_IDR_Addr,0) == 0)
	{
		DelayMs(5);
		if (BIT_ADDR(GPIOB_IDR_Addr,0) == 0)
		{
			value += 4;
		}
	}
	else
	{
		value = 0;
	}
	
	
	return value;
}


由于作者能力有限,有不妥之处欢迎指正,邮箱alex_hua@foxmail.com

  • 4
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值