C语言矩阵键盘函数疑问
假设您按下了按钮3.3,即最左上方的按钮,如下解释您的代码unsigned char scan() {unsigned char a,b,c,i;P3=0XF0;//P3=11110000,即P3口高4位置1,设置高4位为输入状态a=P3; //因为您按下了3.3,且高4位设置为输入,3.3按下时,P3^0与P3^4导通, //故P3^4 被拉低,所以此时a=11100000=0xE0delay(20); P3=0X0F; //P3=00001111,即P3口低四位置1,设置低4位为输入状态b=P3; //因为您按下了3.3,且低4位设置为输入,3.3按下时,P3^0与P3^4导通, //故P3^0被拉低,所以此时b=00001110=0x0Ec=a+b; //综合行码和列码 c=0xE0+0x0E=0xEEfor(i=0;i<16;i++)if(c==tab[i])return i; //查表检测按键序号,找到即返回,后面的return -1无需执行return -1; //找不到,则返回-1}不知道这个回答您满意否?
我想你说的是单片机的键盘设置吧,相对于独立按键来说矩阵键盘的确可以减少io的使用,键盘的读取可以是中断,查询这两种方式为主,因为人的按键动作相对于单片机的处理速度来说是相当的慢,我觉得采用查询方式就完全能够达到要求,你可以使用定时器产生个时间片(10ms)左右,去查询键盘状态,在实际中发现实时性还是相当好的。至于你说的交互式键盘我不太清楚,矩阵键盘若采用中断方式的话会在线路上体现的更稍麻烦一些,希望我的回答能给你提供帮助。
看程序中P1.0-P1.3是行扫描输出,P1.4-P1.7是扫描输入。所以原理是P1.0-P1.3中每次只有一个引脚输出0,其余输出1,然后读取P1.4-P1.7是否有引脚为0;如果有0说明有按键按下,如果全1说明没有按键按下。
scancode这个变量就是用于控制P1.0-P1.3(P1 = scancode;由这句输出)中每次只有一个引脚输出0的。
scancode = 0xfe;这句中bit0值为0,其余bit为1,所以开始时,P1 = scancode;由这句输出后,P1.0为0,其余引脚为1。
scancode = (scancode << 1) | 0x01;这句使为0的bit左移一位(依次值为0xFE, 0xFD, 0xFB, 0xF7, 0xEF)。0xFE, 0xFD, 0xFB, 0xF7都满足while ((scancode &0x10) != 0)这个条件,而0xEF则不满足了,所以说<此语句只检查第五位是否为1,如果最低列按下后不就等于零了,就跳过此函数了>,到这就所有按键都扫描过了,没有按键按下(如果有按键按下,中途就返回了)。
if ((P1 &0xf0) != 0xf0)这句中P1 &0xf0表示只判断P1.4-P1.7,只有当前按下的按键所在行扫描输出为0时,这个表达式才成立(这时(P1 &0xf0) != 0xf0);否则这个表达式肯定不成立(这时(P1 &0xf0) == 0xf0),所以说当前行。
return ((~scancode) + (~tmpcode));这句就是如果有按键按下,那么直接返回键值,并不再进行循环退出程序。
程序格式要注意,下面这样更清楚:
uchar keyscan(void)
{
uchar scancode, tmpcode;
P1 = 0xf0; // 发全0行扫描码
if ((P1 &0xf0) != 0xf0)
// 若有键按下
{
delay(); // 延时去抖动
if ((P1 &0xf0) != 0xf0)
// 延时后再判断一次,去除抖动影响
{
scancode = 0xfe;
while ((scancode &0x10) != 0)
// 逐行扫描<此语句只检查第五位是否为1,如果最低列按下后不就等于零了,就跳过此函数了>
{
P1 = scancode; // 输出行扫描码
if ((P1 &0xf0) != 0xf0)
// 本行有键按下<为什么是行?哪一列按下此句都成立啊>
{
tmpcode = (P1 &0xf0) | 0x0f;
/* 返回特征字节码,为1的位即对应于行和列 */
return ((~scancode) + (~tmpcode));
}
else
scancode = (scancode << 1) | 0x01;
// 行扫描码左移一位
}
}
}
return (0); // 无键按下,返回值为0
}
单片机矩阵键盘读取,怎么在主函数调用键盘值
声明一个全局变量keyvalue,在主函数中 keyvalue=sc_key();这样就可以了。
keil 4x4矩阵键盘出错。。KEY4_4.H(18): error C141: syntax error near...
void key4_4(uchar key) \/\/错误就在这里。这个函数,不应该带有参数,改成:void key4_4()试试看。
单片机c语言编程实例问题!我用矩阵键盘控制LED灯!但是按键盘没有反应...
keyscan()函数有错,进行了修改,如下。另外,楼主是输出是P1口,但是给出的电路图里面,没有P1的电路。uchar keyscan(){ P3 = 0x7f;temp = P3;temp = temp & 0x0f;while(temp != 0x0f) { delay(5);temp = P3;temp = temp & 0x0f;while(temp != 0x0f) { temp = P3;switch(...
矩阵键盘检测,求解,程序自己写的,按键没反应。
矩阵键盘检测,求解,程序自己写的,按键没反应。 #include<reg52.h>#include<74hc595.h>#include<boardinit.h>#include<delay.h>#defineucharunsignedchar#defineuintunsignedintsbitwela=P2^6;sbitdula=P2^5;ucharnum,temp;ucharcod... #include<reg52.h>#include<74hc595.h>#include<boardinit.h>#include<...
跪求!7X7矩阵键盘这个C语言程序怎么改!?
\/\/ === 扫描4*4键盘显示函数 === void scanner(void) \/\/ 扫瞄函数开始 { uchar hang,lie1; \/\/ 声明变数(hang:行lie1:列,dig:颢示位)uchar lie,num;\/\/ 声明变数(lie:列键值,num:按键码)for(hang=0;hang<7;hang++) \/\/ for回圈,扫瞄第hang行 { KEYP = scan[hang]; \/\/ ...
郭天祥的51单片机,我写明明是检测矩阵键盘的,最后出来就变成了独立建...
第一:你最好把现象结果说清楚,你这个键盘显示出来肯定只会是0 1 2 3。第二:你这个矩阵键盘函数还是跟着郭天祥写的步子走,你使用两个while而没有第二个if不知是怎么回事。希望我的回答能帮助到你。
单片机中的4×4矩阵键盘的键值怎么求?
原理如同矩阵数列的行列式 可以用下述代码进行:\/\/*** \/\/函数功能: \/\/单片机驱动4*4键盘,读入键盘值并使用数码管静态 \/\/显示按键键值,若没有数码管用8421码显示LED灯也可以的 \/\/读入原理:先令单片机端口输出11110000读一次,然后 \/\/再令单片机输出00001111读一次把两次的值相加,最后 ...
矩阵键盘一次检测16个键,错在哪
不可以这样,主要是应为矩阵键盘的原理得弄清楚,矩阵键盘必须设定一个口为0才能用相应的代码表示哪一行的键位,你这一下子全写出来是不行的,具体的只要把键盘的如何操作再看看就懂了
80c51单片机的矩阵键盘检测,按键释放代码要怎样写?谢谢。
---*\/ unsigned char KeyScan(void) \/\/键盘扫描函数,使用行列逐级扫描法 { unsigned char Val;KeyPort=0xf0;\/\/高四位置高,低四位拉低 if(KeyPort!=0xf0)\/\/表示有按键按下 { DelayMs(10); \/\/去抖 if(KeyPort!=0xf0){ \/\/表示有按键按下 KeyPort=0xfe; \/\/检测第一行 if(KeyPort...
51单片机矩阵键盘检测方面的问题
第一个问题,应该是考虑如果先开锁存器,在那一时刻,P0的值还是上一次给P0赋的值,下在一条语句才将这次的值给P0,这样会造成数码管的余辉,静态显示的时候,因为太快看不到,动态显示时,就会比较明显了。第二个问题他的程序应该检测的是高四位,是否被拉低,因为temp和0xf0与,低四位不管是...
源哀足光: 看程序中P1.0-P1.3是行扫描输出,P1.4-P1.7是扫描输入.所以原理是P1.0-P1.3中每次只有一个引脚输出0,其余输出1,然后读取P1.4-P1.7是否有引脚为0;如果有0说明有按键按下,如果全1说明没有按键按下.scancode这个变量就是用于控...
浦东新区13055458235: c语言3x4矩阵按键问题 - ?
源哀足光: 3X4矩阵按键的检测 #include <reg51.h> void display(unsigned int lednum); #define uchar unsigned char #define uint unsigned int void mkeyscan(); void delay(uchar i); uchar key,temp,num; uchar LedOut[10]; //此表为 LED 的字模, 共阴数码管 0-...
浦东新区13055458235: 在51单片机中用C51编写矩阵键盘的程序.下面有我编写的,但不知道其中的keyscan()的函数,怎么就错了. - ?
源哀足光: 函数返回值类型为非空的 但是在函数中有一个或者以上的分支没有返回值 例如 int test() {if(){....return 0;}else if{ ......return 0;}else{.....而这里没有返回值的话就可能会出现这种情况了} } uchar keyscan(void) {for( ..)..return ()..//此处需加返回值 }
浦东新区13055458235: 自学单片机 c语言编程 写了个矩阵键盘扫描程序 老是不行,郁闷了两天了呀 请大侠指点下 - ?
源哀足光: void keyscan()//矩阵键盘扫描程序 { P0=0x0f;if(P0!=0x0f) //这里条件0,不会执行后面的程序吧 {delay (10);if(P0!=0x0f){ a=P0; P0=0xf0; b=P0; a= a|b; }; }; }
浦东新区13055458235: 51单片机矩阵键盘检测方面的问题 - ?
源哀足光: 第一个问题,应该是考虑如果先开锁存器,在那一时刻,P0的值还是上一次给P0赋的值,下在一条语句才将这次的值给P0,这样会造成数码管的余辉,静态显示的时候,因为太快看不到,动态显示时,就会比较明显了.第二个问题他的程序应该检测的是高四位,是否被拉低,因为temp和0xf0与,低四位不管是什么,都是0,只有高四位的值从1,变为0,0xf0才会发生改变.
浦东新区13055458235: 单片机矩阵扫描键盘问题 C语言 - ?
源哀足光: 每个switch语句后加一句 while(temp!=0x0f) { temp=P3; temp=temp&0xf0; } 即:按键松手检测
浦东新区13055458235: c语言4X4矩阵键盘怎样判断键盘按键释放? - ?
源哀足光: 大体思路如下:绝大多数按键在硬件设计时可以做到在按下时触发中断,但释放按键并未设计触发中断的机制.因此,如果你在mcu中打算检测按键释放的状态,有如下几种方式: 1、按下&释放均采用轮询方式检测. 这种方式灵活性最差. 2、按下(触发中断),中断中检测到按下状态时,开始轮询(并不一定要在中断过程中进行)按键状态,同方式1. 灵活性不好. 3、采用定时中断进行按键状态检测. 这种方式最好.可以做到及时响应按键各种操作.并且可以简化按键抖动的过滤.
浦东新区13055458235: 怎么样用C语言写51单片机4*4矩阵按键使之响应? - ?
源哀足光: 这个是键盘函数,你参考一下,网上也有很多资料的 uchar keyscan() { P3=0xfe; temp=P3; temp=temp&0xf0; while(temp!=0xf0) { delay(5); temp=P3; temp=temp&0xf0; while(temp!=0xf0) { temp=P3; switch(temp) { case 0xee:num=1; break; case 0...
浦东新区13055458235: 我想用矩阵盘输入数字(比如设置时间),在12864上显示,并实现设置、清除、确认等功能,该怎么写C语言 - ?
源哀足光: 要实现这个功能的话,你先把矩阵键盘的程序编写好,最好是做成一个函数,调用时能返回某一个特定的数值,比如你自己定义一个按键为“1”,那就返回一个“1”,然后有几个按键是左右移动,确认,清楚这些按键,这些按键可以自己定义,然后在程序里进行switch判断就好了,把对应的按键值进行分别编写功能,这些功能具体要怎么实现就看你怎么编写了,如果是我的话,我建议用红外遥控,使用1838这个红外接收器来接收,并通过程序来解码,解析出红外遥控按下的键值就能够实现矩阵键盘的功能,而且就只占用一个中断口,和一个定时器,但是能输入的按键比矩阵的多,而且很直观
浦东新区13055458235: C语言:键盘输入10*10的矩阵,找到最小值和最大值,并交换. - ?
源哀足光: 程序实现如下:#include <stdio.h>#define ROW 10#define QUEUE 10 int main(void) { int max=0,min=0,i,j,k,max_i,max_j,min_i,min_j; int shu_zu[ROW][QUEUE]={0}; for(i=0;i<ROW;i++) { printf("Enter %d numbers: ",QUEUE); for(j=0;j<QUEUE;j++...