STC8 6 位数字密码锁程序功能

STC8 6位数字密码锁程序功能完整描述 ## 一、硬件资源分配 1. **数码管**:P0口作为共阳极数码管段选,单数码管显示最后输入的密码数字,0xFF熄灭。 2. **4×4矩阵键盘**:P1口,行列扫描方式;按键映射:数字0~9、`*`清空键、`#`确认校验键。 3. **指示灯** - P3.1 绿色LED:低电平点亮,密码校验正确开锁时亮; - P3.2 红色LED:低电平点亮,清空、输入位数不足、密码错误、锁定状态报警亮; 4. **蜂鸣器**:P3.6,有源蜂鸣器,不同场景区分长短提示音、报警音。 5. 系统晶振:11.0592MHz。 ## 二、全局参数配置 1. 固定密码长度6位,正确密码固定为 `1,2,3,4,5,6`; 2. 存储缓存:`inputBuf`存放用户输入密码,`inputLen`记录当前输入位数; 3. 保护机制:`errorCnt`记录连续输错次数,连续3次触发锁定标志`systemLock`。 ## 三、底层工具函数功能 1. **延时函数** - `delay_ms`:毫秒级软件延时,用于灯光、蜂鸣时长控制; - `delay_10us`:微秒级短延时,键盘消抖。 2. **蜂鸣器音效函数** - `Beep_Short`:短滴一声,任意按键按下的反馈提示; - `Beep_Success`:多声短促蜂鸣,密码正确解锁提示; - `Beep_Long`:高频交替长鸣,错误、锁定状态持续报警。 3. **键盘扫描函数`key_matrix_ranks_scan`** 逐列拉低扫描4×4矩阵键盘,消抖后返回按键编号:数字0~9、10代表`*`、11代表`#`,无按键/无效按键返回0。 4. **辅助功能函数** - `ClearInput`:清空输入缓存、输入计数,熄灭数码管; - `CheckPassword`:逐位对比输入密码与标准密码,匹配返回1,不匹配返回0; - `IO_Init`:初始化所有IO为准双向口,关闭LED与蜂鸣器,清空数码管。 ## 四、核心业务逻辑(两大运行状态) ### 状态1:系统锁定状态(连续输错3次密码触发) 1. 强制屏蔽全部键盘输入,任何按键无响应; 2. 红灯持续常亮、数码管熄灭; 3. 蜂鸣器持续高频长鸣报警,锁定时长10秒; 4. 锁定倒计时结束后自动解锁:关闭红灯、停止蜂鸣、清空错误计数、清空输入缓存,回到正常操作状态。 ### 状态2:正常操作状态(未锁定) 1. **按键通用反馈**:按下任意有效按键,蜂鸣短滴一声,提示按键识别成功; 2. **数字键(0~9)功能** - 输入未满6位时:数字存入缓存,数码管实时显示当前按下数字; - 已满6位:不再接收数字输入,防止密码数组溢出; 3. **`*`清空键** 一键清空所有已输入密码,红灯短暂点亮0.3秒后熄灭,数码管熄灭; 4. **`#`确认校验键** - 分支1:当前输入不足6位 红灯点亮+蜂鸣长鸣0.5秒报错,自动清空输入,等待重新输入; - 分支2:输入刚好6位,密码匹配正确 绿灯持续点亮3秒,蜂鸣连续3声解锁成功提示;清空错误次数,自动清空输入; - 分支3:输入刚好6位,密码匹配错误 错误计数+1;红灯点亮、蜂鸣长鸣0.8秒报警; 若连续错误达到3次,立即置位锁定标志,下次循环进入10秒锁定保护; 执行完成后自动清空输入缓存。 ## 五、整体程序特点 1. 防暴力破解:连续输错3次密码强制锁定10秒,期间禁止一切输入; 2. 人机交互完善:按键提示音、成功/错误/锁定差异化声光提醒; 3. 输入保护:限制最大6位输入,防止数组越界; 4. 消抖稳定:键盘扫描内置微秒级消抖延时,避免误触发; 5. 硬件兼容:STC8单片机标准准双向IO配置,适配共阳数码管、低电平点亮LED。

cpp 复制代码
#include "STC8.H"
#include <intrins.h>
#include <string.h>

#define MAIN_Fosc		11059200L
#define  uint16   unsigned int  
#define  uint8    unsigned char 
typedef unsigned int u16;	
typedef unsigned char u8;

// 硬件端口定义
#define SMG_A_DP_PORT	P0
#define KEY_MATRIX_PORT	P1	

// LED指示灯 & 蜂鸣器定义
sbit LED_GREEN = P3^1;
sbit LED_RED   = P3^2;
sbit BEEP      = P3^6;	

// 密码配置
#define PWD_MAX_LEN 6
u8 code correctPwd[PWD_MAX_LEN] = {1,2,3,4,5,6};
u8 inputBuf[PWD_MAX_LEN];
u8 inputLen = 0;    // 当前输入位数
u8 errorCnt = 0;    // 错误次数
bit systemLock = 0; // 锁定标志

// 共阳极数码管段码 0~F
u8 gsmg_code[17]={
	0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
	0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E
};

// 毫秒延时
void delay_ms(uint16 x) 
{  
	uint16 j,i;   
	for(j=0;j<x;j++)   
	{    
		for(i=0;i<1100;i++);   
	}  
}

// 10us延时
void delay_10us(u16 ten_us)
{
	while(ten_us--);	
}

// 短滴一声按键提示音
void Beep_Short(void)
{
	BEEP = 1;
	delay_ms(80);
	BEEP = 0;
	delay_ms(50);
}

// N声连续蜂鸣(解锁提示用)
void Beep_Success(u8 cnt)
{
	u8 i;
	for(i=0;i<cnt;i++)
	{
		BEEP = 1;
		delay_ms(150);
		BEEP = 0;
		delay_ms(100);
	}
}

// 持续长蜂鸣报警
void Beep_Long(u16 ms)
{
	u16 t;
	for(t=0;t<ms;t++)
	{
		BEEP = !BEEP;
		delay_ms(2);
	}
	BEEP = 0;
}

// 4*4矩阵键盘扫描:返回 0~9数字 10=* 11=# 0=无按键
u8 key_matrix_ranks_scan(void)
{
	u8 key_value=0;

	// 第一列 P1.4=0xf7
	KEY_MATRIX_PORT=0xf7;
	if(KEY_MATRIX_PORT!=0xf7)
	{
		delay_10us(1000);
		switch(KEY_MATRIX_PORT)
		{
			case 0x77: key_value=1;break;
			case 0xb7: key_value=5;break;
			case 0xd7: key_value=9;break;
			case 0xe7: key_value=10;break; // *
		}
	}
	while(KEY_MATRIX_PORT!=0xf7);
	
	// 第二列 P1.5=0xfb
	KEY_MATRIX_PORT=0xfb;
	if(KEY_MATRIX_PORT!=0xfb)
	{
		delay_10us(1000);
		switch(KEY_MATRIX_PORT)
		{
			case 0x7b: key_value=2;break;
			case 0xbb: key_value=6;break;
			case 0xdb: key_value=0;break; // 0
			case 0xeb: key_value=11;break; // #
		}
	}
	while(KEY_MATRIX_PORT!=0xfb);
	
	// 第三列 P1.6=0xfd
	KEY_MATRIX_PORT=0xfd;
	if(KEY_MATRIX_PORT!=0xfd)
	{
		delay_10us(1000);
		switch(KEY_MATRIX_PORT)
		{
			case 0x7d: key_value=3;break;
			case 0xbd: key_value=7;break;
			case 0xdd: key_value=12;break; // 无定义
			case 0xed: key_value=13;break;
		}
	}
	while(KEY_MATRIX_PORT!=0xfd);
	
	// 第四列 P1.7=0xfe
	KEY_MATRIX_PORT=0xfe;
	if(KEY_MATRIX_PORT!=0xfe)
	{
		delay_10us(1000);
		switch(KEY_MATRIX_PORT)
		{
			case 0x7e: key_value=4;break;
			case 0xbe: key_value=8;break;
			case 0xde: key_value=14;break;
			case 0xee: key_value=15;break;
		}
	}
	while(KEY_MATRIX_PORT!=0xfe);
	
	// 无效按键返回0
	if(key_value >=12) key_value = 0;
	return key_value;		
}

// 清空输入缓冲区
void ClearInput(void)
{
    inputLen = 0;
    memset(inputBuf, 0x00, sizeof(inputBuf));
	SMG_A_DP_PORT = 0xFF; // 熄灭数码管
}

// 密码校验
bit CheckPassword(void)
{
    u8 i;
    for(i = 0; i < PWD_MAX_LEN; i++)
    {
        if(inputBuf[i] != correctPwd[i])
            return 0;
    }
    return 1;
}

// IO初始化
void IO_Init(void)
{
    // P0准双向 数码管段选
    P0M1 = 0x00;	P0M0 = 0x00;
    // P1准双向 矩阵键盘
    P1M1 = 0x00;	P1M0 = 0x00;
    // P3全部准双向输出
    P3M0 = 0x00;
    P3M1 = 0x00;
    
    LED_GREEN = 1; // 低电平点亮,初始熄灭
    LED_RED   = 1;
    BEEP = 0;      // 蜂鸣器关闭
    
    ClearInput();
}

int main(void)
{
	u8 key_val=0;
	IO_Init();
	
	while(1)
	{
		// ==========锁定模式:屏蔽所有输入,红灯+长蜂鸣10秒==========
		if(systemLock)
		{
			LED_RED = 0;
			SMG_A_DP_PORT = 0xFF;
			Beep_Long(10000);  // 锁定全程持续蜂鸣报警
			
			LED_RED = 1;
			BEEP = 0;
			systemLock = 0;
			errorCnt = 0;
			ClearInput();
			continue;
		}

		key_val = key_matrix_ranks_scan();
		if(key_val == 0) // 无按键按下
		{
			delay_ms(10);
			continue;
		}
		Beep_Short(); // 任意按键按下短滴反馈

		if(key_val == 10) // * 清空输入
		{
			ClearInput();
			LED_RED = 0;
			delay_ms(300);
			LED_RED = 1;
		}
		else if(key_val == 11) // # 确认校验密码
		{
			// 输入不足6位报错
			if(inputLen != PWD_MAX_LEN)
			{
				LED_RED = 0;
				Beep_Long(500);
				LED_RED = 1;
				ClearInput();
				continue;
			}
			// 密码正确,解锁成功
			if(CheckPassword())
			{
				LED_GREEN = 0;
				Beep_Success(3); // 三声解锁提示
				delay_ms(3000);
				LED_GREEN = 1;
				errorCnt = 0;
			}
			// 密码错误
			else
			{
				errorCnt++;
				LED_RED = 0;
				Beep_Long(800);
				LED_RED = 1;
				// 连续3次触发锁定
				if(errorCnt >= 3)
					systemLock = 1;
			}
			ClearInput();
		}
		else // 数字键0~9录入
		{
			if(inputLen < PWD_MAX_LEN) // 未满6位才允许录入
			{
				inputBuf[inputLen++] = key_val;
				SMG_A_DP_PORT = gsmg_code[key_val]; // 数码管显示当前数字
			}
		}
		delay_ms(10);
	}
}
相关推荐
Dlrb12112 小时前
51单片机--GPIO、按键、中断、蜂鸣器、PWM
单片机·嵌入式硬件·51单片机·定时器·中断
dddwjzx16 小时前
嵌入式Linux C应用编程入门——高级I/O
linux·嵌入式
piaoyiren16 小时前
普中A6 静态数码管显示 数字
单片机·嵌入式·普中a6
Yunhoa17 小时前
51单片机(1)
单片机·嵌入式硬件·51单片机
阿拉斯攀登21 小时前
平台设备驱动:platform bus 与设备树
linux·嵌入式硬件·嵌入式·linux驱动·字符设备驱动
纯音乐sjc1 天前
51单片机入门Day1:从概念到第一个IO操作踩坑记录
单片机·嵌入式硬件·51单片机
阿拉斯攀登1 天前
SPI 设备驱动开发
linux·驱动开发·嵌入式硬件·linux内核·嵌入式·linux驱动·spi
Dlrb12111 天前
51单片机基础知识
单片机·嵌入式硬件·51单片机
阿拉斯攀登1 天前
定时器与延时:内核定时器、hrtimer 与延时函数
linux·嵌入式硬件·linux内核·嵌入式·linux驱动