用c 语言编写程序3 3矩阵6,C语言编写的矩阵键盘程序为什么第一列的达成条件和后面三列不一样?...

//实验效果:依次按下S7~S19,倒数第四个数码管会依次显示0~F。

//不足:所有按键在按下时那一刹那都会出现消隐的情况,若长按,数码管一直保持消隐状态,直至松手。

#include

#include

#include

void Delay5ms();

void Delay10us();

unsigned char smg_Pxdata[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};//数码管片选数据,共有八片,为共阳极数码管。

unsigned char smg_Dxdata[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//数码管段选数据,依次为0~f。

int buzz();

int smg(tem);

int button();

unsigned char num;//全局变量,使用于按键函数和数码管显示函数中。

int main()

{

while(1)

{

buzz();

button();

smg(num);

}

return 0;

}

int buzz()

{

XBYTE[0xA000]=0;//关闭蜂鸣器。

return 0;

}

int smg(tem)//数码管显示程序,和按键函数结合使用,用于判断按下哪个键。

{

XBYTE[0xC000]=0;//片选信号——消隐。

Delay10us();

XBYTE[0xE000]=smg_Dxdata[tem];//段选信号。

XBYTE[0XC000]=smg_Pxdata[3];//片选信号——始终显示一片数码管。

Delay10us();

return 0;

}

int button()//P3.0~P3.3为行线,P3.4、P3.5、P4.2、P4.4为列线。

{

unsigned int key;

P44=0,P42=1,P3=0x7f;//所有8个端口中,只令1个端口为低电平,若1个按键按下,那么肯定有另外1个端口会被拉低。因此,通过扫描就可以知道是哪个按键按下了。

key=P3&0x0f;//和0x0f相与,让高四位在任何情况下始终为0000,也就是让case后的值始终是0x0****形式。

P44=1,P42=0,P3=0xbf;

key=(key<<4)|(P3&0x0f);//为保留上一行扫描的数据,故将数据左移4位。此处“P3&0x0f”是为了将高四位清0,进而再进行位运算时不会清除之前的数据。

P44=1,P42=1,P3=0xdf;

key=(key<<4)|(P3&0x0f);

P44=1,P42=1,P3=0xef;

key=(key<<4)|(P3&0x0f);

if(((key&0x0f000)!=0x0f000)|((key&0x00f00)!=0x00f00)|((key&0x000f0)!=0x000f0)|((key&0x0000f)!=0x0000f))//通过位运算,提取出按下不同按键时各自独有的数据部分,并加以判断。

{

Delay5ms();//第一次消抖开始:消除按键前沿抖动,即按下抖动。

P44=0,P42=1,P3=0x7f;

key=P3&0x0f;

P44=1,P42=0,P3=0xbf;

key=(key<<4)|(P3&0x0f);

P44=1,P42=1,P3=0xdf;

key=(key<<4)|(P3&0x0f);

P44=1,P42=1,P3=0xef;

key=(key<<4)|(P3&0x0f);

if(((key&0x0f000)!=0x0f000)|((key&0x00f00)!=0x00f00)|((key&0x000f0)!=0x000f0)|((key&0x0000f)!=0x0000f))

{

P44=0,P42=1,P3=0x7f;

key=P3&0x0f;

P44=1,P42=0,P3=0xbf;

key=(key<<4)|(P3&0x0f);

P44=1,P42=1,P3=0xdf;

key=(key<<4)|(P3&0x0f);

P44=1,P42=1,P3=0xef;

key=(key<<4)|(P3&0x0f);//第一次消抖结束。

switch(key)//开始判断key的值,并依此赋予num不同的值,然后将值传递给数码管显示函数。

{

case 0x0fffe:num=15;break;

case 0x0fffd:num=14;break;

case 0x0fffb:num=13;break;

case 0x0fff7:num=12;break;

case 0x0ffef:num=11;break;

case 0x0ffdf:num=10;break;

case 0x0ffbf:num=9;break;

case 0x0ff7f:num=8;break;

case 0x0feff:num=7;break;

case 0x0fdff:num=6;break;

case 0x0fbff:num=5;break;

case 0x0f7ff:num=4;break;

case 0x0eeee:num=3;break;//正确的代码应该是0x0efff 。

case 0x0dddd:num=2;break;//正确的代码应该是0x0dfff。

case 0x0bbbb:num=1;break; //正确的代码应该是0x0bfff  。

case 0x07777:num=0;break;//正确的代码应该是0x07fff 。

default://倘若有的按键按下没有达到预期效果,根据这个来判断key的值是否正确。

{

XBYTE[0x8000]=0xf5;//LED灯亮。

Delay5ms();

XBYTE[0x8000]=0xff;//LED灯灭。

}

}

while (((key&0x0f000)!=0x0f000)|((key&0x00f00)!=0x00f00)|((key&0x000f0)!=0x000f0)|((key&0x0000f)!=0x0000f))//第二次消抖开始:消除后沿抖动,即松手抖动。

{

P44=0,P42=1,P3=0x7f;

key=P3&0x0f;

P44=1,P42=0,P3=0xbf;

key=(key<<4)|(P3&0x0f);

P44=1,P42=1,P3=0xdf;

key=(key<<4)|(P3&0x0f);

P44=1,P42=1,P3=0xef;

key=(key<<4)|(P3&0x0f);

}//第二次消抖结束。

}

}

return 0;

}

void Delay5ms()                //单片机内部晶振频率@11.0592MHz

{

unsigned char i, j;

i = 54;

j = 199;

do

{

while (--j);

} while (--i);

}

void Delay10us()                //单片机内部晶振频率@11.0592MHz

{

unsigned char i;

_nop_();

i = 25;

while (--i);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值