一、使用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();
}
/**
* @bri