模块学习(五)——矩阵键盘

发布者:脑电风暴最新更新时间:2022-08-09 来源: csdn关键字:矩阵键盘  MSP430F5529 手机看文章 扫描二维码
随时随地手机看文章

矩阵键盘的学习只是为了做一个简单的遥控器,主要目标还是后续的遥控器控制小车实现简单而精准的直行和转弯,加上前面的模块,锻炼自己PID的调试和理解能力。但毕竟矩阵键盘也算个模块嘛,就也记录一下,分享给有需要的同志。

(此代码是基于MSP430F5529系列,其他系列MCU均可用,自己修改引脚,配置IO口即可)


1.基本原理

矩阵键盘主要方便在16个按键只需要8个引脚即可实现控制,根据我们所学的4*4的矩阵可以很容易理解他的原理,无非就是先确定行(列),再确定列,即可确定某个具体的键位。方法自然而然也有很多种,用的比较多的就是行扫描法和列扫描法。

在这里插入图片描述

例如,我们确定第三行,第四列的键位该如何确定呢?我们利用行扫描法。将四个关于行的引脚设置为输出模式,四个关于列的引脚设置为输入模式(这里一定要是上拉输入)。随后,对四个关于行的引脚轮流给出低电平,给到第一行的时候,此时因为第一行的四个列引脚电平读取均为高,即证明第一行没有按键按下,当低电平给到第三行的时候,第四列电平读取为低电平,此时便可以确定是三行四列的按键按下!大概的流程便是如此。


2.上代码

/*

 * matrix_keybord.c

 *

 *  Created on: 2022年7月20日

 *      Author: S10

 */


#include "matrix_keyboard.h"

#include "oled.h"

/* 设置为列输入,行输出

 * 无入口参数

 * 无返回值

 */

void ROCI_Init(void)

{

    GPIO_setAsOutputPin(R1_Port,R1_Pin);

    GPIO_setAsOutputPin(R2_Port,R2_Pin);

    GPIO_setAsOutputPin(R3_Port,R3_Pin);

    GPIO_setAsOutputPin(R4_Port,R4_Pin);


    GPIO_setAsInputPinWithPullUpResistor(C1_Port,C1_Pin);

    GPIO_setAsInputPinWithPullUpResistor(C2_Port,C2_Pin);

    GPIO_setAsInputPinWithPullUpResistor(C3_Port,C3_Pin);

    GPIO_setAsInputPinWithPullUpResistor(C4_Port,C4_Pin);

}


/* 设置为行输入,列输出

 * 无入口参数

 * 无返回值

 */

void RICO_Init(void)

{

    GPIO_setAsInputPinWithPullUpResistor(R1_Port,R1_Pin);

    GPIO_setAsInputPinWithPullUpResistor(R2_Port,R2_Pin);

    GPIO_setAsInputPinWithPullUpResistor(R3_Port,R3_Pin);

    GPIO_setAsInputPinWithPullUpResistor(R4_Port,R4_Pin);


    GPIO_setAsOutputPin(C1_Port,C1_Pin);

    GPIO_setAsOutputPin(C2_Port,C2_Pin);

    GPIO_setAsOutputPin(C3_Port,C3_Pin);

    GPIO_setAsOutputPin(C4_Port,C4_Pin);

}


int key_scan_column(void)

{

    if(GPIO_getInputPinValue(C1_Port,C1_Pin) == GPIO_INPUT_PIN_LOW)

        return 5;

    else if(GPIO_getInputPinValue(C2_Port,C2_Pin) == GPIO_INPUT_PIN_LOW)

        return 6;

    else if(GPIO_getInputPinValue(C3_Port,C3_Pin) == GPIO_INPUT_PIN_LOW)

        return 7;

    else if(GPIO_getInputPinValue(C4_Port,C4_Pin) == GPIO_INPUT_PIN_LOW)

        return 8;

    else return 0;

}


char key_detect(void)

{

    ROCI_Init();//置为列输入,行输出


    GPIO_setOutputLowOnPin(R1_Port,R1_Pin);//设置第一行为低电平

    GPIO_setOutputHighOnPin(R2_Port,R2_Pin);//设置第二行为高电平

    GPIO_setOutputHighOnPin(R3_Port,R3_Pin);//设置第三行为高电平

    GPIO_setOutputHighOnPin(R4_Port,R4_Pin);//设置第四行为高电平

    OLED_ShowNum(0,0,key_scan_column(),2,10);

    if(key_scan_column() != 0)//扫描存在按键按下

    {

//        __delay_cycles(160000);

        delay_ms(10);//按键消抖

        if(key_scan_column() != 0 )//若依然判断有低电平,则确实有按键按下

        {

            switch(key_scan_column())

            {


                case 5: return '1';

                case 6: return '2';

                case 7: return '3';

                case 8: return '4';

                default:break;

            }

        }

    }

    GPIO_setOutputHighOnPin(R1_Port,R1_Pin);//设置第一行为高电平

    GPIO_setOutputHighOnPin(R2_Port,R2_Pin);//设置第二行为高电平

    GPIO_setOutputHighOnPin(R3_Port,R3_Pin);//设置第三行为高电平

    GPIO_setOutputHighOnPin(R4_Port,R4_Pin);//设置第四行为高电平


    GPIO_setOutputHighOnPin(R1_Port,R1_Pin);//设置第一行为高电平

    GPIO_setOutputLowOnPin(R2_Port,R2_Pin);//设置第二行为低电平

    GPIO_setOutputHighOnPin(R3_Port,R3_Pin);//设置第三行为高电平

    GPIO_setOutputHighOnPin(R4_Port,R4_Pin);//设置第四行为高电平

    if(key_scan_column() !=0 )//扫描存在按键按下

    {

        delay_ms(10);//按键消抖

        if(key_scan_column() !=0 )//若依然判断有低电平,则确实有按键按下

        {

            switch(key_scan_column())

            {

                case 5: return '5';

                case 6: return '6';

                case 7: return '7';

                case 8: return '8';

                default: break;

            }

        }

    }

    GPIO_setOutputHighOnPin(R1_Port,R1_Pin);//设置第一行为高电平

    GPIO_setOutputHighOnPin(R2_Port,R2_Pin);//设置第二行为高电平

    GPIO_setOutputHighOnPin(R3_Port,R3_Pin);//设置第三行为高电平

    GPIO_setOutputHighOnPin(R4_Port,R4_Pin);//设置第四行为高电平


    GPIO_setOutputHighOnPin(R1_Port,R1_Pin);//设置第一行为高电平

    GPIO_setOutputHighOnPin(R2_Port,R2_Pin);//设置第二行为高电平

    GPIO_setOutputLowOnPin(R3_Port,R3_Pin);//设置第三行为低电平

    GPIO_setOutputHighOnPin(R4_Port,R4_Pin);//设置第四行为高电平

    if(key_scan_column() !=0 )//扫描存在按键按下

    {

        delay_ms(10);//按键消抖

        if(key_scan_column() !=0 )//若依然判断有低电平,则确实有按键按下

        {

            switch(key_scan_column())

            {

                case 5: return '9';

                case 6: return 'a';

                case 7: return 'b';

                case 8: return 'c';

                default: break;

            }

        }

    }

    GPIO_setOutputHighOnPin(R1_Port,R1_Pin);//设置第一行为高电平

    GPIO_setOutputHighOnPin(R2_Port,R2_Pin);//设置第二行为高电平

    GPIO_setOutputHighOnPin(R3_Port,R3_Pin);//设置第三行为高电平

    GPIO_setOutputHighOnPin(R4_Port,R4_Pin);//设置第四行为高电平


    GPIO_setOutputHighOnPin(R1_Port,R1_Pin);//设置第一行为高电平

    GPIO_setOutputHighOnPin(R2_Port,R2_Pin);//设置第二行为高电平

    GPIO_setOutputHighOnPin(R3_Port,R3_Pin);//设置第三行为高电平

    GPIO_setOutputLowOnPin(R4_Port,R4_Pin);//设置第四行为低电平

    if(key_scan_column() != 0 )//扫描存在按键按下

    {

        delay_ms(10);//按键消抖

        if(key_scan_column() != 0 )//若依然判断有低电平,则确实有按键按下

        {

            switch(key_scan_column())

            {

                case 5: return 'd';

                case 6: return 'e';

                case 7: return 'f';

                case 8: return 'g';

                default: break;

            }

        }

    }

    GPIO_setOutputHighOnPin(R1_Port,R1_Pin);//设置第一行为高电平

    GPIO_setOutputHighOnPin(R2_Port,R2_Pin);//设置第二行为高电平

    GPIO_setOutputHighOnPin(R3_Port,R3_Pin);//设置第三行为高电平

    GPIO_setOutputHighOnPin(R4_Port,R4_Pin);//设置第四行为高电平


    return '0';

}


/*

 * matrix_keyboard.h

 *

 *  Created on: 2022年7月20日

 *      Author: S10

 */


#ifndef MATRIX_KEYBOARD_H_

#define MATRIX_KEYBOARD_H_


#include "driverlib.h"


#define C1_Port GPIO_PORT_P1

#define C1_Pin  GPIO_PIN6


#define C2_Port GPIO_PORT_P6

#define C2_Pin  GPIO_PIN6


#define C3_Port GPIO_PORT_P3

#define C3_Pin  GPIO_PIN2


#define C4_Port GPIO_PORT_P2

#define C4_Pin  GPIO_PIN7


#define R1_Port GPIO_PORT_P6

#define R1_Pin  GPIO_PIN2


#define R2_Port GPIO_PORT_P6

#define R2_Pin  GPIO_PIN3


#define R3_Port GPIO_PORT_P6

#define R3_Pin  GPIO_PIN4


#define R4_Port GPIO_PORT_P7

#define R4_Pin  GPIO_PIN0


#define CPU_CLOCK       16000000

#define delay_us(us)    __delay_cycles(CPU_CLOCK/1000000*(us))

#define delay_ms(ms)    __delay_cycles(CPU_CLOCK/1000*(ms))


void ROCI_Init(void);

void RICO_Init(void);

int key_scan_column(void);

char key_detect(void);


#endif /* MATRIX_KEYBOARD_H_ */


在主函数中直接调用即可


关键字:矩阵键盘  MSP430F5529 引用地址:模块学习(五)——矩阵键盘

上一篇:MSP430——Timer(输出比较编码器测速)
下一篇:模块学习(四)——超声波测距

推荐阅读最新更新时间:2024-11-12 13:49

MSP430F5529关于ADC12模数转换介绍
一、ADC12_A模块介绍 1、12位ADC核心   ADC核心将模拟输入转换为它的12位数字表示,并将结果存储在转换存储器中。核心使用两个可编程和可选择的电压电平(VR+和VR -)来定义转换的上限和下限。输入通道和参考电压水平(VR+和VR-)被定义在转换控制存储器。   当输入信号等于或大于VR+时,数字输出(NADC)为全量程(0FFFh)   当输入信号等于或小于VR-时,数字输出(NADC)为零   ADC12_A核心是由两个控制寄存器ADC12CTL0和ADC12CTL1配置的。核心是通过ADC12ON位启用的。ADC12_A可以在不使用时关闭,以节省电能。ADC12_A控制位只能在ADC12ENC = 0时
[单片机]
<font color='red'>MSP430F5529</font>关于ADC12模数转换介绍
MSP430F5529之1.44寸OLED显示
前言 有几天没更新了,最近一直忙着电赛,学习这个TI处理器芯片,因为我之前并没有接触过。毕竟我学的51单片机和32单片机,感觉这个16位的单片机“食之乏味,弃之可惜”,但是没办法,电赛TI公司赞助的,还是得准备准备哈哈,这里我是用CCS软件来入门的。 一、1.44寸OLED “独白” 其实相对于0.96寸OLED ,该OLED 最明显的特点就是它多出了四个接口(RES、DC、CS、BLK),同时保留了原有的接口(VCC、GND、SCL、SDA),下面讲一下接线问题: 电源接线: VCC :接 5V GND :接地 液晶屏数据线接线: CS : 片选信号 SCL(CLK): SPI 时钟信号引
[单片机]
<font color='red'>MSP430F5529</font>之1.44寸OLED显示
51单片机之矩阵键盘的驱动实现
用这个矩阵键盘做单片机输入,插 P1 口的 P1.0~P1.6。 想问的是,当: 按下 1 键 P0 口的 P0.0 输出高电平; 按下 2 键 P0.1 输出高电平; …… 一直到 8 键就可以了。 还有一个要求,当按下一个键时延时5秒并锁住其它按键,5秒之后回到起点。用汇编语言 ;===================================================== ;如下即可: ORG 0000H START: MOV P0, #255 MOV P1, #255 CLR P1.0 NOP JNB P1.4, K1 JNB P1.5, K2 JNB P1.6, K3 MOV P1, #
[单片机]
51单片机之<font color='red'>矩阵键盘</font>的驱动实现
采用AT89S51的并行口P1接4×4矩阵键盘程序
1.实验任务 如图4.14.2所示,用AT89S51的并行口P1接4×4矩阵键盘,以P1.0-P1.3作输入线,以P1.4-P1.7作输出线;在数码管上显示每个按键的“0-F”序号。对应的按键的序号排列如图4.14.1所示   图4.14.1 2.硬件 电路 设计原理图   图4.14.2 3.系统板上硬件连线设计 (1. 把“单片机系统“区域中的P3.0-P3.7端口用8芯排线连接到“4X4行列式键盘”区域中的C1-C4 R1-R4端口上; (2. 把“单片机系统”区域中的P0.0/AD0-P0.7/AD7端口用8芯排线连接到“四路静态数码显示模块”区域中的任
[单片机]
采用AT89S51的并行口P1接4×4<font color='red'>矩阵键盘</font>程序
AVR扩展4*4矩阵键盘的CVAVR程序2
// 8位LED动态显示按键值 // 芯片 ATMEGA16L // 时钟 4MHz 内部 // 采用系统自带延时程序 #include mega16.h #include delay.h unsigned char KeyNumber; // 全局变量,保存按键值 void leddisplay(); // 数码管显示 void keyin(void); // 键盘扫描 unsigned char ledxs ={16,16,16,16,16,16,0,0}; // 数码管显示缓冲区 flash unsigned char tab ={0x3f,0x06,0x5b,0x4f,0x
[单片机]
51单片机矩阵键盘PROTEUS仿真演示
原文地址: 51单片机矩阵键盘PROTEUS仿真演示(图、程序) 作者: 给力哈哈 程序如下: #include AT89x52.h #define uchar unsigned char; uchar key_val=0; //定义键值,初始默认为0 uchar code TAB ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x83,0xC6,0xa1,0x86,0x8e}; //0~F 共阳数码管显示段码 void Check_Key(void) { unsigned char row,
[单片机]
学习笔记-CCS-MSP430F5529[快速入门篇一]
一·开发环境的选择 关于MSP430的开发环境,有很多种选择,常见的有Energia,CCS,IAR for MSP430,MDK等,本人仅使用过Energia和CCS,这两个开发环境都是TI公司官方给我们用来开发TI板子的开发环境,其中Energia是一个开源的社区驱动型开发环境,界面与Arduino有97%的类似度,如果你之前有过Arduino的开发经验,那么大概率可以无缝衔接到Energia,Arduino的开源库大多都可以移植到Energia,源代码都托管到了github上面,点击Energia 可查看。而CCS是Eclipse软件框架结合嵌入式开发调试功能的产品,对于常用VS,Eclipse以及MDK等环境的朋友
[单片机]
<font color='red'>学习</font>笔记-CCS-MSP430F5529[快速入门篇一]
msp430f5529产生单路/双路spwm正弦波信号
//main.c #include msp430.h #include PWM.h #include include.h #define uint unsigned int /*---------------------------------------------------------------------------------------------- * 功能:产生单路SPWM波 * 输入:无 * 输出:P1.4 */ void SPWM_1Way_Init(float x,float y)//x控制pwm周期,y控制占空比,y小于1且大于0 {
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved