薄膜键盘驱动(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;
}

由于作者能力有限,有不妥之处欢迎指正,邮箱[email protected]

猜你喜欢

转载自blog.csdn.net/huazhen1234/article/details/80292873