单片机C语言之学习矩阵按键
新手记录学习:单片机C语言之矩阵按键
一、先画好原理图,了解基本原理:
二、再构思一下基本的程序思路:
矩阵按键扫描思路:
1、如单个IO检测按键,IO口要检测到高低电平变化,才能检测到按键;那么矩阵按键也一样。
2、先检测第1个按键(按键1),那么需要列1的IO口输出高电平,行1的IO口做输入(内部下拉,不能做高阻输入,IO没有内部下拉,就需要接外部下拉)检测,或者列1的IO口做输入,行1的IO做输出。先以列的IO做输出,行的IO口做输入(内部下拉)检测按键
3、检测设置与判断:当列1的IO输出高的时候(其它列的IO设置高阻输入),4个行的IO口做输入,有按键按下了,所在行的IO会有高电平。读取该行IO的电平,就可以判断有无按键,假如按键1按键,那么行1的IO就会有高电平,读取到了高电平,进行消抖确认后,就判断为有按键,其它按键依此类推。
4、 扫描完列_1,下一个2MS扫描列_2的IO上的按键,此时列_2的IO输出高,其它列的IO设置高阻输入,读取行IO有无按键,再间隔2毫秒扫描切换一个列输出(4个行IO做输入),来识别不同的按键
5、无按键判断,采用计数的方式,连续5个2MS无按键,则判断为无按键,有按键计数清0,按键状态标志位清0, 有按键时,无按键计数变量清0
三、画个流程图,把程序架构理顺一下:
五、开始写代码。
5.1、先初始化定时器和IO口。定时器0定时2ms中断一次,IO口P04~P07设置为输入带下拉模式:
P0=B00000000; //P0[7:0] 端口数据寄存器 P0^0 口输出高电平 P0M0 =0xC0; //推挽输出P0M1 =0xC0; //推挽输出P0M2 =0xC0; //推挽输出P0M3 =0xC0; //推挽输出P0M4 =0x58; //施密特数字带下拉输入 P0M5 =0x58; //施密特数字带下拉输入P0M6 =0x58; //施密特数字带下拉输入P0M7 =0x58; //施密特数字带下拉输入
5.2、定义IO口脚位配置和标志位 .h文件配置如下:
#ifndef _matrix_key_H_
#define _matrix_key_H_/*********************** 函数声明 ************************************/
void matrix_key();
void key_check();
void key_press();
void key_release();/******************声明全局字节变量*********************************/extern unsigned char bdata key_flag0;
extern unsigned char bdata key_flag1;/********************声明全局位变量*********************************/extern bit F_KeyScan_2ms; // 按键扫描2ms标志位
extern bit F_Key_state; //按键状态标志位 1=有按键 0=无按键
extern bit F_SW_1; //按键1标志位
extern bit F_SW_2; //按键2标志位
extern bit F_SW_3; //按键3标志位
extern bit F_SW_4; //按键4标志位
extern bit F_SW_5; //按键5标志位
extern bit F_SW_6; //按键6标志位
extern bit F_SW_7; //按键7标志位
extern bit F_SW_8; //按键8标志位
extern bit F_SW_9; //按键9标志位
extern bit F_SW_10; //按键10标志位
extern bit F_SW_11; //按键11标志位
extern bit F_SW_12; //按键12标志位
extern bit F_SW_13; //按键13标志位
extern bit F_SW_14; //按键14标志位
extern bit F_SW_15; //按键15标志位
extern bit F_SW_16; //按键16标志位/********************功能声明与定义*********************************/
sbit IO_Lie_1 =P0^3;
sbit IO_Lie_2 =P0^2;
sbit IO_Lie_3 =P0^1;
sbit IO_Lie_4 =P0^0;#define IO_Lie_1_outport {P0M3=0xC0; IO_Lie_1=1;} //输出模式,输出高
#define IO_Lie_2_outport {P0M2=0xC0; IO_Lie_2=1;} //输出模式,输出高
#define IO_Lie_3_outport {P0M1=0xC0; IO_Lie_3=1;} //输出模式,输出高
#define IO_Lie_4_outport {P0M0=0xC0; IO_Lie_4=1;} //输出模式,输出高#define IO_Lie_1_intport {IO_Lie_1=0;P0M3=0x00; } //模拟高阻输入
#define IO_Lie_2_intport {IO_Lie_2=0;P0M2=0x00; } //模拟高阻输入
#define IO_Lie_3_intport {IO_Lie_3=0;P0M1=0x00; } //模拟高阻输入
#define IO_Lie_4_intport {IO_Lie_4=0;P0M0=0x00; } //模拟高阻输入#define KeyScan_Lie_1 {IO_Lie_1_outport; IO_Lie_2_intport; IO_Lie_3_intport; IO_Lie_4_intport;} //扫描列1上的按键设置
#define KeyScan_Lie_2 {IO_Lie_1_intport; IO_Lie_2_outport; IO_Lie_3_intport; IO_Lie_4_intport;} //扫描列2上的按键设置
#define KeyScan_Lie_3 {IO_Lie_1_intport; IO_Lie_2_intport; IO_Lie_3_outport; IO_Lie_4_intport;} //扫描列3上的按键设置
#define KeyScan_Lie_4 {IO_Lie_1_intport; IO_Lie_2_intport; IO_Lie_3_intport; IO_Lie_4_outport;} //扫描列4上的按键设置#endif
5.3、定义IO口脚位配置和标志位 .C文件配置如下:
/*********************** 包含的头文件 ******************************/
#include "my_HC89F0541.H"
#include "matrix_key.H"/******************声明全局字节变量********************************/
static unsigned char data r_KeyScan_cnt=0; //按键扫描计数变量
static unsigned char data r_key_t1 =0; //有按键计数(消抖)变量static unsigned char data r_key_hang =0; // 按键行变量,低四位有效
static unsigned char data r_NoKey_cnt=0; //无按键计数变量/********************声明全局位变量********************************/bit F_KeyScan_2ms=0; // 按键扫描2ms标志位
bit F_Key_state=0; //按键状态标志位 1=有按键 0=无按键unsigned char bdata key_flag0 =0;
sbit F_SW_1 =key_flag0^0; //按键1标志位
sbit F_SW_2 =key_flag0^1; //按键2标志位
sbit F_SW_3 =key_flag0^2; //按键3标志位
sbit F_SW_4 =key_flag0^3; //按键4标志位
sbit F_SW_5 =key_flag0^4; //按键5标志位
sbit F_SW_6 =key_flag0^5; //按键6标志位
sbit F_SW_7 =key_flag0^6; //按键7标志位
sbit F_SW_8 =key_flag0^7; //按键8标志位unsigned char bdata key_flag1 =0;
sbit F_SW_9 =key_flag1^0; //按键9标志位
sbit F_SW_10 =key_flag1^1; //按键10标志位
sbit F_SW_11 =key_flag1^2; //按键11标志位
sbit F_SW_12 =key_flag1^3; //按键12标志位
sbit F_SW_13 =key_flag1^4; //按键13标志位
sbit F_SW_14 =key_flag1^5; //按键14标志位
sbit F_SW_15 =key_flag1^6; //按键15标志位
sbit F_SW_16 =key_flag1^7; //按键16标志位/********************功能声明与定义********************************/
5.4、矩阵扫描主程序如下:
/**********************************************************************
函 数:matrix_key() ---> 矩阵扫描按键程序
输 入:无
输 出:无
返 回:无
说 明:
1、
***********************************************************************/
void matrix_key()
{if (F_KeyScan_2ms) //每2ms进来扫描一次按键{F_KeyScan_2ms=0;if (++r_KeyScan_cnt>4) {r_KeyScan_cnt=1; //扫描完4列后,从第1列开始}switch(r_KeyScan_cnt){case 1:{KeyScan_Lie_1; //第1列准备key_check(); //扫描第1列上的按键};break;case 2:{KeyScan_Lie_2;key_check();};break;case 3:{KeyScan_Lie_3;key_check();};break;case 4:{KeyScan_Lie_4;key_check();};break; }}}
5.5、按键检测子程序如下:
void key_check()
{r_key_hang=P0&0xF0; //提取P0口高四位,检测4个行上的按键r_key_hang>>=4; //行变量,左移4位,低4位有效if (r_key_hang==0) {key_release(); //无按键子程序}else{key_press(); //有按键子程序}
}
5.6、有按键判断子程序如下:
/**********************************************************************
函 数:key_press() ---> 有按键子程序
输 入:无
输 出:无
返 回:无
说 明:
1、
***********************************************************************/
void key_press()
{r_NoKey_cnt=0; //无按键计数清0if(!F_Key_state) //按键状态标志位=1,不再重复进入判断短按{ if(++r_key_t1&0x08) //递增后判断,消抖时间8*8ms{ r_key_t1 = 0; //消抖计数清0F_Key_state = 1; //按键状态标志位=1switch(r_key_hang) //按键标志位判断{case 1: //第1行上的按键{switch(r_KeyScan_cnt){case 1: F_SW_1=1; break; //第1列扫描时第1行有按键 case 2: F_SW_2=1; break; //第2列扫描时第1行有按键case 3: F_SW_3=1; break; //第3列扫描时第1行有按键case 4: F_SW_4=1; break; //第4列扫描时第1行有按键} }; break;case 2: //第2行上的按键{switch(r_KeyScan_cnt){case 1: F_SW_5=1; break; //第1列扫描时第2行有按键case 2: F_SW_6=1; break; //第2列扫描时第2行有按键case 3: F_SW_7=1; break; //第3列扫描时第2行有按键case 4: F_SW_8=1; break; //第4列扫描时第2行有按键} }; break;case 4: //第3行上的按键{switch(r_KeyScan_cnt){case 1: F_SW_9=1; break;case 2: F_SW_10=1; break;case 3: F_SW_11=1; break;case 4: F_SW_12=1; break;} } ; break;case 8: //第4行上的按键{switch(r_KeyScan_cnt){case 1: F_SW_13=1; break;case 2: F_SW_14=1; break;case 3: F_SW_15=1; break;case 4: F_SW_16=1; break;} } ; break; } }}}
5.7、无按键时判断子程序如下:
/**********************************************************************
函 数:key_release() ---> 无按键子程序
输 入:无
输 出:无
返 回:无
说 明:
1、
***********************************************************************/
void key_release()
{if (++r_NoKey_cnt>4) {r_key_t1 =0; //扫完一轮,没有按键,按键计数清0r_NoKey_cnt=0; //无按键计数变量清0F_Key_state=0; //按键状态标志位}}
六、在主程序内搞个测试程序, 下载到芯片内测试OK。
void main()
{sys_init(); //系统初始化while(1){ WDTC |= 0x10; //看门狗清0 matrix_key(); //按键扫描P10=~P10;if (key_flag0 | key_flag1) //查询按键标志位{P12=~P12; // 按任意按键,IO口反转key_flag0=0; // 按键标志位都清0key_flag1=0; }sleep(); //睡眠}
}
7、有图有真相:
八、每天努力一点点,十年之功,必出大成果, 加油加油~!!
单片机C语言之学习矩阵按键相关推荐
- 单片机怎么跳出循环_自学单片机第二十七篇:矩阵按键的硬件测试
我们继续来说矩阵按键的问题,这次是用在实际电路中的.在仿真中我们没有发现问题,但是文章最后我提出了,这个电路在实际应用中一定是存在问题的,那么问题在哪里呢? 这是我们分析的电路. 前几篇我们也对硬件进 ...
- 51学习-矩阵按键篇
使用并行接口方式连接键盘,对独立式键盘而言,8根I/O口线可以接 **8** 个按键,而对矩阵式键盘而言,8根I/O口线最多可以接 **64** 个按键. 项目(工程)的时候,我们经常要用到比较多的按 ...
- 单片机c语言怎么实现按键松开,灯还保持松开前的状态,单片机C语言程序设计:K1-K4按键状态显示...
时间:2013-05-22 15:40:01 /* 名称:K1-K4 按键状态显示 说明:K1.K2 按下时 LED 点亮,松开时熄灭, */ K3.K4 按下并释放时 LED 点亮,再次按下并释 ...
- 矩阵按键及独立按键工作原理
文章目录 前言 一.独立按键工作原理 二.矩阵按键 1.原理图 总结 前言 学习矩阵按键前需要理解独立按键工作原理及扫描原理 一.独立按键工作原理 开发板所有io口默认全是高电平即 1: 独立按键外接 ...
- 独立按键和矩阵按键c语言,单片机独立按键与矩阵按键原理图
当前位置:电工之家 > 电工知识 > 单片机 > 正文 单片机独立按键与矩阵按键原理图 时间:2017-02-22 12:40 来源:电工之家 单片机独立按键与矩阵按键原理图 独立按 ...
- 单片机矩阵消抖延时c语言,单片机矩阵按键定时器消抖程序源码
芯片是采用的stc89c51单片机. 下面是矩阵键盘的电路图,矩阵键盘是接在p2口的. 下面是单片机部分的图,数码管显示等完整的原理图可以从http://www.51hei.com/f/ks51.pd ...
- 蓝桥杯单片机学习4——独立按键矩阵按键
上期学习了数码管的静态显示,这次我们来学习独立按键&矩阵按键 独立按键 原理很简单,当作为独立按键使用时,跳线帽的23接在一起,此时按键如果按下,则按键连接的IO口电平会被拉低,通过捕获IO的 ...
- 51单片机学习记录(五)矩阵按键
文章目录 1.矩阵按键的控制原理 2.矩阵按键实现 1.行列式法实现矩阵按键 2.线翻转法实现矩阵按键 3.按键实战 1.矩阵按键的控制原理 独立按键与单片机连接时, 每一个按键都需要单片机的一个 I ...
- 51单片机——数码管、按键、矩阵按键C语言入门编程
目录 数码管: 1.静态数码管:第二位数码管显示0 2.动态数码管:每一位数码管依次显示对应位数 按键: 1.独立按键:按下按键对应LED亮灭 矩阵按键: 1.矩阵按键:按下的每个按键,数码管显示对应 ...
最新文章
- linux python cpu温度,linux-raspbian系统下编写python脚本显示树莓派的当前cpu温度、使用率、内存和硬盘信息...
- Ionic(ionicframework)一款接近原生的Html5移动App开发框架 中文网
- matlab相语法,学会System Generator(10)——支持的MATLAB语法
- python国内谁的书最好看_强烈建议|转行Python最好看一下这篇文章
- mac SecureCRT设置
- 如何选择LoRa产品
- android面试题精选
- SVG图片以 https 链接的方式展示在页面上,并且可继承父类的颜色大小(类似阿里巴巴iconfont)
- 必备的Linux基础命令
- MFC工作笔记0007---消息映射处理
- 2017云栖大会门票转让_2018云栖大会门票价格及购买流程!附赠购买代金券
- 两个类似的ViewModel一个可以重写事件,另一个不能重写事件,是哪里出了错。...
- opencv 摄像机标定
- html盒模型中border的写法,CSS盒模型--边框设置:border: 1px solid red(像素 样式 颜色 ),border-bottom:1px dotted #ccc...
- python商品评论数据采集与分析可视化系统 Flask框架 requests爬虫 NLP情感分析 毕业设计 源码
- STM32+ESP8266连接电脑Qt网络上位机——QT篇
- 华为大佬:做一个快乐的程序员
- 电商系统,商品属性表和功能设计,可用于各种实体的属性
- log报错的原因解决
- java图片式验证码的实现(引入hutool工具类和自己编写工具类两种方法)