怎么用德飞莱51单片机实现如下代码

怎么用德飞莱51单片机实现如下代码

要在德飞莱51单片机上实现这个密码输入和倒计时的程序,我们需要正确地连接硬件,包括LCD1602显示器、矩阵键盘、蜂鸣器和定时器。以下是完整的代码和硬件连接说明。

硬件连接说明

LCD1602显示器:

RS -> P2.0RW -> P2.1E -> P2.2D4 -> P2.4D5 -> P2.5D6 -> P2.6D7 -> P2.7

矩阵键盘:

矩阵键盘的行和列分别连接到P1口的相应引脚(P1.0-P1.3作为行,P1.4-P1.7作为列)

蜂鸣器:

蜂鸣器连接到P2.5

独立按键:

按键1-4分别连接到P3.0 - P3.3

程序代码

main.c

#include

#include "Delay.h"

#include "LCD1602.h"

#include "matrixkey.h"

#include "Timer0.h"

#include "KEY.h"

#define len_pd 7

sbit Buzzer = P2^5; //定义蜂鸣器为P2.5

unsigned char KeyNum, Sec = 40, flag, cai = 0; //定义字节,keyNum为矩阵按键、Sec为爆炸倒计时秒数、flag为判断字符、cai为拆弹密码计数

unsigned int j, i; //定义整数j、i

int Count = 0; //定义输入密码计数

unsigned char Password[len_pd] = {'7','3','5','5','6','0','8'}; //密码

unsigned char Temp_Password[len_pd]; //中间变量

void Buzzer_Time(unsigned int ms) { //蜂鸣器配置

unsigned int i;

for (i = 0; i < ms; i++) {

Buzzer = ~Buzzer;

Delay(1);

}

}

void main() {

for(i = 0; i < len_pd; i++) {

Temp_Password[i] = '*'; //密码清零

}

LCD_Init();

Timer0Init(); //定时器初始化

TR0 = 0; //关定时器

LCD_ShowString(1, 1, "BOOM");

LCD_ShowCharlist(2, 17 - len_pd, Temp_Password, len_pd); //更新显示

while(1) {

KeyNum = MatrixKey(); //矩阵键盘使用

if(KeyNum) {

if(KeyNum == 10) //S10代表0

{

KeyNum = 0;

}

if(KeyNum <= 10) { //如果按键S1~S10按键按下,输入密码

for(i = 0; i < 100; i++) { //按键提示音

Buzzer = !Buzzer;

Delay(1);

}

if(Count < len_pd) { //如果输入次数小于7

Temp_Password[Count] = KeyNum + 48; //获取一位密码

Count++; //计次加一

}

LCD_ShowCharlist(2, 17 - len_pd, Temp_Password, len_pd); //更新显示

}

if(KeyNum == 16 && Count == 7) { //如果S16按下且输入位数等于7位,确认

flag = 1; //密码判断正确标志

for(i = 0; i < len_pd; i++) {

if(Temp_Password[i] != Password[i]) { //如果不等于正确密码

LCD_ShowString(1, 14, "ERR"); //显示ERR

flag = 0;

}

}

if(flag == 1) {

LCD_ShowString(1, 14, "OK "); //显示OK

Delay(300);

for(i = 0; i < len_pd; i++) {

Temp_Password[i] = '*'; //密码清零

}

Count = 0; //计数清零

LCD_ShowCharlist(2, 17 - len_pd, Temp_Password, len_pd); //更新显示

flag = 0; //密码判段标志清零

Timer0Init(); //定时器初始化

TR0 = 1; //开定时器

while(1) {

LCD_ShowString(1, 1, "Protect Bomb ");

LCD_ShowNum(2, 1, Sec, 2); //更新显示,进入引爆倒计时

if(KEY1 == 0 || KEY2 == 0 || KEY3 == 0 || KEY4 == 0) {

cai++;

Delay(500); //若独立按键按下,拆弹密码计数加一,每0.5秒输入一个密码

LCD_ShowCharlist(2, 17 - len_pd, Temp_Password, len_pd);

LCD_ShowCharlist(2, 17 - len_pd, Password, cai); //更新显示

if(cai == len_pd) { //若拆弹计数等于密码,拆弹成功

LCD_ShowCharlist(2, 17 - len_pd, Password, len_pd); //更新显示

LCD_Init(); //用1602初始化清屏

TR0 = 0; //关定时器

P2 = 0x00;

Buzzer_Time(300);

P2 = 0xFF;

Delay(100);

P2 = 0x00;

Buzzer_Time(300);

P2 = 0xFF;

LCD_ShowString(1, 5, "You Win");

LCD_ShowString(2, 1, "Press S14 restart"); //显示胜利,按下S14重新开始

break;

}

} else {

cai = 0; //拆弹计数清零

}

if(Sec == 0) { //引爆!!!!!!

for(i = 0; i < 100; i++) {

P2 = 0x00;

Buzzer_Time(100);

P2 = 0xFF;

}

TR0 = 0;

LCD_Init(); //1602初始化清屏

LCD_ShowString(1, 5, "You Lost");

LCD_ShowString(2, 1, "Press S14 restart"); //显示失败,按下S14重新开始

break;

}

}

} else {

LCD_ShowString(1, 14, "ERR"); //显示ERR

for(i = 0; i < len_pd; i++) {

Temp_Password[i] = '*'; //密码清零

}

Count = 0; //计次清零

LCD_ShowCharlist(2, 17 - len_pd, Temp_Password, len_pd); //更新显示

}

}

if(KeyNum == 15) { //如果S15被按下,清零

for(i = 0; i < len_pd; i++) {

Temp_Password[i] = '*'; //密码清零

}

Count = 0; //计次清零

LCD_ShowString(1, 14, " "); //清除显示

LCD_ShowCharlist(2, 17 - len_pd, Temp_Password, len_pd); //更新显示

}

if(KeyNum == 14) { //重置游戏,炸弹启动时无法重置(没有回头路)

return;

}

}

}

}

//定时器中断

void Timer0_Routine() interrupt 1 {

static unsigned int count = 0;

TH0 = 0x3C;

TL0 = 0xB0;

count++;

if(count >= 1000) { //每1秒计数一次

count = 0;

if(Sec > 0) {

Sec--;

}

}

}

LCD1602.h

#ifndef __LCD1602_H__

#define __LCD1602_H__

void LCD_Init();

void LCD_ShowChar(unsigned char Line, unsigned char Column, char Char);

void LCD_ShowNum(unsigned char Line, unsigned char Column, unsigned int Num, unsigned char Length);

void LCD_ShowString(unsigned char Line, unsigned char Column, char *String);

void LCD_ShowCharlist(unsigned char Line, unsigned char Column, char *Charlist, unsigned char Length);

#endif

LCD1602.c

#include

#include "LCD1602.h"

#include "Delay.h"

// ... LCD初始化和显示函数的实现

Timer0.h

#ifndef __TIMER0_H__

#define __TIMER0_H__

void Timer0Init();

#endif

Timer0.c

#include

#include "Timer0.h"

void Timer0Init() {

TMOD &= 0xF0; //清除定时器0的设置

TMOD |= 0x01; //设置定时器0为模式1(16位定时器)

TH0 = 0x3C; //设置定时器初始值

TL0 = 0xB0; //设置定时器初始值

ET0 = 1; //使能定时器0中断

EA = 1; //使能总中断

TR0 = 1; //启动定时器0

}

void Timer0_Routine() interrupt 1 {

static unsigned int count = 0;

TH0 = 0x3C;

TL0 = 0xB0;

count++;

if (count >= 1000) { //每1秒计数一次

count = 0;

if (Sec > 0) {

Sec--;

}

}

}

Delay.h

#ifndef __DELAY_H__

#define __DELAY_H__

void Delay(unsigned int xms);

#endif

Delay.c

#include

#include "Delay.h"

void Delay(unsigned int xms) {

unsigned char i, j;

while (xms--) {

i = 2;

j = 239;

do {

while (--j);

} while (--i);

}

}

MatrixKey.h

#ifndef __MATRIXKEY_H__

#define __MATRIXKEY_H__

unsigned char MatrixKey();

#endif

MatrixKey.c

#include

#include "MatrixKey.h"

#include "Delay.h"

unsigned char MatrixKey() {

unsigned char KeyNumber = 0;

P1 = 0xF0; //列输出,行输入

if (P1 != 0xF0) {

Delay(20); //去抖动

if (P1 != 0xF0) {

switch (P1) {

case 0xE0: KeyNumber = 1; break;

case 0xD0: KeyNumber = 2; break;

case 0xB0: KeyNumber = 3; break;

case 0x70: KeyNumber = 4; break;

}

P1 = 0x0F; //行输出,列输入

switch (P1) {

case 0x0E: KeyNumber += 0; break;

case 0x0D: KeyNumber += 4; break;

case 0x0B: KeyNumber += 8; break;

case 0x07: KeyNumber += 12; break;

}

while (P1 != 0x0F); //等待释放

}

}

return KeyNumber;

}

KEY.h

#ifndef __KEY_H__

#define __KEY_H__

sbit KEY1 = P3^0;

sbit KEY2 = P3^1;

sbit KEY3 = P3^2;

sbit KEY4 = P3^3;

#endif

连接硬件

LCD1602:

RS -> P2.0RW -> P2.1E -> P2.2D4 -> P2.4D5 -> P2.5D6 -> P2.6D7 -> P2.7

矩阵键盘:

行连接到P1.0 - P1.3列连接到P1.4 - P1.7

蜂鸣器:

蜂鸣器连接到P2.5

独立按键:

按键1 -> P3.0按键2 -> P3.1按键3 -> P3.2按键4 -> P3.3

确保以上连接和代码都正确后,编译和烧录到德飞莱51单片机上,代码应能正确运行,显示密码输入和倒计时,并且实现蜂鸣器报警功能。

相关推荐

柰【中药】【中医百科】
365bet体育在线赌场

柰【中药】【中医百科】

📅 08-11 👁️ 5453
千珏皮肤手感大比拼:哪款手感最佳?
精准原创123656官方网

千珏皮肤手感大比拼:哪款手感最佳?

📅 08-02 👁️ 6443
一种去除含钕、镨、镝和铁溶液中铁离子的方法与流程
精准原创123656官方网

一种去除含钕、镨、镝和铁溶液中铁离子的方法与流程

📅 08-07 👁️ 6002
格式工厂的使用方法:如何使用格式工厂转换文件格式
365bet体育在线赌场

格式工厂的使用方法:如何使用格式工厂转换文件格式

📅 07-15 👁️ 9386
《宝可梦》火箭队为何钟情于小智的皮卡丘?早在一开始就有交代
佣金比率是多少?佣金比率的计算方法
365bet体育在线赌场

佣金比率是多少?佣金比率的计算方法

📅 07-17 👁️ 4690
辟谣:还说狗狗不咬人?没有绝不咬人的犬种,狗狗咬人都有原因的
卡航是什么意思?
精准原创123656官方网

卡航是什么意思?

📅 07-20 👁️ 2603
100幅国画狗,太哏儿了~(附教程)
365游戏注册

100幅国画狗,太哏儿了~(附教程)

📅 08-01 👁️ 876