这个键盘扫描程序怎么解读

这个键盘扫描程序怎么解读,第1张

0x10折成二进制是00010000,高四位是列,那么程序就是逐列扫描的了,这是从最低列扫起,用它作为掩码,只留下一位。

P1 = 0xf0; // 发全0行扫描码,这句就是让所有的列先置高,行置低,是初始值,建议你把电路图对着看,可以在脑子里假设一个钮按下的状态再分析程序。

if ((P1&0xf0)!=0xf0) // 若有键按下,这句如果为真,就说明至少有一列中有键按下了,但是它是区别不出来是哪一列的,只能证明有键按下,当然就更分不出来是哪行了。

scancode = 0xfe; //这句是给扫描码置一个初值,0xfe就是二进制的11111110,接着看后边。

while((scancode&0x10)!=0) // 逐行扫描,刚才说过,这个0x10就是二进制的00010000,和扫描码11111110做与之后留下00010000,那么这时如果在最低列中有键按下,表达式就为假了,没有键按下时才会为真,也就是继续扫描。这种方式不能处理多个键按下的情形,会低位优先,因为一旦有键按下了就不再扫后边的了。而此时注意scancode本身中是行的值。

P1 = scancode; // 输出行扫描码,注意扫描码中的值并未改变,是11111110。

if ((P1&0xf0)!=0xf0) // 本行有键按下,这个判断中对P1做与,如果没有键按下,那么P1应该是和scancode中的值一样的,和0xf0做与之后就是留下高四位得到11110000,一旦有按下的键,相应的位会被拉低,肯定就不等于11110000了,比如说11100000,那么表达式就为真了。

tmpcode = (P1&0xf0)|0x0f; //这句将P1与上的值与0x0f做或运算,得到低4位为全1的列扫描码。

return((~scancode)+(~tmpcode)); //由于其它的位都被填了1,每次招描的结果都只有1个0,取反输出就得到了只有一个1的码。

else scancode = (scancode<<1)|0x01; // 行扫描码左移一位,这样就是将scancode中的11111110变成11111100,而且还要或上0x01保持最低位被补1变成11111101,依次后边会变成11111011和11110111,完成四个行的扫描。

重复上述过程完成所有的扫描。

你要放到“死循环”中不断扫描。他的原理图一般是这样的

以第一个按键为例,当你按下时I/O口读到的数据就不是0x0f了。好吧你最开始的赋值错了。你要用0xee,0xde检测的话你应该给0xfe。每四个按键是一组。我这有一个我做密码锁的程序你参考一下。

void key()

{

    P3=0xfe;

    if(P3!=0xfe)

    {

        time(50);

        if(P3!=0xfe)

            {

            switch(P3)

                {

case 0xee:num=1,cs++;

break;

case 0xde:num=2,cs++;

break;

case 0xbe:num=3,cs++;

break;

case 0x7e:num=4,cs++;

break;

                }

        }

        while(P3!=0xfe);

}

P3=0xfd;

if(P3!=0xfd)

{

time(50);

if(P3!=0xfd)

{

switch(P3)

{

case 0xed:num=5,cs++;

break;

case 0xdd:num=6,cs++;

break;

case 0xbd:num=7,cs++;

break;

case 0x7d:num=8,cs++;

break;

}

}

while(P3!=0xfd);

}

P3=0xfb;

if(P3!=0xfb)

{

time(50);

if(P3!=0xfb)

{

         switch(P3)

{

case 0xeb:num=9,cs++;

break;

case 0xdb:num=0,cs++;

break;

case 0xbb:cs++;

break;

case 0x7b:num=10,cs=0,a=b=c=d=e=f=10,ply=1;

break;

}

  }

while(P3!=0xfb);

}

}

楼主的那个程序我看不太懂:不过根据你的大概意思更改了一下程序,希望对你有帮助!下面是我的程序代码:

/

 文件名  : 矩阵键盘c

 描述    :  该文件实现了 4  4 键盘的试验。通过数码管的最后一位来显示

 当前的按键值。

/

#include<reg51h>

#include<intrinsh>

#define uint unsigned int

#define uchar unsigned char

uchar code table[16] = {0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71}; //用于数码管显示 本程序未用

uchar Key;  //读出的键值

/

 名称 : Delay_1ms()

 功能 : 延时子程序,延时时间为 1ms  x

 输入 : x (延时一毫秒的个数)

 输出 : 无

/

void Delay_1ms(uint i)//1ms延时

{

uchar x,j;

for(j=0;j<i;j++)

for(x=0;x<=148;x++);

}

/

 名称 : delay()

 功能 : 延时,延时时间大概为140US。

 输入 : 无

 输出 : 无

/

void delay()

{

int i,j;

for(i=0; i<=10; i++)

for(j=0; j<=2; j++);

}

/

 名称 : Keyscan()

 功能 : 实现按键的读取。下面这个子程序是按处理 矩阵键盘 的基本方法处理的。

 输入 : 无

 输出 : 按键值

/

uchar Keyscan(void)

{

uchar i,j, temp, Buffer[4] = {0xef, 0xdf, 0xbf, 0x7f};

for(j=0; j<4; j++)

{

P1 = Buffer[j];

temp = 0x01;

for(i=0; i<4; i++)

{

if(!(P1 & temp))

{

return (i+j4);   //这里返回的是按键牌排列值!

}

temp <<= 1;

}

}

}

/

 名称 : InitTimer0()

 功能 : 用于定时器初始化。

 输入 : 无

 输出 :

/

unsigned int Timer_1s=0;//定时器中断响应次数变量

//定时时间长度=定时中断响应时间定时中断响应次数

void InitTimer0()

{

//    AUXR=0x80;  //定时时钟为Sysclk,即晶振时钟 实用于具有单时钟周期的单片机系列

//特别的还需要注意时钟设置在其它模块中的设置,如波特率的定时器1时钟设置

TMOD = 0x21; //定时器0工作于方式1,,16位定时,定时器1为波特率发生器

//特别地,高四位控制定时器1,低四位控制定时器0,

//所以此处需要注意程序中是否并存定时器1工作,如串口就需要定时1的设置为TMOD=0x20

TH0 = 0x0B8; //定时装如初值   //定时1000us 即1ms

TL0 = 0x00; //定时其它值可由需要重新计算初值

ET0 = 1; //允许中断

TR0 = 1; //启动定时器

}

/

 名称 : Timer0Interrupt()interrupt 1

 功能 : 定时器中断。

 输入 : 无

 输出 :

/

void Timer0Interrupt() interrupt 1

{

TR0 = 0; //关闭定时器

TH0 = 0x0B8; //重装初值

TL0 = 0x00;

Timer_1s++; //中断响应次数自加1

if(Timer_1s=20) //可以在此处调节按键的扫描时间

{

/一下是扫描按键并带返回值的结果/

P1 = 0xf0;

if(P1 != 0xf0)

{

Delay_1ms(15); //按键消抖

if(P1 != 0xf0)

{

Key = Keyscan();

}

}

}

TR0 = 1; //启动定时器

}

/

 名称 : Main()

 功能 : 主函数

 输入 : 无

 输出 : 无

/

void Main(void)

{

InitTimer0();//初始化定时器

EA =1;       //开中断

while(1)

{

switch (Key) //判断键值(那一个键按下)

case 0: /加入需要执行该按键下的程序/; break;  //假设0号按键被按下

case 1: /加入需要执行该按键下的程序/; break;

case 2: /加入需要执行该按键下的程序/; break;

case 3: /加入需要执行该按键下的程序/; break;

case 4: /加入需要执行该按键下的程序/; break;

case 5: /加入需要执行该按键下的程序/; break;

case 6: /加入需要执行该按键下的程序/; break;

case 7: /加入需要执行该按键下的程序/; break;

case 8: /加入需要执行该按键下的程序/; break;

case 9: /加入需要执行该按键下的程序/; break;

case 10: /加入需要执行该按键下的程序/; break;

case 11: /加入需要执行该按键下的程序/; break;

case 12: /加入需要执行该按键下的程序/; break;

case 13: /加入需要执行该按键下的程序/; break;

case 14: /加入需要执行该按键下的程序/; break;

case 15: /加入需要执行该按键下的程序/; break; 

default: break;

}

}

}

以上就是关于这个键盘扫描程序怎么解读全部的内容,包括:这个键盘扫描程序怎么解读、矩阵键盘扫描程序、单片机实现对按键的定时扫描 哪位高手能帮忙把下面按键扫描程序改成用定时器对按键进行定时扫描啊,我用的等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zz/10135002.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存