TA的每日心情 | 奋斗 2014-11-27 16:02 |
---|
签到天数: 66 天 连续签到: 1 天 [LV.6]常住居民II
|
本帖最后由 tao475824827 于 2013-3-23 21:57 编辑
在论坛里做了N久的伸手党了(感觉论坛里有一半的求助帖都是我发的……也感谢大家一直帮我解决着问题……感谢!)
今天跟大家分享一下我做的一个扫描4*4矩阵的小程序。
不会用比较高端的方式,就用的pin的IO口来做的……囧……新学,确实水平不高……
我记得微机原理书上说过,矩阵键盘的扫描方法一般三种方法
1、中断式:在键盘按下时产生一个外部中断通知CPU,并由中断处理程序通过不同的地址读取数据线上的状态,判断哪个案件被按下。
2、扫描法:对键盘上的某一行送低电平,其他行为高电平,然后读取列值。若列值中有一位是低,则表明该行与低电平对应列的键被按下;否则,扫描下一行。
3、反转法:先将所有行扫描线输出低电平,读列值。若列值有一位是低,则表明有键按下,读列值;然后所有列扫描线输出低电平,再读行值。根据读到的值组合就可以查表1 得到的键码。
个人习惯,一般用反转法,可能是因为用的扫描次数最少吧。
矩阵键盘电路图如下
矩阵键盘电路
遇到的第一个问题就是管脚既要做输入,又要做输出,就是要选择bidirection模式,但是一直没找着这个的资料,也不怎么会用,不知道设置成什么模式比较好,给support_china@cypress.com发了邮件询问,他也给我回了,如下图
回信
然后我就懵了……我不知道去哪里下载工程……崩溃……论坛里有知道的可以告诉我一下,谢谢!
于是我就自己测试,最后觉得 Resistive Pull Up/Down(上下拉)这个模式貌似能用
直接输出高的话,我用表测是3.3v,带一个0v的,两个就都变成1.65v,识别仍然是 高。
所以我就用这个模式做的,不知道是不是很不稳定。但是至少出结果了。
原理图中再拉一个LCD出来做显示即可,默认设置。
原理图
引脚如下
引脚
程序写的比较水,大家轻拍
#include <device.h>
void main()
{
uint16 num_button=0;
CYGlobalIntEnable;
LCD_Start();
LCD_Position(0,0);
LCD_PrintString("num");
for(;;)
{
row1_Write(1);
row2_Write(1);
row3_Write(1);
row4_Write(1);
column1_Write(0);
column2_Write(0);
column3_Write(0);
column4_Write(0);
if(column1_Read()||column2_Read() || column3_Read()||column4_Read()) //检测到有电平被拉高
{
// CyDelay(20);//CyDelayCycles(2000 * 48); /* 延时函数Delay 2000us(20ms) based on 48MHz clock */
if(column1_Read())
{
row1_Write(0);
row2_Write(0);
row3_Write(0);
row4_Write(0);
column1_Write(1);
if(row1_Read()) {num_button=1;}
if(row2_Read()) {num_button=5;}
if(row3_Read()) {num_button=9;}
if(row4_Read()) {num_button=13;}
}
if(column2_Read())
{
row1_Write(0);
row2_Write(0);
row3_Write(0);
row4_Write(0);
column2_Write(1);
if(row1_Read()) {num_button=2;}
if(row2_Read()) {num_button=6;}
if(row3_Read()) {num_button=10;}
if(row4_Read()) {num_button=14;}
}
if(column3_Read())
{
row1_Write(0);
row2_Write(0);
row3_Write(0);
row4_Write(0);
column3_Write(1);
if(row1_Read()) {num_button=3;}
if(row2_Read()) {num_button=7;}
if(row3_Read()) {num_button=11;}
if(row4_Read()) {num_button=15;}
}
if(column4_Read())
{
row1_Write(0);
row2_Write(0);
row3_Write(0);
row4_Write(0);
column4_Write(1);
if(row1_Read()) {num_button=4;}
if(row2_Read()) {num_button=8;}
if(row3_Read()) {num_button=12;}
if(row4_Read()) {num_button=16;}
}
}
if(num_button<10)
{
LCD_Position(1,0);
LCD_PrintNumber(num_button);
LCD_Position(1,1);
LCD_PrintString(" "); //覆盖之前两位数的个位数
}
else
{
LCD_Position(1,0);
LCD_PrintNumber(num_button);
}
}
}
实物图就不上了、、手机不在、、
实现的结果就是按4*4键盘,1602上会显示出 你按下的键的编码 1~16
build没问题
实际program的时候,有些时候(我有时有,有时没有)会提示
error
这个怎么解决,论坛里有人知道么?
不过提示了也没关系,只要按一下板子的复位键就行,只能正常工作了。(囧)
附件上传
Design01_keyboard.rar
(2.38 MB, 下载次数: 72)
|
|