一、前期准备
单片机: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;
}
由于作者能力有限,有不妥之处欢迎指正,邮箱[email protected]