一、硬件连接设计
1.1 引脚分配表
| 模块 | 引脚 | 说明 |
|---|---|---|
| 矩阵键盘 | P1.0-P1.7 | 4×4矩阵键盘 |
| 继电器控制 | P2.0 | 电磁锁驱动 |
| 蜂鸣器 | P2.1 | 报警提示 |
| LED指示灯 | P2.2-P2.4 | 状态指示 |
| LCD1602 | P0.0-P0.7 | 数据线 |
| LCD RS | P2.5 | 寄存器选择 |
| LCD RW | P2.6 | 读写控制 |
| LCD EN | P2.7 | 使能信号 |
| EEPROM | P3.4/P3.5 | I2C接口 |
| 备用电源 | P3.0 | 电源检测 |
1.2 系统框图
┌─────────────────────────────────────┐
│ CMS8S5880 │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ 矩阵键盘 │ │ 继电器驱动 │ │
│ │ 4×4输入 │ │ 电磁锁控制 │ │
│ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ LCD1602显示 │ │ 蜂鸣器报警 │ │
│ │ 状态提示 │ │ 错误提示 │ │
│ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ EEPROM存储 │ │ LED状态灯 │ │
│ │ 密码保存 │ │ 工作指示 │ │
│ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────┘
二、完整程序代码
2.1 主程序 (main.c)
c
/***********************************************************
* 文件名:ElectronicLock.c
* 功能:CMS8S5880电子锁主程序
* 硬件:CMS8S5880 + 4×4矩阵键盘 + LCD1602 + 继电器
***********************************************************/
#include "main.h"
#include "keyboard.h"
#include "lcd1602.h"
#include "eeprom.h"
#include "relay.h"
#include "beep.h"
#include "led.h"
/* 系统参数 */
#define PASSWORD_LENGTH 6 // 密码长度
#define MAX_TRY_TIMES 3 // 最大尝试次数
#define LOCK_TIME 30000 // 锁定时间30秒
#define ADMIN_PASSWORD_ADDR 0x00 // 管理员密码存储地址
#define USER_PASSWORD_ADDR 0x10 // 用户密码存储地址
/* 全局变量 */
volatile uint8_t system_state = STATE_NORMAL;
volatile uint8_t input_index = 0;
volatile uint8_t try_times = 0;
volatile uint32_t lock_timer = 0;
uint8_t input_password[PASSWORD_LENGTH];
uint8_t stored_password[PASSWORD_LENGTH];
/* 函数声明 */
void System_Init(void);
void State_Machine(void);
void Input_Password(void);
void Verify_Password(void);
void Unlock_Success(void);
void Lock_System(void);
void Change_Password(void);
void Display_State(void);
/***********************************************************
* 主函数
***********************************************************/
void main(void)
{
/* 系统初始化 */
System_Init();
/* 显示欢迎界面 */
LCD_ShowString(0, 0, "Electronic Lock");
LCD_ShowString(0, 1, "Initializing...");
Delay_ms(2000);
/* 读取存储的密码 */
EEPROM_Read(USER_PASSWORD_ADDR, stored_password, PASSWORD_LENGTH);
/* 主循环 */
while(1)
{
/* 状态机处理 */
State_Machine();
/* 键盘扫描 */
Keyboard_Scan();
/* 显示更新 */
Display_State();
/* 延时 */
Delay_ms(10);
}
}
/***********************************************************
* 系统初始化
***********************************************************/
void System_Init(void)
{
/* IO口初始化 */
P0M0 = 0x00; P0M1 = 0x00; // P0准双向
P1M0 = 0x00; P1M1 = 0x00; // P1准双向
P2M0 = 0x00; P2M1 = 0x00; // P2准双向
P3M0 = 0x00; P3M1 = 0x00; // P3准双向
/* 外设初始化 */
LCD_Init();
Keyboard_Init();
Relay_Init();
Beep_Init();
LED_Init();
EEPROM_Init();
/* 定时器初始化 */
Timer0_Init();
/* 开中断 */
EA = 1;
}
/***********************************************************
* 状态机处理
***********************************************************/
void State_Machine(void)
{
static uint8_t last_state = 0xFF;
switch(system_state)
{
case STATE_NORMAL:
/* 正常工作状态 */
if(last_state != STATE_NORMAL)
{
LED_Set(LED_GREEN, LED_ON);
LED_Set(LED_RED, LED_OFF);
LCD_Clear();
LCD_ShowString(0, 0, "Enter Password:");
LCD_ShowString(0, 1, "Press # to confirm");
input_index = 0;
memset(input_password, 0, PASSWORD_LENGTH);
}
break;
case STATE_INPUT:
/* 密码输入状态 */
Input_Password();
break;
case STATE_VERIFY:
/* 密码验证状态 */
Verify_Password();
break;
case STATE_UNLOCK:
/* 解锁状态 */
Unlock_Success();
break;
case STATE_LOCKED:
/* 系统锁定状态 */
Lock_System();
break;
case STATE_CHANGE_PWD:
/* 修改密码状态 */
Change_Password();
break;
default:
system_state = STATE_NORMAL;
break;
}
last_state = system_state;
}
/***********************************************************
* 密码输入处理
***********************************************************/
void Input_Password(void)
{
uint8_t key_value;
key_value = Get_Key_Value();
if(key_value != NO_KEY)
{
Beep_Short(); // 按键提示音
if(key_value >= '0' && key_value <= '9')
{
/* 数字键 */
if(input_index < PASSWORD_LENGTH)
{
input_password[input_index] = key_value - '0';
LCD_ShowChar(12 + input_index, 0, '*');
input_index++;
}
}
else if(key_value == '#')
{
/* 确认键 */
if(input_index == PASSWORD_LENGTH)
{
system_state = STATE_VERIFY;
}
else
{
/* 密码长度不足 */
LCD_ShowString(0, 1, "Incomplete Password!");
Beep_Error();
Delay_ms(1000);
system_state = STATE_NORMAL;
}
}
else if(key_value == '*')
{
/* 删除键 */
if(input_index > 0)
{
input_index--;
input_password[input_index] = 0;
LCD_ShowChar(12 + input_index, 0, ' ');
}
}
else if(key_value == 'A')
{
/* 管理员功能 */
system_state = STATE_CHANGE_PWD;
}
}
}
/***********************************************************
* 密码验证
***********************************************************/
void Verify_Password(void)
{
uint8_t i;
uint8_t match = 1;
/* 比较密码 */
for(i = 0; i < PASSWORD_LENGTH; i++)
{
if(input_password[i] != stored_password[i])
{
match = 0;
break;
}
}
if(match)
{
/* 密码正确 */
try_times = 0;
system_state = STATE_UNLOCK;
}
else
{
/* 密码错误 */
try_times++;
Beep_Error();
LED_Set(LED_RED, LED_ON);
if(try_times >= MAX_TRY_TIMES)
{
/* 超过最大尝试次数,锁定系统 */
system_state = STATE_LOCKED;
lock_timer = LOCK_TIME;
}
else
{
/* 显示错误信息 */
LCD_Clear();
LCD_ShowString(0, 0, "Wrong Password!");
LCD_ShowString(0, 1, "Try again:");
LCD_ShowNumber(10, 1, MAX_TRY_TIMES - try_times, 1);
LCD_ShowString(12, 1, "left");
/* 清空输入 */
input_index = 0;
memset(input_password, 0, PASSWORD_LENGTH);
system_state = STATE_NORMAL;
}
}
}
/***********************************************************
* 解锁成功
***********************************************************/
void Unlock_Success(void)
{
static uint16_t unlock_time = 0;
LCD_Clear();
LCD_ShowString(0, 0, "Access Granted!");
LCD_ShowString(0, 1, "Door Unlocked");
/* 点亮绿灯,打开继电器 */
LED_Set(LED_GREEN, LED_ON);
LED_Set(LED_RED, LED_OFF);
Relay_Open();
Beep_Success();
/* 延时5秒后重新锁定 */
unlock_time++;
if(unlock_time >= 500) // 5秒
{
Relay_Close();
unlock_time = 0;
system_state = STATE_NORMAL;
}
}
/***********************************************************
* 系统锁定
***********************************************************/
void Lock_System(void)
{
static uint16_t lock_display_time = 0;
LCD_Clear();
LCD_ShowString(0, 0, "SYSTEM LOCKED!");
LCD_ShowString(0, 1, "Wait:");
LCD_ShowNumber(6, 1, lock_timer/1000, 2);
LCD_ShowString(10, 1, "seconds");
/* 红色LED闪烁,蜂鸣器报警 */
if(lock_display_time % 100 == 0)
{
LED_Set(LED_RED, LED_ON);
Beep_Long();
}
else if(lock_display_time % 100 == 50)
{
LED_Set(LED_RED, LED_OFF);
}
/* 倒计时 */
if(lock_timer > 0)
{
lock_timer--;
}
else
{
/* 锁定时间到,恢复正常状态 */
try_times = 0;
system_state = STATE_NORMAL;
}
lock_display_time++;
}
/***********************************************************
* 修改密码
***********************************************************/
void Change_Password(void)
{
static uint8_t step = 0;
static uint8_t old_password[PASSWORD_LENGTH];
static uint8_t new_password[PASSWORD_LENGTH];
static uint8_t confirm_password[PASSWORD_LENGTH];
uint8_t key_value;
key_value = Get_Key_Value();
switch(step)
{
case 0: // 输入旧密码
LCD_Clear();
LCD_ShowString(0, 0, "Enter Old Pwd:");
step = 1;
input_index = 0;
break;
case 1: // 等待输入旧密码
if(key_value != NO_KEY)
{
if(key_value >= '0' && key_value <= '9')
{
if(input_index < PASSWORD_LENGTH)
{
old_password[input_index] = key_value - '0';
LCD_ShowChar(12 + input_index, 0, '*');
input_index++;
}
}
else if(key_value == '#')
{
if(input_index == PASSWORD_LENGTH)
{
/* 验证旧密码 */
uint8_t i, match = 1;
for(i = 0; i < PASSWORD_LENGTH; i++)
{
if(old_password[i] != stored_password[i])
{
match = 0;
break;
}
}
if(match)
{
step = 2;
input_index = 0;
}
else
{
LCD_ShowString(0, 1, "Wrong Old Pwd!");
Beep_Error();
Delay_ms(1000);
step = 0;
}
}
}
}
break;
case 2: // 输入新密码
LCD_Clear();
LCD_ShowString(0, 0, "Enter New Pwd:");
step = 3;
input_index = 0;
break;
case 3: // 等待输入新密码
if(key_value != NO_KEY)
{
if(key_value >= '0' && key_value <= '9')
{
if(input_index < PASSWORD_LENGTH)
{
new_password[input_index] = key_value - '0';
LCD_ShowChar(12 + input_index, 0, '*');
input_index++;
}
}
else if(key_value == '#')
{
if(input_index == PASSWORD_LENGTH)
{
step = 4;
input_index = 0;
}
}
}
break;
case 4: // 确认新密码
LCD_Clear();
LCD_ShowString(0, 0, "Confirm New Pwd:");
step = 5;
input_index = 0;
break;
case 5: // 等待确认密码
if(key_value != NO_KEY)
{
if(key_value >= '0' && key_value <= '9')
{
if(input_index < PASSWORD_LENGTH)
{
confirm_password[input_index] = key_value - '0';
LCD_ShowChar(12 + input_index, 0, '*');
input_index++;
}
}
else if(key_value == '#')
{
if(input_index == PASSWORD_LENGTH)
{
/* 比较两次密码 */
uint8_t i, match = 1;
for(i = 0; i < PASSWORD_LENGTH; i++)
{
if(new_password[i] != confirm_password[i])
{
match = 0;
break;
}
}
if(match)
{
/* 保存新密码到EEPROM */
EEPROM_Write(USER_PASSWORD_ADDR, new_password, PASSWORD_LENGTH);
memcpy(stored_password, new_password, PASSWORD_LENGTH);
LCD_ShowString(0, 1, "Password Changed!");
Beep_Success();
Delay_ms(2000);
system_state = STATE_NORMAL;
}
else
{
LCD_ShowString(0, 1, "Password Mismatch!");
Beep_Error();
Delay_ms(1000);
step = 2; // 重新输入新密码
}
}
}
}
break;
}
}
/***********************************************************
* 显示系统状态
***********************************************************/
void Display_State(void)
{
static uint8_t display_counter = 0;
if(display_counter % 100 == 0)
{
switch(system_state)
{
case STATE_NORMAL:
LED_Set(LED_GREEN, LED_ON);
LED_Set(LED_RED, LED_OFF);
break;
case STATE_INPUT:
LED_Set(LED_GREEN, LED_BLINK);
LED_Set(LED_RED, LED_OFF);
break;
case STATE_VERIFY:
LED_Set(LED_GREEN, LED_ON);
LED_Set(LED_RED, LED_ON);
break;
case STATE_UNLOCK:
LED_Set(LED_GREEN, LED_ON);
LED_Set(LED_RED, LED_OFF);
break;
case STATE_LOCKED:
LED_Set(LED_GREEN, LED_OFF);
LED_Set(LED_RED, LED_BLINK);
break;
case STATE_CHANGE_PWD:
LED_Set(LED_GREEN, LED_ON);
LED_Set(LED_RED, LED_ON);
break;
}
}
display_counter++;
}
/***********************************************************
* 定时器0中断服务程序
***********************************************************/
void Timer0_ISR(void) interrupt 1
{
static uint16_t beep_counter = 0;
static uint16_t led_counter = 0;
/* 蜂鸣器控制 */
if(beep_counter > 0)
{
beep_counter--;
BEEP = 1;
}
else
{
BEEP = 0;
}
/* LED闪烁控制 */
if(led_counter % 500 == 0)
{
LED_GREEN = ~LED_GREEN;
}
led_counter++;
}
2.2 头文件 (main.h)
c
#ifndef __MAIN_H
#define __MAIN_H
#include <reg52.h>
#include <intrins.h>
/* 系统状态定义 */
#define STATE_NORMAL 0
#define STATE_INPUT 1
#define STATE_VERIFY 2
#define STATE_UNLOCK 3
#define STATE_LOCKED 4
#define STATE_CHANGE_PWD 5
/* 按键定义 */
#define NO_KEY 0xFF
#define KEY_0 '0'
#define KEY_1 '1'
#define KEY_2 '2'
#define KEY_3 '3'
#define KEY_4 '4'
#define KEY_5 '5'
#define KEY_6 '6'
#define KEY_7 '7'
#define KEY_8 '8'
#define KEY_9 '9'
#define KEY_CONFIRM '#'
#define KEY_DELETE '*'
#define KEY_ADMIN 'A'
/* LED状态 */
#define LED_ON 0
#define LED_OFF 1
#define LED_BLINK 2
/* 硬件引脚定义 */
sbit RELAY = P2^0; // 继电器控制
sbit BEEP = P2^1; // 蜂鸣器
sbit LED_GREEN = P2^2; // 绿色LED
sbit LED_RED = P2^3; // 红色LED
sbit LED_BLUE = P2^4; // 蓝色LED
/* LCD引脚定义 */
sbit LCD_RS = P2^5;
sbit LCD_RW = P2^6;
sbit LCD_EN = P2^7;
/* EEPROM引脚定义 */
sbit EEPROM_SDA = P3^4;
sbit EEPROM_SCL = P3^5;
/* 函数声明 */
void Delay_ms(unsigned int ms);
void Delay_us(unsigned int us);
#endif
2.3 矩阵键盘驱动 (keyboard.c)
c
/***********************************************************
* 文件名:keyboard.c
* 功能:4×4矩阵键盘驱动
***********************************************************/
#include "keyboard.h"
/* 键盘映射表 */
unsigned char code KeyMap[4][4] = {
{'1', '2', '3', KEY_DELETE},
{'4', '5', '6', KEY_ADMIN},
{'7', '8', '9', KEY_CONFIRM},
{'*', '0', '#', 'B'}
};
/***********************************************************
* 键盘初始化
***********************************************************/
void Keyboard_Init(void)
{
/* P1口设置为准双向模式 */
P1M0 = 0x00;
P1M1 = 0x00;
}
/***********************************************************
* 扫描键盘
***********************************************************/
unsigned char Keyboard_Scan(void)
{
unsigned char i, j;
unsigned char key_value = NO_KEY;
/* 扫描行 */
for(i = 0; i < 4; i++)
{
P1 = ~(0x01 << i); // 设置第i行为低电平
/* 短暂延时 */
Delay_us(10);
/* 读取列状态 */
for(j = 0; j < 4; j++)
{
if((P1 & (0x10 << j)) == 0) // 第j列为低电平
{
key_value = KeyMap[i][j];
/* 等待按键释放 */
while((P1 & (0x10 << j)) == 0);
return key_value;
}
}
}
return NO_KEY;
}
/***********************************************************
* 获取键值(带消抖)
***********************************************************/
unsigned char Get_Key_Value(void)
{
static unsigned char last_key = NO_KEY;
static unsigned char debounce_count = 0;
unsigned char current_key;
current_key = Keyboard_Scan();
if(current_key == last_key)
{
if(debounce_count < 255)
debounce_count++;
}
else
{
debounce_count = 0;
last_key = current_key;
}
if(debounce_count >= 3) // 消抖3次
{
return current_key;
}
return NO_KEY;
}
2.4 LCD1602驱动 (lcd1602.c)
c
/***********************************************************
* 文件名:lcd1602.c
* 功能:LCD1602液晶显示驱动
***********************************************************/
#include "lcd1602.h"
/***********************************************************
* 延时函数
***********************************************************/
void LCD_Delay(unsigned int t)
{
unsigned int i, j;
for(i = 0; i < t; i++)
for(j = 0; j < 120; j++);
}
/***********************************************************
* 写命令
***********************************************************/
void LCD_WriteCmd(unsigned char cmd)
{
LCD_RS = 0;
LCD_RW = 0;
P0 = cmd;
LCD_EN = 1;
LCD_Delay(5);
LCD_EN = 0;
}
/***********************************************************
* 写数据
***********************************************************/
void LCD_WriteData(unsigned char dat)
{
LCD_RS = 1;
LCD_RW = 0;
P0 = dat;
LCD_EN = 1;
LCD_Delay(5);
LCD_EN = 0;
}
/***********************************************************
* 初始化LCD
***********************************************************/
void LCD_Init(void)
{
LCD_Delay(15000);
LCD_WriteCmd(0x38); // 8位数据,2行显示,5×7点阵
LCD_Delay(5000);
LCD_WriteCmd(0x38);
LCD_Delay(5000);
LCD_WriteCmd(0x38);
LCD_WriteCmd(0x0C); // 显示开,光标关
LCD_WriteCmd(0x06); // 地址递增
LCD_WriteCmd(0x01); // 清屏
LCD_Delay(2000);
}
/***********************************************************
* 清屏
***********************************************************/
void LCD_Clear(void)
{
LCD_WriteCmd(0x01);
LCD_Delay(2000);
}
/***********************************************************
* 设置显示位置
***********************************************************/
void LCD_SetCursor(unsigned char x, unsigned char y)
{
unsigned char addr;
if(y == 0)
addr = 0x80 + x;
else
addr = 0xC0 + x;
LCD_WriteCmd(addr);
}
/***********************************************************
* 显示字符
***********************************************************/
void LCD_ShowChar(unsigned char x, unsigned char y, unsigned char ch)
{
LCD_SetCursor(x, y);
LCD_WriteData(ch);
}
/***********************************************************
* 显示字符串
***********************************************************/
void LCD_ShowString(unsigned char x, unsigned char y, unsigned char *str)
{
LCD_SetCursor(x, y);
while(*str)
{
LCD_WriteData(*str);
str++;
}
}
/***********************************************************
* 显示数字
***********************************************************/
void LCD_ShowNumber(unsigned char x, unsigned char y, unsigned int num, unsigned char len)
{
unsigned char i;
unsigned char temp[5];
for(i = 0; i < len; i++)
{
temp[i] = num % 10 + '0';
num /= 10;
}
LCD_SetCursor(x, y);
for(i = len; i > 0; i--)
{
LCD_WriteData(temp[i-1]);
}
}
2.5 EEPROM驱动 (eeprom.c)
c
/***********************************************************
* 文件名:eeprom.c
* 功能:24C02 EEPROM驱动
***********************************************************/
#include "eeprom.h"
/***********************************************************
* I2C起始信号
***********************************************************/
void I2C_Start(void)
{
EEPROM_SDA = 1;
EEPROM_SCL = 1;
Delay_us(5);
EEPROM_SDA = 0;
Delay_us(5);
EEPROM_SCL = 0;
}
/***********************************************************
* I2C停止信号
***********************************************************/
void I2C_Stop(void)
{
EEPROM_SDA = 0;
EEPROM_SCL = 1;
Delay_us(5);
EEPROM_SDA = 1;
Delay_us(5);
}
/***********************************************************
* I2C应答
***********************************************************/
void I2C_Ack(void)
{
EEPROM_SDA = 0;
EEPROM_SCL = 1;
Delay_us(5);
EEPROM_SCL = 0;
}
/***********************************************************
* I2C非应答
***********************************************************/
void I2C_NoAck(void)
{
EEPROM_SDA = 1;
EEPROM_SCL = 1;
Delay_us(5);
EEPROM_SCL = 0;
}
/***********************************************************
* I2C等待应答
***********************************************************/
bit I2C_WaitAck(void)
{
bit ack;
EEPROM_SDA = 1;
EEPROM_SCL = 1;
Delay_us(5);
ack = EEPROM_SDA;
EEPROM_SCL = 0;
return ack;
}
/***********************************************************
* 写字节
***********************************************************/
void I2C_WriteByte(unsigned char dat)
{
unsigned char i;
for(i = 0; i < 8; i++)
{
EEPROM_SDA = (dat & 0x80) >> 7;
EEPROM_SCL = 1;
Delay_us(5);
EEPROM_SCL = 0;
dat <<= 1;
}
}
/***********************************************************
* 读字节
***********************************************************/
unsigned char I2C_ReadByte(void)
{
unsigned char i, dat = 0;
EEPROM_SDA = 1;
for(i = 0; i < 8; i++)
{
EEPROM_SCL = 1;
Delay_us(5);
dat <<= 1;
dat |= EEPROM_SDA;
EEPROM_SCL = 0;
Delay_us(5);
}
return dat;
}
/***********************************************************
* 写EEPROM
***********************************************************/
void EEPROM_Write(unsigned char addr, unsigned char *buf, unsigned char len)
{
unsigned char i;
I2C_Start();
I2C_WriteByte(0xA0); // 24C02写地址
I2C_WaitAck();
I2C_WriteByte(addr);
I2C_WaitAck();
for(i = 0; i < len; i++)
{
I2C_WriteByte(buf[i]);
I2C_WaitAck();
Delay_ms(5); // 等待写入完成
}
I2C_Stop();
}
/***********************************************************
* 读EEPROM
***********************************************************/
void EEPROM_Read(unsigned char addr, unsigned char *buf, unsigned char len)
{
unsigned char i;
I2C_Start();
I2C_WriteByte(0xA0); // 24C02写地址
I2C_WaitAck();
I2C_WriteByte(addr);
I2C_WaitAck();
I2C_Start();
I2C_WriteByte(0xA1); // 24C02读地址
I2C_WaitAck();
for(i = 0; i < len-1; i++)
{
buf[i] = I2C_ReadByte();
I2C_Ack();
}
buf[i] = I2C_ReadByte();
I2C_NoAck();
I2C_Stop();
}
2.6 继电器控制 (relay.c)
c
/***********************************************************
* 文件名:relay.c
* 功能:继电器控制模块
***********************************************************/
#include "relay.h"
/***********************************************************
* 继电器初始化
***********************************************************/
void Relay_Init(void)
{
RELAY = 0; // 初始关闭
}
/***********************************************************
* 打开继电器
***********************************************************/
void Relay_Open(void)
{
RELAY = 1;
}
/***********************************************************
* 关闭继电器
***********************************************************/
void Relay_Close(void)
{
RELAY = 0;
}
/***********************************************************
* 继电器状态翻转
***********************************************************/
void Relay_Toggle(void)
{
RELAY = ~RELAY;
}
2.7 蜂鸣器控制 (beep.c)
c
/***********************************************************
* 文件名:beep.c
* 功能:蜂鸣器控制模块
***********************************************************/
#include "beep.h"
/***********************************************************
* 蜂鸣器初始化
***********************************************************/
void Beep_Init(void)
{
BEEP = 0; // 关闭蜂鸣器
}
/***********************************************************
* 短响提示
***********************************************************/
void Beep_Short(void)
{
BEEP = 1;
Delay_ms(100);
BEEP = 0;
}
/***********************************************************
* 长响提示
***********************************************************/
void Beep_Long(void)
{
BEEP = 1;
Delay_ms(500);
BEEP = 0;
}
/***********************************************************
* 错误提示
***********************************************************/
void Beep_Error(void)
{
unsigned char i;
for(i = 0; i < 3; i++)
{
BEEP = 1;
Delay_ms(200);
BEEP = 0;
Delay_ms(200);
}
}
/***********************************************************
* 成功提示
***********************************************************/
void Beep_Success(void)
{
BEEP = 1;
Delay_ms(100);
BEEP = 0;
Delay_ms(100);
BEEP = 1;
Delay_ms(100);
BEEP = 0;
}
2.8 LED控制 (led.c)
c
/***********************************************************
* 文件名:led.c
* 功能:LED指示灯控制
***********************************************************/
#include "led.h"
/***********************************************************
* LED初始化
***********************************************************/
void LED_Init(void)
{
LED_GREEN = LED_OFF;
LED_RED = LED_OFF;
LED_BLUE = LED_OFF;
}
/***********************************************************
* 设置LED状态
***********************************************************/
void LED_Set(unsigned char led, unsigned char state)
{
switch(led)
{
case LED_GREEN:
if(state == LED_ON)
LED_GREEN = 0;
else if(state == LED_OFF)
LED_GREEN = 1;
break;
case LED_RED:
if(state == LED_ON)
LED_RED = 0;
else if(state == LED_OFF)
LED_RED = 1;
break;
case LED_BLUE:
if(state == LED_ON)
LED_BLUE = 0;
else if(state == LED_OFF)
LED_BLUE = 1;
break;
}
}
/***********************************************************
* LED闪烁
***********************************************************/
void LED_Blink(unsigned char led, unsigned int times)
{
unsigned int i;
for(i = 0; i < times; i++)
{
LED_Set(led, LED_ON);
Delay_ms(200);
LED_Set(led, LED_OFF);
Delay_ms(200);
}
}
三、Keil工程配置
3.1 工程设置
- Target: CMS8S5880
- Code Rom Size: Large
- Xtal: 11.0592MHz
- Memory Model: Large
- Code Optimization: Level 8 (Favor Speed)
3.2 编译选项
Project -> Options for Target 'Target 1':
- Target Tab:
- Xtal (MHz): 11.0592
- Memory Model: Large
- Code Rom Size: Large
- Output Tab:
- Create HEX File: √
- Listing Tab:
- Assembly Code: √
- C51 Tab:
- Code Optimization: Level 8 (Favor Speed)
- Define: __CMS8S5880__
参考代码 电子锁程序(CMS8S5880,51单片机程序开发) www.youwenfan.com/contentcsv/115986.html
四、使用说明
4.1 首次使用设置
- 通电后显示"Electronic Lock"
- 默认密码:123456
- 输入密码后按#键确认
4.2 管理员功能
- 输入密码123456#
- 按A键进入管理员模式
- 输入旧密码确认
- 输入新密码两次
- 按#键保存
4.3 安全特性
- 连续3次密码错误锁定30秒
- 密码存储在EEPROM中,断电不丢失
- 支持备用电源接口