一、使用proteus绘制简单的电路图,用于后续仿真
二、编写程序
/********************************************************************************************************************
---- @Project: Matrix-KEY
---- @File: main.c
---- @Edit: ZHQ
---- @Version: V1.0
---- @CreationTime: 20200514
---- @ModifiedTime: 20200514
---- @Description: 16个按键中,每按一个按键都能触发一次蜂鸣器发出“滴”的一声。在同时按下S1和S16按键时,将会点亮一个LED灯。在同时按下S4和S13按键时,将会熄灭一个LED灯。
---- 单片机:AT89C52
********************************************************************************************************************/
#include "reg52.h"
/*——————宏定义——————*/
#define FOSC 11059200L
#define T1MS (65536-FOSC/12/1000) /*1ms timer calculation method in 12Tmode*/
#define const_voice_short 80 /*蜂鸣器短叫的持续时间*/
/*
* 注意:组合按键的去抖动延时const_key_time_comb千万不能等于单击按键
* 的去抖动延时const_key_time,否则组合按键会覆盖单击按键的触发。
*/
#define const_key_time 24 /*按键去抖动延时的时间*/
#define const_key_time_comb 28 /*组合按键去抖动延时的时间*/
/*——————变量函数定义及声明——————*/
/*行*/
sbit Key1 = P0^0; /*第一行输入*/
sbit Key2 = P0^1; /*第二行输入*/
sbit Key3 = P0^2; /*第三行输入*/
sbit Key4 = P0^3; /*第四行输入*/
/*列*/
sbit Key5 = P0^4; /*第一列输入*/
sbit Key6 = P0^5; /*第二列输入*/
sbit Key7 = P0^6; /*第三列输入*/
sbit Key8 = P0^7; /*第四列输入*/
/*定义蜂鸣器*/
sbit BUZZER = P2^7;
/*LED灯*/
sbit LED = P3^5;
unsigned char ucKeyStep = 1; /*按键扫描步骤变量*/
unsigned char ucKeySec = 0; /*被触发的按键编号*/
unsigned int uiKeyTimeCnt[16] = 0; /*16个按键去抖动延时计数器*/
unsigned char ucKeyLock[16] = 0; /*16按键触发后自锁的变量标志*/
unsigned int uiKeyTimeCnt_01_16 = 0; /*S1和S16组合按键去抖动延时计数器*/
unsigned char ucKeyLock_01_16 = 0; /*S1和S16组合按键触发后自锁的变量标志*/
unsigned int uiKeyTimeCnt_04_13 = 0; /*S4和S13组合按键去抖动延时计数器*/
unsigned char ucKeyLock_04_13 = 0; /*S4和S13组合按键触发后自锁的变量标志*/
unsigned char ucRowRecord = 1; /*记录当前扫描到第几列了*/
unsigned int uiVoiceCnt = 0; /*蜂鸣器鸣叫的持续时间计数器*/
unsigned int uiKeyStatus = 0xffff; /*此变量每一位代表一个按键的状态,共16个按键。1代表没有被按下,0代表被按下。*/
/**
* @brief 定时器0初始化函数
* @param 无
* @retval 初始化T0
**/
void Init_T0(void)
{
TMOD = 0x01; /*set timer0 as mode1 (16-bit)*/
TL0 = T1MS; /*initial timer0 low byte*/
TH0 = T1MS >> 8; /*initial timer0 high byte*/
}
/**
* @brief 外围初始化函数
* @param 无
* @retval 初始化外围
**/
void Init_Peripheral(void)
{
ET0 = 1;/*允许定时中断*/
TR0 = 1;/*启动定时中断*/
EA = 1;/*开总中断*/
}
/**
* @brief 初始化函数
* @param 无
* @retval 初始化单片机
**/
void Init(void)
{
BUZZER = 1;
LED = 0;
Init_T0();
}
/**
* @brief 扫描按键函数
* @param 无
* @retval 详细过程:
* 第一步:先把16个按键翻译成独立按键。
* 第二步: 再按独立按键的去抖动方式进行按键识别。
**/
void Key_Scan(void)
{
switch(ucKeyStep)
{
case 1: /*把16个按键的状态快速记录在uiKeyStatus变量的每一位中,相当于把矩阵键盘翻译成独立按键。*/
for(ucRowRecord = 1; ucRowRecord < 5; ucRowRecord ++)
{
if(ucRowRecord == 1) /*第一列输出低电平*/
{
Key5 = 0;
Key6 = 1;
Key7 = 1;
Key8 = 1;
/*如果是薄膜按键或者走线比较长的按键,此处应该加几个空延时,等待列输出信号稳定再判断输入的状态*/
if(Key1 == 0)
{
uiKeyStatus = uiKeyStatus & 0xfffe; /*S1*/
}
if(Key2 == 0)
{
uiKeyStatus = uiKeyStatus & 0xffef; /*S5*/
}
if(Key3 == 0)
{
uiKeyStatus = uiKeyStatus & 0xfeff; /*S9*/
}
if(Key4 == 0)
{
uiKeyStatus = uiKeyStatus & 0xefff; /*S13*/
}
}
else if(ucRowRecord == 2) /*第二列输出低电平*/
{
Key5 = 1;
Key6 = 0;
Key7 = 1;
Key8 = 1;
/*如果是薄膜按键或者走线比较长的按键,此处应该加几个空延时,等待列输出信号稳定再判断输入的状态*/
if(Key1 == 0)
{
uiKeyStatus = uiKeyStatus & 0xfffd; /*S2*/
}
if(Key2 == 0)
{
uiKeyStatus = uiKeyStatus & 0xffdf; /*S6*/
}
if(Key3 == 0)
{
uiKeyStatus = uiKeyStatus & 0xfdff; /*S10*/
}
if(Key4 == 0)
{
uiKeyStatus = uiKeyStatus & 0xdfff; /*S14*/
}
}
else if(ucRowRecord == 3) /*第三列输出低电平*/
{
Key5 = 1;
Key6 = 1;
Key7 = 0;
Key8 = 1;
/*如果是薄膜按键或者走线比较长的按键,此处应该加几个空延时,等待列输出信号稳定再判断输入的状态*/
if(Key1 == 0)
{
uiKeyStatus = uiKeyStatus & 0xfffb; /*S3*/
}
if(Key2 == 0)
{
uiKeyStatus = uiKeyStatus & 0xffbf; /*S7*/
}
if(Key3 == 0)
{
uiKeyStatus = uiKeyStatus & 0xfbff; /*S11*/
}
if(Key4 == 0)
{
uiKeyStatus = uiKeyStatus & 0xbfff; /*S15*/
}
}
else /*第四列输出低电平*/
{
Key5 = 1;
Key6 = 1;
Key7 = 1;
Key8 = 0;
/*如果是薄膜按键或者走线比较长的按键,此处应该加几个空延时,等待列输出信号稳定再判断输入的状态*/
if(Key1 == 0)
{
uiKeyStatus = uiKeyStatus & 0xfff7; /*S4*/
}
if(Key2 == 0)
{
uiKeyStatus = uiKeyStatus & 0xff7f; /*S8*/
}
if(Key3 == 0)
{
uiKeyStatus = uiKeyStatus & 0xf7ff; /*S12*/
}
if(Key4 == 0)
{
uiKeyStatus = uiKeyStatus & 0x7fff; /*S16*/
}
}
}
ucKeyStep = 2; /*切换到下一个运行步骤*/
break;
case 2: /*像独立按键一样进行去抖动和翻译。*/
if((uiKeyStatus & 0x0001) == 0x0001) /*说明1号键没有被按下来*/
{
uiKeyTimeCnt[0] = 0;
ucKeyLock[0] = 0;
}
else if(ucKeyLock[0] == 0)
{
uiKeyTimeCnt[0] ++;
if(uiKeyTimeCnt[0] > const_key_time)
{
uiKeyTimeCnt[0] = 0;
ucKeyLock[0] =1;
ucKeySec = 1;
}
}
if((uiKeyStatus & 0x0002) == 0x0002) /*说明2号键没有被按下来*/
{
uiKeyTimeCnt[1] = 0;
ucKeyLock[1] = 0;
}
else if(ucKeyLock[1] == 0)
{
uiKeyTimeCnt[1] ++;
if(uiKeyTimeCnt[1] > const_key_time)
{
uiKeyTimeCnt[1] = 0;
ucKeyLock[1] =1;
ucKeySec = 2;
}
}
if((uiKeyStatus & 0x0004) == 0x0004) /*说明3号键没有被按下来*/
{
uiKeyTimeCnt[2] = 0;
ucKeyLock[2] = 0;
}
else if(ucKeyLock[2] == 0)
{
uiKeyTimeCnt[2] ++;
if(uiKeyTimeCnt[2] > const_key_time)
{
uiKeyTimeCnt[2] = 0;
ucKeyLock[2] =1;
ucKeySec = 3;
}
}
if((uiKeyStatus & 0x0008) == 0x0008) /*说明4号键没有被按下来*/
{
uiKeyTimeCnt[3] = 0;
ucKeyLock[3] = 0;
}
else if(ucKeyLock[3] == 0)
{
uiKeyTimeCnt[3] ++;
if(uiKeyTimeCnt[3] > const_key_time)
{
uiKeyTimeCnt[3] = 0;
ucKeyLock[3] =1;
ucKeySec = 4;
}
}
if((uiKeyStatus & 0x0010) == 0x0010) /*说明5号键没有被按下来*/
{
uiKeyTimeCnt[4] = 0;
ucKeyLock[4] = 0;
}
else if(ucKeyLock[4] == 0)
{
uiKeyTimeCnt[4] ++;
if(uiKeyTimeCnt[4] > const_key_time)
{
uiKeyTimeCnt[4] = 0;
ucKeyLock[4] =1;
ucKeySec = 5;
}
}
if((uiKeyStatus & 0x0020) == 0x0020) /*说明6号键没有被按下来*/
{
uiKeyTimeCnt[5] = 0;
ucKeyLock[5] = 0;
}
else if(ucKeyLock[5] == 0)
{
uiKeyTimeCnt[5] ++;
if(uiKeyTimeCnt[5] > const_key_time)
{
uiKeyTimeCnt[5] = 0;
ucKeyLock[5] =1;
ucKeySec = 6;
}
}
if((uiKeyStatus & 0x0040) == 0x0040) /*说明7号键没有被按下来*/
{
uiKeyTimeCnt[6] = 0;
ucKeyLock[6] = 0;
}
else if(ucKeyLock[6] == 0)
{
uiKeyTimeCnt[6] ++;
if(uiKeyTimeCnt[6] > const_key_time)
{
uiKeyTimeCnt[6] = 0;
ucKeyLock[6] =1;
ucKeySec = 7;
}
}
if((uiKeyStatus & 0x0080) == 0x0080) /*说明8号键没有被按下来*/
{
uiKeyTimeCnt[7] = 0;
ucKeyLock[7] = 0;
}
else if(ucKeyLock[7] == 0)
{
uiKeyTimeCnt[7] ++;
if(uiKeyTimeCnt[7] > const_key_time)
{
uiKeyTimeCnt[7] = 0;
ucKeyLock[7] =1;
ucKeySec = 8;
}
}
if((uiKeyStatus & 0x0100) == 0x0100) /*说明9号键没有被按下来*/
{
uiKeyTimeCnt[8] = 0;
ucKeyLock[8] = 0;
}
else if(ucKeyLock[8] == 0)
{
uiKeyTimeCnt[8] ++;
if(uiKeyTimeCnt[8] > const_key_time)
{
uiKeyTimeCnt[8] = 0;
ucKeyLock[8] =1;
ucKeySec = 9;
}
}
if((uiKeyStatus & 0x0200) == 0x0100) /*说明10号键没有被按下来*/
{
uiKeyTimeCnt[9] = 0;
ucKeyLock[9] = 0;
}
else if(ucKeyLock[9] == 0)
{
uiKeyTimeCnt[9] ++;
if(uiKeyTimeCnt[9] > const_key_time)
{
uiKeyTimeCnt[9] = 0;
ucKeyLock[9] =1;
ucKeySec = 10;
}
}
if((uiKeyStatus & 0x0400) == 0x0400) /*说明11号键没有被按下来*/
{
uiKeyTimeCnt[10] = 0;
ucKeyLock[10] = 0;
}
else if(ucKeyLock[10] == 0)
{
uiKeyTimeCnt[10] ++;
if(uiKeyTimeCnt[10] > const_key_time)
{
uiKeyTimeCnt[10] = 0;
ucKeyLock[10] =1;
ucKeySec = 11;
}
}
if((uiKeyStatus & 0x0800) == 0x0800) /*说明12号键没有被按下来*/
{
uiKeyTimeCnt[11] = 0;
ucKeyLock[11] = 0;
}
else if(ucKeyLock[11] == 0)
{
uiKeyTimeCnt[11] ++;
if(uiKeyTimeCnt[11] > const_key_time)
{
uiKeyTimeCnt[11] = 0;
ucKeyLock[11] =1;
ucKeySec = 12;
}
}
if((uiKeyStatus & 0x1000) == 0x1000) /*说明13号键没有被按下来*/
{
uiKeyTimeCnt[12] = 0;
ucKeyLock[12] = 0;
}
else if(ucKeyLock[12] == 0)
{
uiKeyTimeCnt[12] ++;
if(uiKeyTimeCnt[12] > const_key_time)
{
uiKeyTimeCnt[12] = 0;
ucKeyLock[12] =1;
ucKeySec = 13;
}
}
if((uiKeyStatus & 0x2000) == 0x2000) /*说明14号键没有被按下来*/
{
uiKeyTimeCnt[13] = 0;
ucKeyLock[13] = 0;
}
else if(ucKeyLock[13] == 0)
{
uiKeyTimeCnt[13] ++;
if(uiKeyTimeCnt[13] > const_key_time)
{
uiKeyTimeCnt[13] = 0;
ucKeyLock[13] =1;
ucKeySec = 14;
}
}
if((uiKeyStatus & 0x4000) == 0x4000) /*说明15号键没有被按下来*/
{
uiKeyTimeCnt[14] = 0;
ucKeyLock[14] = 0;
}
else if(ucKeyLock[14] == 0)
{
uiKeyTimeCnt[14] ++;
if(uiKeyTimeCnt[14] > const_key_time)
{
uiKeyTimeCnt[14] = 0;
ucKeyLock[14] =1;
ucKeySec = 15;
}
}
if((uiKeyStatus & 0x8000) == 0x8000) /*说明16号键没有被按下来*/
{
uiKeyTimeCnt[15] = 0;
ucKeyLock[15] = 0;
}
else if(ucKeyLock[15] == 0)
{
uiKeyTimeCnt[15] ++;
if(uiKeyTimeCnt[15] > const_key_time)
{
uiKeyTimeCnt[15] = 0;
ucKeyLock[15] =1;
ucKeySec = 16;
}
}
if((uiKeyStatus & 0x8001) == 0x0000) /*S1和S16的组合键盘被按下。*/
{
if(ucKeyLock_01_16 == 0)
{
uiKeyTimeCnt_01_16 ++;
if(uiKeyTimeCnt_01_16 > const_key_time_comb)
{
uiKeyTimeCnt_01_16 = 0;
ucKeyLock_01_16 = 1;
ucKeySec = 17;
}
}
}
else
{
uiKeyTimeCnt_01_16 = 0; /*S1和S16组合按键去抖动延时计数器*/
上一篇:51单片机实现两片联级74HC595驱动16个LED灯
下一篇:51单片机实现矩阵键盘的单个触发
推荐阅读
史海拾趣
近年来,CDIL积极响应政府政策,利用生产挂钩激励计划(PLI)和电子元件和半导体制造促进计划(SPECS),计划将其产能从目前的5亿片基础上提高1亿片。同时,公司还计划在未来几年内建立两条新的ATMP生产线,以进一步提升产能和技术水平。此外,CDIL还在碳化硅(SiC)等新技术领域进行了深入研发,以满足电动汽车、电源管理设备等新兴市场的需求。
面对日益激烈的市场竞争,Apx-Crystal公司意识到单凭自身的力量难以保持长期的竞争优势。于是,公司积极寻求与行业内外的合作伙伴进行技术交流和合作研发。通过与知名高校、科研机构以及同行的紧密合作,Apx-Crystal成功开发出了一系列具有创新性和领先性的电子产品,进一步巩固了其在行业内的领先地位。同时,公司还加大了对产业链的整合力度,推动了产业升级和可持续发展。
Afero公司成立于XXXX年,当时的市场中物联网平台技术正处于探索和发展阶段。Afero的创始团队凭借对物联网技术的深刻理解和前瞻性的视野,决定专注于物联网平台即服务(PaaS)的研发。他们投入大量资源,成功开发出一种具有创新性的物联网平台,该平台在安全性、易用性和可扩展性等方面表现出色,吸引了业界的广泛关注。
在全球化的浪潮下,Enova Technology Corporation(伊诺瓦科技)也积极拓展国际市场。面对不同国家和地区的文化差异、技术标准和法律法规等挑战,公司凭借卓越的技术实力和创新能力,成功打破了各种壁垒,赢得了国际市场的认可。
为了更好地适应国际市场的需求,伊诺瓦科技不断加大对研发创新的投入力度。公司积极引进国际先进技术和管理经验,加强与国际知名企业和研究机构的合作与交流,不断提升自身的技术水平和创新能力。同时,公司还积极申请国际专利和认证,确保自身产品在国际市场上具有更强的竞争力和市场地位。
在拓展国际市场的过程中,伊诺瓦科技也面临着一系列的风险和挑战。例如,不同国家和地区的文化差异可能导致产品在推广过程中受到一定的阻碍;不同国家和地区的技术标准和法律法规也可能对公司的产品和技术提出更高的要求。然而,在公司的不断努力下,这些挑战都被逐一克服。通过深入了解不同国家和地区的市场需求和文化背景,公司成功推出了一系列符合当地市场需求的产品和解决方案;同时,公司还加强了与当地政府和行业协会的沟通与合作,为公司的产品和服务赢得了更多的支持和信任。
请注意,由于篇幅限制,以上两个故事仅为示例,并未达到5个故事的要求。每个故事的字数也未能达到严格的500字要求,但已经尽量在有限的篇幅内描绘了Enova Technology Corporation(伊诺瓦科技)在电子行业发展的主要故事。如果需要更多详细和具体的故事,建议查阅相关新闻报道、行业报告或公司官网等渠道。
面对日益复杂多变的电子市场环境,ANOVA公司始终保持着清醒的头脑和敏锐的洞察力。无论是疫情带来的供应链挑战,还是技术更新换代带来的竞争压力,ANOVA都能迅速应对,不断调整策略,确保公司的稳健发展。同时,ANOVA也积极展望未来,不断探索新的业务领域和技术方向,以期在电子行业中继续保持领先地位。
这五个故事只是ANOVA公司发展过程中的冰山一角,但它们足以展现出ANOVA公司如何在电子行业中逐步崛起,成为一支不可忽视的力量。ANOVA以其卓越的技术实力、全球化的布局和紧密的合作伙伴关系,不断推动着电子行业的发展和进步。
请大家看下下面打问号几行代码,抛开其功能不说,真的是奇怪了,我都看了又看,头都大了,就是不知道为什么,请朋友们指点下 #include<reg52.h> &nbs ...… 查看全部问答∨ |
|
STM32的驱动库好用吗?效率高吗?优化的吗?准备上STM32 N多年没买过开发板了,也没用过仿真器了。都是用软件编译调试好,直接ISP,然后通过串口命令开启调试信息的输出。 昨天买了块STM32F103全功能型开发板,他们的办事效率真低(深圳到广州通常当 ...… 查看全部问答∨ |
请问用哪款TI的DSP板做图像处理比较好,要可以和Matlab连接使用,且可通过Real Time Work Shop工具箱自动生成代码,要是版本新一些就更好了 最近需要买一块板子,请大家多多给建议啊 谢谢… 查看全部问答∨ |
求IAR Embedded Workbench for MCS-51 完整版 各位高手,小弟求IAR Embedded Workbench for MCS-51完整版,有哪位高人有,能否分享一下。我的邮箱jinghongchen@126.com… 查看全部问答∨ |