历史上的今天
返回首页

历史上的今天

今天是:2025年03月06日(星期四)

正在发生

2020年03月06日 | 51单片机-矩阵键盘模块-长短按键&数码管显示-编程模板

2020-03-06 来源:eefocus

1.视频

bilibili视频地址:


https://www.bilibili.com/video/av90715834


51单片机-矩阵键盘模块-长短按键&数码管显示-模块化编程模版


2.文件

代码文件下载地址:


https://download.csdn.net/download/weixin_43130546/12180191


3.说明

此段代码体现了模块化编程思想,具有很好的可移植性。


用到的知识点包括:矩阵键盘扫描,长短按键,按键动作识别;数码管动态扫描,数码管高位不显示;LED;BUZZER;片内片外RAM。


89C52:

有 8K FLASH(存程序.hex文件的地方 );

有512BRAM(程序运行过程中,存临时数据的地方);

分为128B片内RAM;128B片内扩展RAM;256B片外RAM;


RAM:

data: 片内RAM,直接调用。从 0x00 到 0x7F 共 128B 。(默认用这个)

idata: 片内扩展RAM,寄存器寻址间接调用。从 0x80 到 0xFF 共 128B 。(一般用于中断,函数调用的堆栈)

pdata: 片外扩展RAM,1个寄存器寻址间接调用。从 0x00 到 0xFF 共 256B 。(一般用于定义很大很多的数)

pdata: 片外扩展RAM,2个寄存器寻址间接调用。从 0x0000 到 0xFFFF 共 64K 。(一般用于定义很大很多的数)(89C52没有这么多)


4.代码


#include


sbit BUZZER = P2^3;


sbit DULA = P2^6;

sbit WELA = P2^7;


sbit KEYOUT1 = P3^0;

sbit KEYOUT2 = P3^1;

sbit KEYOUT3 = P3^2;

sbit KEYOUT4 = P3^3;

sbit KEYIN1 = P3^4;

sbit KEYIN2 = P3^5;

sbit KEYIN3 = P3^6;

sbit KEYIN4 = P3^7;


unsigned char code DUTable[16] = 

{

0x3F,0x06,0x5B,0x4F,

0x66,0x6D,0x7D,0x07,

0x7F,0x6F,0x77,0x7C,

0x39,0x5E,0x79,0x71

};


unsigned char code WETable[8] = 

{

~0x80,~0x40,~0x20,~0x10,

~0x08,~0x04,~0x02,~0x01

};


unsigned char LedBuff[8] = 

{

0x3F,0x00,0x00,0X00,

0X00,0X00,0X00,0X00

};


unsigned char code KeyCode[4][4] = 

{

{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}

};


unsigned char KeyStay[4][4] = 

{

{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}

};


unsigned long pdata KeyTime[4][4] = 

{

{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}

};


unsigned long number = 0;


void ConfigTimer0(void);

void KeyDriver(void);


void main(void)

{

ConfigTimer0();

while(1)

{

KeyDriver();

}

}


void ConfigTimer0(void)

{

TH0 = 0xFC;

TL0 = 0x67;

EA = 1;

ET0 = 1;

TMOD &= 0xF0;

TMOD |= 0x01;

TF0 = 0;

TR0 = 1;

}


void ShowNum(unsigned char num)

{

char i;

static unsigned char buff[7];


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

{

buff[i] = num % 10;

num /= 10;

}

for(i=6; i>=1; i--)

{

if(0 == buff[i])

{

LedBuff[i] = 0x00;

}

else

{

break;

}

}

for(; i>=0; i--)

{

LedBuff[i] = DUTable[buff[i]];

}

}


void KeyAction(unsigned char KeyCoder)

{

number++;

ShowNum(number);

LedBuff[7] = DUTable[KeyCoder];

}


void KeyDriver(void)

{

unsigned char i,j;

static unsigned char KeyBack[4][4] = 

{

{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}

};

static unsigned long pdata KeyTimer[4][4] = 

{

{1000,1000,1000,1000},{1000,1000,1000,1000},

{1000,1000,1000,1000},{1000,1000,1000,1000}

};


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

{

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

{

if(KeyStay[i][j] != KeyBack[i][j])

{

if(1==KeyBack[i][j])

{

P1 = 0x00;

KeyAction(KeyCode[i][j]);

}

else                   

{

P1 = 0xFF;

}

KeyBack[i][j] = KeyStay[i][j];

}


if(KeyTime[i][j]>0)

{

if(KeyTime[i][j]>=KeyTimer[i][j])

{

KeyTimer[i][j] += 200;

KeyAction(KeyCode[i][j]);

BUZZER = 0;

}

}

else

{

KeyTimer[i][j] = 1000;

BUZZER = 1;

}

}

}

}


void LedScan(void)

{

static unsigned char i = 0;


P0 = 0x00;

DULA = 1;

DULA = 0;

P0 = WETable[i];

WELA = 1;

WELA = 0;

P0 = LedBuff[i];

DULA = 1;

DULA = 0;


i++;

if(i>=8)

{

i = 0;

}

}


void KeyScan(void)

{

unsigned char i;

static unsigned char KeyOut = 0;

static unsigned char KeyBuff[4][4] = 

{

{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF},

{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF}

};


KeyBuff[KeyOut][0] = (KeyBuff[KeyOut][0]<<1) | KEYIN1;

KeyBuff[KeyOut][1] = (KeyBuff[KeyOut][1]<<1) | KEYIN2;

KeyBuff[KeyOut][2] = (KeyBuff[KeyOut][2]<<1) | KEYIN3;

KeyBuff[KeyOut][3] = (KeyBuff[KeyOut][3]<<1) | KEYIN4;


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

{

if(0x00 == (KeyBuff[KeyOut][i] & 0x0F))

{

KeyStay[KeyOut][i] = 0;

KeyTime[KeyOut][i] += 4;

}

else if(0x0F == (KeyBuff[KeyOut][i] & 0x0F))

{

KeyStay[KeyOut][i] = 1;

KeyTime[KeyOut][i] = 0;

}

}


KeyOut++;

KeyOut &= 0x03;


switch(KeyOut)

{

case 0 : KEYOUT4 = 1; KEYOUT1 = 0; break;

case 1 : KEYOUT1 = 1; KEYOUT2 = 0; break;

case 2 : KEYOUT2 = 1; KEYOUT3 = 0; break;

case 3 : KEYOUT3 = 1; KEYOUT4 = 0; break;

default : break;

}

}


void InterruptTimer0(void) interrupt 1

{

TH0 = 0xFC;

TL0 = 0x67;


LedScan();

KeyScan();

}

推荐阅读

史海拾趣

Cedrat Technologies公司的发展小趣事

在电子行业中,振动控制是一个至关重要的领域。Cedrat Technologies凭借其在压电技术领域的深厚积累,成功开发了一套主动振动控制系统。该系统通过精确监测机械结构或设备的振动情况,利用压电执行器产生相位相反的振动信号,有效抵消原始振动。这一技术的问世,不仅大幅提升了设备的稳定性和精度,也为机械结构的振动控制开辟了新的途径。Cedrat Technologies因此在电子行业中树立了新的技术标杆。

Fillfactory Nv公司的发展小趣事

2015年,FIDELIX迎来了一个重要的转折点。在这一年,东芯半导体有限公司(以下简称“东芯半导体”)正式收购了FIDELIX 25.3%的股权,成为其第一大股东及实际控制人。这一收购标志着FIDELIX开始进入一个新的发展阶段。

通过与东芯半导体的合作,FIDELIX获得了更多的资金支持和市场资源。东芯半导体是一家专注于中小容量存储芯片研发、设计和销售的中国企业,在半导体领域拥有丰富的经验和资源。双方的合作不仅为FIDELIX带来了更多的发展机会,同时也加速了FIDELIX在国际市场上的扩张步伐。

在上述两个故事的基础上,可以根据FIDELIX公司的具体发展历程、重要事件、技术创新、市场策略等方面进行进一步的拓展和补充,以形成完整、详细的故事内容。

Engineered Components Co公司的发展小趣事

随着市场竞争的加剧,ECC意识到只有不断创新才能保持领先地位。因此,公司加大了对研发的投入,引进了一批先进的研发设备和人才。经过数年的努力,ECC成功研发出了具有更高精度、更好性能的电子连接器,并推出了一系列新型电子元件。这些新产品不仅满足了客户日益增长的需求,还为公司带来了更多的市场份额。

EDI [Electronic devices inc.]公司的发展小趣事

近年来,Eclipse Magnetics公司在电火花加工领域取得了显著的成就。他们推出的Micromag磁过滤器产品在电火花加工过程中实现了巨大的成本节约。通过与ADM精密工具和Sodi-tech EDM有限公司的合作,Eclipse Magnetics成功提高了Sodick AQ600L线蚀机的效率,减少了停机时间,为客户带来了显著的经济效益。

维峰电子(WCON)公司的发展小趣事

质量是企业的生命线。维峰电子始终将质量管理作为公司发展的重中之重。公司建立了完善的质量管理体系,从原材料采购、生产过程到产品检验等各个环节都进行严格把控。同时,公司还引入了先进的检测设备和技术,确保产品的质量和性能达到最高标准。这些措施的实施不仅提升了产品的竞争力,也赢得了客户的信任和好评。

B&B Electronics Manufacturing Company公司的发展小趣事

近年来,电子行业面临着技术更新迅速、市场需求多变等挑战。B&B公司积极应对这些挑战,不断调整和优化产品结构,加强技术创新和人才培养。同时,公司也密切关注行业动态和市场需求变化,为未来的发展做好充分准备。

这些故事虽然无法涵盖B&B公司发展的全部细节,但可以从不同侧面反映出公司在电子行业中的成长轨迹和发展脉络。作为一家在电子行业中具有一定影响力的公司,B&B公司的发展历程无疑是一个充满挑战和机遇的过程。

问答坊 | AI 解惑

wince 怎么让添加到NK的dll是没办法复制拷贝的?

如题。就是在*.bib文件下添加dll 属性是SH,(系统隐藏),可是在wince windows目录下是可以copy的,要怎么搞啊。。…

查看全部问答>

WinCE5.0系统加载完之后起不来

WinCE5.0系统加载完之后,屏幕还显示Logo,采用的是研华的嵌入式主板,Flash芯片采用M-System ,硬件驱动都是研华提供以及BSP, 我采用Hive-based注册表方式, [code] [HKEY_LOCAL_MACHINE\\init\\BootVars]   \"SystemHive\"=\"Docume ...…

查看全部问答>

SJF2440不能烧写Nor Flash.

我的SJF2440不能烧写MX 29LV160这个NOR Flash,读不到ID,我检察了发送命令的顺序没有错误.请大家指教.…

查看全部问答>

程序获取wince系统密码

我通过BOOL NTLMSetUserInfo( LPTSTR pszUser, LPTSTR pszPassword )这个函数给系统添加了用户名和密码,请问如何通过过程序来获取这个密码呢?我看了看Ntlmssp.h 这个头文件,好像没有类似NTLMGetUserInfo函数用来获取用户信息的。 …

查看全部问答>

电容的计量单位

电容单位总是忘: 现发一贴子希望记住   这是我找来的: 电容单位换算 电容器Q容量Kvar换算C容值uF公式I=0.314×C×UC=Q / 0.314×U×U Q容量=单位KvarC容值=单位uF1F=1000000μFI为补偿电流,单位为A,式中0.314=2πf/100 ...…

查看全部问答>

STM8用什么调试?有JTAG么?

                                 手册里面说的单线调试接口是用来调试的么?…

查看全部问答>

浅析DIM3517板子的CVBS

为了解决DIM3517的显示问题(因为板子没有代LCD),坛主建议我买一块LCD,最后她可以买回,坛主一片盛情,买一个LCD虽然不贵,但是只用一次的话显得太浪费,不符合一个开发者的做法,寻找廉价方案,另外一个方案:HDMI转AV,因为我的电视机有AV接口 ...…

查看全部问答>

stm32 中断问题

我买的stm32f103zet6最小系统板,在设置中断的时候,发现不论我把外部中断设置在哪个端口,都会在端口A上面反映,比如说我设置PB.2为外部中断, 但写程序的时候,PB.2不会响应中断,而PA.2则会,就算我把A的时钟关了,它也会相应中断。 就相当于 ...…

查看全部问答>

[open1081]摄像头终于工作了

反复折腾,摄像头终于可以工作了。发现1.12版的可以,1.19版的不行。主要区别也就在main.c文件上,用1.12版的main.c文件替换1.19版的也可以工作。对比文件后,发现主要问题在于OV2640_JPEG_Dis()函数,将它从93行的if前移到if语句中就可以了。 ...…

查看全部问答>

win732位安装ccs3.3完成后打开没有烧写插件?哪位大神能帮我解决一下 非常感谢

win732位安装ccs3.3完成后打开没有烧写插件?哪位大神能帮我解决一下  非常感谢…

查看全部问答>