51单片机实战训练——红外遥控电子密码锁(含项目源码)

51单片机红外遥控电子密码锁实战

51单片机实战训练——红外遥控电子密码锁(含项目源码)

开发软件:Keil4(编写程序)、STC-ISP(烧录下载)
目标效果:用户可以通过红外遥控器上的数字输入密码(0-9)。密码输入正确,驱动舵机旋转90°(模拟门锁开启);密码错误则蜂鸣器发出警报。

一、HS0038红外接收模块

在51单片机模块学习中,我们对HS0038红外接收模块已经有了一定的了解,在这里我们做一个更加全面的学习。

1-1.HS0038基本参数

  • 工作电压:2.7V ~ 5.5V(兼容3.3V和5V系统)
  • 载波频率:中心频率38kHz(允许偏差±1kHz,如37kHz~39kHz)
  • 接收距离:典型值约10米(实际受环境光、发射功率影响)
  • 输出信号:数字信号(低电平有效),无信号时输出高电平,接收到信号时输出低电平脉冲。
  • 引脚定义:3个引脚,通常从左到右依次为OUT/GND/VCC(不同厂家可能引脚顺序不同,需以实际模块标注为准

1-2.工作原理

1-2-1.HS0038硬件工作流程
  1. 信号接收:HS0038 持续接收环境中的红外信号,通过内部电路滤除非38kHz的干扰信号。当检测到38kHz调制的红外信号(如遥控器按键按下)时,其OUT引脚输出低电平脉冲。
  2. 信号输出特性:无信号时OUT引脚保持高电平。有信号时OUT引脚输出与调制信号反相的低电平波形(如NEC协议信号)。
1-2-2.结合代码讲解HS0038工作流程

1. 初始化
IR_Init() 调用 Timer0_Init()Int0_Init()

  • 定时器0:用于精确测量脉冲时间间隔。
  • 外部中断0:配置为下降沿触发(IT0=1),当HS0038的OUT引脚电平从高变低时触发中断。

2. 中断触发与状态机控制

  • 中断入口:红外信号到来时,HS0038的OUT引脚产生下降沿,触发 Int0_Routine() 中断函数。
  • 通过状态机(IR_State) 分阶段处理信号。

在这里插入图片描述

3. 时间测量与协议解析

  • 定时器关键作用
    使用定时器0记录相邻两个下降沿之间的时间(单位:定时器计数),用于判断信号类型:
    在这里插入图片描述
  • 数据位存储
    通过 IR_Data[4] 数组存储32位数据(4字节):
    字节0:地址码
    字节1:地址码反码(校验用)
    字节2:命令码
    字节3:命令码反码(校验用)

4. 数据验证与应用

  • 校验逻辑:检查地址和命令的反码是否正确
  • 用户接口:通过 IR_GetDataFlag()IR_GetCommand() 等函数获取解码后的地址和命令。

二、SG90舵机模块

SG90 是一款常见的微型舵机(伺服电机),广泛应用于机器人、遥控模型、DIY项目等场景。

2-1.基本参数

在这里插入图片描述

2-2.工作原理

2-2-1.内部结构

SG90舵机内部包含以下核心组件:

  • 直流电机:提供动力。
  • 减速齿轮组:降低转速并增加扭矩。
  • 电位器(位置传感器):检测输出轴角度,形成闭环反馈。
  • 控制电路:接收PWM信号并驱动电机转动至目标角度。
2-2-2.控制逻辑
  • PWM信号解析:
    舵机通过信号线接收PWM信号,其脉冲宽度决定目标角度:

  • 0.5ms脉冲 → 对应0°位置。

  • 1.5ms脉冲 → 对应90°中间位置。

  • 2.5ms脉冲 → 对应180°位置。

  • 闭环控制:

  • 控制电路将PWM脉冲宽度转换为目标角度。

  • 电位器实时检测输出轴的实际角度

  • 控制电路比较目标角度与实际角度,驱动电机转动直至两者一致(误差趋近于零)。

2-2-3.运动流程
PWM信号输入 → 控制电路解码目标角度 → 电机转动 → 齿轮减速 → 输出轴转动  
                ↑反馈调整↓  
              电位器检测当前角度
2-2-4.代码测试

在这里我们不妨写一个代码,实现以下的功能:按下独立按键1(模拟输入正确密码),舵机旋转90°(开锁),五秒后舵机复位。

#include <reg52.h>
#include <intrins.h>

sbit Servo_PWM = P1^0;  // 舵机信号线接P1.0
sbit Key1 = P3^1;       // 独立按键1接P3.1

unsigned int PWM_Count = 0;     // PWM周期计数器
unsigned char PWM_Duty = 11;    // 初始占空比(对应0°)
bit Key_Pressed = 0;            // 按键按下标志
unsigned int Delay_Cnt = 0;     // 延时计数器

/* 定时器0初始化(用于PWM生成) */
void Timer0_Init() {
    TMOD &= 0xF0;     // 设置定时器模式为模式1(16位)
    TMOD |= 0x01;     
    // 11.0592MHz下,定时器每加1耗时1.085us
    // 目标中断周期:50us → 计数值 = 50 / 1.085 ≈ 46
    TH0 = (65536 - 46) / 256;  // 重装初值
    TL0 = (65536 - 46) % 256;
    ET0 = 1;          // 允许定时器0中断
    EA = 1;           // 开启总中断
    TR0 = 1;          // 启动定时器0
}

/* 定时器0中断服务函数 */
void Timer0_ISR() interrupt 1 {
    TH0 = (65536 - 46) / 256;  // 重装初值
    TL0 = (65536 - 46) % 256;
    
    PWM_Count++;
    if (PWM_Count <= PWM_Duty) {
        Servo_PWM = 1;   // 高电平阶段
    } else {
        Servo_PWM = 0;   // 低电平阶段
    }
    // 20ms周期计算:50us * 400 = 20ms
    if (PWM_Count >= 400) {  
        PWM_Count = 0;
    }
}

/* 定时器1初始化(用于精确延时) */
void Timer1_Init() {
    TMOD &= 0x0F;     // 设置定时器模式为模式1(16位)
    TMOD |= 0x10;     
    // 11.0592MHz下,50ms中断一次
    // 计数值 = 50000us / 1.085us ≈ 46082
    TH1 = (65536 - 46082) / 256;
    TL1 = (65536 - 46082) % 256;
    ET1 = 1;          // 允许定时器1中断
    TR1 = 1;          // 启动定时器1
}

/* 定时器1中断服务函数(50ms触发一次) */
void Timer1_ISR() interrupt 3 {
    static unsigned int sec_cnt = 0;
    TH1 = (65536 - 46082) / 256;  // 重装初值
    TL1 = (65536 - 46082) % 256;
    
    sec_cnt++;
    if (sec_cnt >= 100) {  // 100*50ms = 5秒
        // 5秒到,恢复舵机角度
        PWM_Duty = 11;      // 返回0°
        sec_cnt = 0;
        Key_Pressed = 0;    // 清除按键标志
    }
}

/* 按键消抖延时(粗略延时) */
void DelayMs(unsigned int ms) {
    unsigned int i, j;
    // 11.0592MHz下,调整为约1ms延时
    for (i = ms; i > 0; i--)
        for (j = 120; j > 0; j--); // 调整循环次数
}

/* 主函数 */
void main() {
    Timer0_Init();  // 初始化定时器0(PWM)
    Timer1_Init();  // 初始化定时器1(延时)
    
    while (1) {
        // 检测按键1是否按下(带消抖)
        if (Key1 == 0) {             
            DelayMs(10);          // 消抖延时
            if (Key1 == 0) {       // 确认按键按下
                Key_Pressed = 1;  // 标记按键已按下
                PWM_Duty = 33;    // 设置舵机为90°(1.5ms高电平)
                TR1 = 1;          // 启动定时器1开始5秒计时
            }
            while (!Key1);        // 等待按键释放
        }
    }
}

整合了一下,舵机模块代码如下

//SG90.c
#include <reg52.h>
#include <intrins.h>

sbit Servo_PWM = P1^0;
unsigned char PWM_Duty = 10;     // 默认初始位置(90度)
unsigned char Init_Duty = 10;    // 可根据需要调整

/* 角度转占空比 */
unsigned char AngleToDuty(unsigned char angle) {
    if(angle > 180) angle = 180;
    return 10 + (angle * 40) / 180; // 0.5ms~2.5ms对应10~50
}

/* 简化版角度控制 */
void SG90_rotate(unsigned char angle) {
    PWM_Duty = AngleToDuty(angle);
}

/* 定时器0中断(保持PWM生成) */
void Timer0_ISR() interrupt 1 {
    static unsigned int pwm_counter = 0;
    TH0 = (65536 - 50) >> 8;  // 50us中断
    TL0 = (65536 - 50) & 0xFF;
    
    if(++pwm_counter >= 400) pwm_counter = 0; // 20ms周期
    Servo_PWM = (pwm_counter < PWM_Duty) ? 1 : 0;
}

/* 高精度阻塞延时 */
void SG90_Delay(unsigned int ms) {
    unsigned int i, j;
    for(i=0; i<ms; i++) {
        for(j=0; j<112; j++) {  // 11.0592MHz校准值
            _nop_();
        }
    }
}

/* 系统初始化 */
void System_Init() {
    EA = 1;
    TMOD = 0x01;  // 定时器0模式1
    TH0 = (65536 - 50) >> 8;
    TL0 = (65536 - 50) & 0xFF;
    ET0 = 1;
    TR0 = 1;
}

因为单片机上定时器资源紧张,我这里去掉了一个负责舵机回位的定时器,换用Delay

主函数中只要按照初始化-舵机转动-舵机延时-舵机转动的步骤就可以驱动舵机了

三、实操步骤

3-1.LCD屏幕设计

计划一行一列显示Password:,二行二列显示红外遥控对应数字;密码输入完毕后点击确认进行判断,如果和Password一致,则清空第二行,密码错误则在第一行第11列开始闪烁Error!

3-2.红外遥控接收数字调试

结合51单片机模块学习中有关红外遥控的内容,我们可以写出以下代码

#include <REGX52.H>
#include "SG90.h"
#include "Delay.h"
#include "LCD1602.h"
#include "IR.h"

unsigned char location=0;
unsigned char Address;
unsigned char Command;

void main() {
    LCD_Init();
	LCD_ShowString(1,1,"Password:");
	IR_Init();
    while(1) 
	{
      if(IR_GetDataFlag() )	//如果收到数据帧或者收到连发帧
		{
			Address=IR_GetAddress();		//获取遥控器地址码
			Command=IR_GetCommand();		//获取遥控器命令码
			switch(Command)
			{
				case IR_1:location++;LCD_ShowNum(2,location,1,1);break;
				case IR_2:location++;LCD_ShowNum(2,location,2,1);break;
				case IR_3:location++;LCD_ShowNum(2,location,3,1);break;
				case IR_4:location++;LCD_ShowNum(2,location,4,1);break;
				case IR_5:location++;LCD_ShowNum(2,location,5,1);break;
				case IR_6:location++;LCD_ShowNum(2,location,6,1);break;
				case IR_7:location++;LCD_ShowNum(2,location,7,1);break;
				case IR_8:location++;LCD_ShowNum(2,location,8,1);break;
				case IR_9:location++;LCD_ShowNum(2,location,9,1);break;
				case IR_0:location++;LCD_ShowNum(2,location,0,1);break;
			}
		}		
        
    }
}

这串代码实现了基本的输入密码展示。

3-3.设定密码并进行确认

#include <REGX52.H>
#include "SG90.h"
#include "Delay.h"
#include "LCD1602.h"
#include "IR.h"

unsigned char location=0;
unsigned char Address;
unsigned char Command;
unsigned char password=0;
unsigned char PW=1012;//设定密码

void main() {

    LCD_Init();
	LCD_ShowString(1,1,"Password:");
	IR_Init();

    while(1) 
	{
      if(IR_GetDataFlag() )	//如果收到数据帧或者收到连发帧
		{
			Address=IR_GetAddress();		//获取遥控器地址码
			Command=IR_GetCommand();		//获取遥控器命令码

			switch(Command)
			{
				case IR_1:password=password*10+1;location++;LCD_ShowNum(2,location,1,1);break;
				case IR_2:password=password*10+2;location++;LCD_ShowNum(2,location,2,1);break;
				case IR_3:password=password*10+3;location++;LCD_ShowNum(2,location,3,1);break;
				case IR_4:password=password*10+4;location++;LCD_ShowNum(2,location,4,1);break;
				case IR_5:password=password*10+5;location++;LCD_ShowNum(2,location,5,1);break;
				case IR_6:password=password*10+6;location++;LCD_ShowNum(2,location,6,1);break;
				case IR_7:password=password*10+7;location++;LCD_ShowNum(2,location,7,1);break;
				case IR_8:password=password*10+8;location++;LCD_ShowNum(2,location,8,1);break;
				case IR_9:password=password*10+9;location++;LCD_ShowNum(2,location,9,1);break;
				case IR_0:password=password*10+0;location++;LCD_ShowNum(2,location,0,1);break;
				case IR_USD:if(password==PW){LCD_ShowString(2,1,"                ");location=0;password=0;}
							else{LCD_ShowString(1,11,"ERROR!");Delay(3000);location=0;LCD_ShowString(1,11,"      ");LCD_ShowString(2,1,"                ");password=0;}	break;
			}
		}		
        
    }
}

注意到上述密码有个限制,即密码开头必须是1-9,不可以是0.
怎么改进呢?我们可以设定密码为字符串,感兴趣的同学可以自己动手试一试

3-4.密码输入正确时,舵机工作

#include <REGX52.H>
#include "SG90.h"
#include "Delay.h"
#include "LCD1602.h"
#include "IR.h"


unsigned char location=0;
unsigned char Address;
unsigned char Command;
unsigned int password=0;
unsigned int PW=1012;


void main()
{
    LCD_Init();
	LCD_ShowString(1,1,"Password:");
	IR_Init();
	System_Init();

    while(1) 
	{
      if(IR_GetDataFlag() )	//如果收到数据帧或者收到连发帧
		{
			Address=IR_GetAddress();		//获取遥控器地址码
			Command=IR_GetCommand();		//获取遥控器命令码
			
			switch(Command)
			{
				case IR_1:password=password*10+1;LCD_ShowNum(2,++location,1,1);break;
				case IR_2:password=password*10+2;LCD_ShowNum(2,++location,2,1);break;
				case IR_3:password=password*10+3;LCD_ShowNum(2,++location,3,1);break;
				case IR_4:password=password*10+4;LCD_ShowNum(2,++location,4,1);break;
				case IR_5:password=password*10+5;LCD_ShowNum(2,++location,5,1);break;
				case IR_6:password=password*10+6;LCD_ShowNum(2,++location,6,1);break;
				case IR_7:password=password*10+7;LCD_ShowNum(2,++location,7,1);break;
				case IR_8:password=password*10+8;LCD_ShowNum(2,++location,8,1);break;
				case IR_9:password=password*10+9;LCD_ShowNum(2,++location,9,1);break;
				case IR_0:password=password*10+0;LCD_ShowNum(2,++location,0,1);break;
				case IR_USD:if(password==PW)
							{LCD_ShowString(1,11,"OPEN! ");  
							LCD_ShowString(2,1,"                ");
							SG90_rotate(0);  // 舵机动作
                            Delay(1000);
                            SG90_rotate(90);
							}
							else
							{LCD_ShowString(1,11,"ERROR!");
							LCD_ShowString(2,1,"                ");
							Delay(3000);
							}
							LCD_ShowString(1,11,"      ");LCD_ShowString(2,1,"                ");
							location=0;password=0;
							break;
			}
		}
		
					
	}
}		
        

写到这里时,会发现舵机并不能很好的运动。用单片机的IO口给舵机供电还是太勉强了,给舵机单独供电效果更佳。

四、拓展提高

完成第三章后,我们的红外遥控电子密码锁已经可以工作了。但它还有许多可提升的地方

4-1.显示优化(报错时闪烁、不显示正在输入的密码)

#include <REGX52.H>
#include "SG90.h"
#include "Delay.h"
#include "LCD1602.h"
#include "IR.h"


unsigned char location=0;
unsigned char i;
unsigned char Command;
unsigned int password=0;
unsigned int PW=1012;


void main()
{
    LCD_Init();
	LCD_ShowString(1,1,"Password:");
	IR_Init();
	System_Init();

    while(1) 
	{
      if(IR_GetDataFlag() )	//如果收到数据帧或者收到连发帧
		{
		
			Command=IR_GetCommand();		//获取遥控器命令码
			
			switch(Command)
			{
				case IR_1:password=password*10+1;LCD_ShowString(2,++location,"*");break;
				case IR_2:password=password*10+2;LCD_ShowString(2,++location,"*");break;
				case IR_3:password=password*10+3;LCD_ShowString(2,++location,"*");break;
				case IR_4:password=password*10+4;LCD_ShowString(2,++location,"*");break;
				case IR_5:password=password*10+5;LCD_ShowString(2,++location,"*");break;
				case IR_6:password=password*10+6;LCD_ShowString(2,++location,"*");break;
				case IR_7:password=password*10+7;LCD_ShowString(2,++location,"*");break;
				case IR_8:password=password*10+8;LCD_ShowString(2,++location,"*");break;
				case IR_9:password=password*10+9;LCD_ShowString(2,++location,"*");break;
				case IR_0:password=password*10+0;LCD_ShowString(2,++location,"*");break;
				case IR_USD:if(password==PW)
							{LCD_ShowString(1,11,"OPEN! ");  
							LCD_ShowString(2,1,"                ");
							SG90_rotate(0);  // 舵机动作
                            Delay(1000);
                            SG90_rotate(90);
							}
							else
							{
							LCD_ShowString(2,1,"                ");
							for(i=0;i<3;i++){LCD_ShowString(1,11,"ERROR!");Delay(500);LCD_ShowString(1,11,"      ");Delay(500);}
							}
							LCD_ShowString(1,11,"      ");LCD_ShowString(2,1,"                ");
							location=0;password=0;
							break;
			}
		}
		
					
	}
}		
        

4-2.密码输入时退位

有时密码输入错误,我们需要删除刚刚输入的那位密码,我们可以用以下代码实现

#include <REGX52.H>
#include "SG90.h"
#include "Delay.h"
#include "LCD1602.h"
#include "IR.h"


unsigned char location=0;
unsigned char i;
unsigned char Command;
unsigned int password=0;
unsigned int PW=1012;


void main()
{
    LCD_Init();
	LCD_ShowString(1,1,"Password:");
	IR_Init();
	System_Init();

    while(1) 
	{
      if(IR_GetDataFlag() )	//如果收到数据帧或者收到连发帧
		{
		
			Command=IR_GetCommand();		//获取遥控器命令码
			
			if(Command==IR_1)
			{
				password=password*10+1;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_2)
			{
				password=password*10+2;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_3)
			{
				password=password*10+3;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_4)
			{
				password=password*10+4;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_5)
			{
				password=password*10+5;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_6)
			{
				password=password*10+6;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_7)
			{
				password=password*10+7;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_8)
			{
				password=password*10+8;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_9)
			{
				password=password*10+9;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_0)
			{
				password=password*10+0;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_USD)
			{
				if(password==PW)
				{
					LCD_ShowString(1,11,"OPEN! ");  
					LCD_ShowString(2,1,"                ");
					SG90_rotate(0);  // 舵机动作
                    Delay(1000);
                    SG90_rotate(90);
				}
				else
				{
					LCD_ShowString(2,1,"                ");
					for(i=0;i<3;i++)
					{
					LCD_ShowString(1,11,"ERROR!");
					Delay(500);
					LCD_ShowString(1,11,"      ");
					Delay(500);
					}
				}
				LCD_ShowString(1,11,"      ");
				LCD_ShowString(2,1,"                ");
				location=0;
				password=0;	
			}
			if(Command==IR_RPT)
			{
				LCD_ShowString(2,location," ");
				password=password/10;
				location--;
			}
				
		}
		
					
	}
}		
        

4-3.修改密码

我们再添加一个修改密码锁密码

#include <REGX52.H>
#include "SG90.h"
#include "Delay.h"
#include "LCD1602.h"
#include "IR.h"

unsigned char mode=0;
unsigned char location=0;
unsigned char i;
unsigned char Command;
unsigned int password=0;
unsigned int PW=1012;


void main()
{
    LCD_Init();
	LCD_ShowString(1,1,"Password:");
	IR_Init();
	System_Init();

    while(1) 
	{
      if(IR_GetDataFlag()&&mode==0 )	//输入密码
		{
		
			Command=IR_GetCommand();		
			
			if(Command==IR_1)
			{
				password=password*10+1;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_2)
			{
				password=password*10+2;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_3)
			{
				password=password*10+3;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_4)
			{
				password=password*10+4;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_5)
			{
				password=password*10+5;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_6)
			{
				password=password*10+6;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_7)
			{
				password=password*10+7;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_8)
			{
				password=password*10+8;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_9)
			{
				password=password*10+9;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_0)
			{
				password=password*10+0;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_USD)
			{
				if(password==PW)
				{
					LCD_ShowString(1,11,"OPEN! ");  
					LCD_ShowString(2,1,"                ");
					SG90_rotate(0);  // 舵机动作
                    Delay(1000);
                    SG90_rotate(90);
				}
				else
				{
					LCD_ShowString(2,1,"                ");
					for(i=0;i<3;i++)
					{
					LCD_ShowString(1,11,"ERROR!");
					Delay(500);
					LCD_ShowString(1,11,"      ");
					Delay(500);
					}
				}
				LCD_ShowString(1,11,"      ");
				LCD_ShowString(2,1,"                ");
				location=0;
				password=0;	
			}
			if(Command==IR_RPT)
			{
				LCD_ShowString(2,location," ");
				password=password/10;
				location--;
			}
			if(Command==IR_EQ)
			{
				LCD_ShowString(1,1,"PW test         ");
				LCD_ShowString(2,1,"                ");
				location=0;
				password=0;
				mode=1;
			}
				
		}
		if(IR_GetDataFlag()&&mode==1 )//修改密码前确认密码	
		{
		
			Command=IR_GetCommand();
			
			if(Command==IR_1)
			{
				password=password*10+1;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_2)
			{
				password=password*10+2;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_3)
			{
				password=password*10+3;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_4)
			{
				password=password*10+4;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_5)
			{
				password=password*10+5;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_6)
			{
				password=password*10+6;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_7)
			{
				password=password*10+7;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_8)
			{
				password=password*10+8;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_9)
			{
				password=password*10+9;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_0)
			{
				password=password*10+0;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_USD)
			{
				if(password==PW)
				{
					LCD_ShowString(1,1,"New Password");  
					LCD_ShowString(2,1,"                ");
					PW=0;
					mode++;
				}
				else
				{					
					LCD_ShowString(1,1,"Password:");
					LCD_ShowString(2,1,"                ");
					mode--;		
				}
				
				LCD_ShowString(2,1,"                ");
				location=0;
				password=0;	
			}
			if(Command==IR_RPT)
			{
				LCD_ShowString(2,location," ");
				password=password/10;
				location--;
			}		
		}

	if(IR_GetDataFlag()&&mode==2 )	//输入新密码
		{
		
			Command=IR_GetCommand();		//获取遥控器命令码
			
			if(Command==IR_1)
			{
				PW=PW*10+1;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_2)
			{
				PW=PW*10+2;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_3)
			{
				PW=PW*10+3;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_4)
			{
				PW=PW*10+4;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_5)
			{
				PW=PW*10+5;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_6)
			{
				PW=PW*10+6;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_7)
			{
				PW=PW*10+7;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_8)
			{
				PW=PW*10+8;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_9)
			{
				PW=PW*10+9;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_0)
			{
				PW=PW*10+0;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_USD)
			{
				for(i=0;i<3;i++)
					{
					LCD_ShowString(1,13,"OK!");
					Delay(500);
					LCD_ShowString(1,13,"      ");
					Delay(500);
					}
				LCD_ShowString(1,1,"Password:   ");
				LCD_ShowString(2,1,"                ");
				location=0;
				password=0;
				mode=0;	
			}
			if(Command==IR_RPT)
			{
				LCD_ShowString(2,location," ");
				PW=PW/10;
				location--;
			}				
		}	
					
	}
}		

4-4.蜂鸣器报警

我们再添加一下蜂鸣器报警部分

#include <REGX52.H>
#include "SG90.h"
#include "Delay.h"
#include "LCD1602.h"
#include "IR.h"
#include "Buzzer.h"

unsigned char mode=0;
unsigned char location=0;
unsigned char i;
unsigned char Command;
unsigned int password=0;
unsigned int PW=1012;


void main()
{
    LCD_Init();
	LCD_ShowString(1,1,"Password:");
	IR_Init();
	System_Init();

    while(1) 
	{
      if(IR_GetDataFlag()&&mode==0 )	//输入密码
		{
		
			Command=IR_GetCommand();		
			
			if(Command==IR_1)
			{
				password=password*10+1;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_2)
			{
				password=password*10+2;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_3)
			{
				password=password*10+3;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_4)
			{
				password=password*10+4;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_5)
			{
				password=password*10+5;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_6)
			{
				password=password*10+6;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_7)
			{
				password=password*10+7;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_8)
			{
				password=password*10+8;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_9)
			{
				password=password*10+9;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_0)
			{
				password=password*10+0;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_USD)
			{
				if(password==PW)
				{
					LCD_ShowString(1,11,"OPEN! ");  
					LCD_ShowString(2,1,"                ");
					SG90_rotate(0);  // 舵机动作
                    Delay(1000);
                    SG90_rotate(90);
				}
				else
				{
					LCD_ShowString(2,1,"                ");
					for(i=0;i<3;i++)
					{
					LCD_ShowString(1,11,"ERROR!");
					Buzzer_Time(500);
					LCD_ShowString(1,11,"      ");
					Delay(500);
					}
				}
				LCD_ShowString(1,11,"      ");
				LCD_ShowString(2,1,"                ");
				location=0;
				password=0;	
			}
			if(Command==IR_RPT)
			{
				LCD_ShowString(2,location," ");
				password=password/10;
				location--;
			}
			if(Command==IR_EQ)
			{
				LCD_ShowString(1,1,"PW test         ");
				LCD_ShowString(2,1,"                ");
				location=0;
				password=0;
				mode=1;
			}
				
		}
		if(IR_GetDataFlag()&&mode==1 )//修改密码前确认密码	
		{
		
			Command=IR_GetCommand();
			
			if(Command==IR_1)
			{
				password=password*10+1;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_2)
			{
				password=password*10+2;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_3)
			{
				password=password*10+3;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_4)
			{
				password=password*10+4;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_5)
			{
				password=password*10+5;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_6)
			{
				password=password*10+6;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_7)
			{
				password=password*10+7;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_8)
			{
				password=password*10+8;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_9)
			{
				password=password*10+9;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_0)
			{
				password=password*10+0;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_USD)
			{
				if(password==PW)
				{
					LCD_ShowString(1,1,"New Password");  
					LCD_ShowString(2,1,"                ");
					PW=0;
					mode++;
				}
				else
				{					
					LCD_ShowString(1,1,"Password:");
					LCD_ShowString(2,1,"                ");
					mode--;		
				}
				
				LCD_ShowString(2,1,"                ");
				location=0;
				password=0;	
			}
			if(Command==IR_RPT)
			{
				LCD_ShowString(2,location," ");
				password=password/10;
				location--;
			}		
		}

	if(IR_GetDataFlag()&&mode==2 )	//输入新密码
		{
		
			Command=IR_GetCommand();		//获取遥控器命令码
			
			if(Command==IR_1)
			{
				PW=PW*10+1;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_2)
			{
				PW=PW*10+2;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_3)
			{
				PW=PW*10+3;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_4)
			{
				PW=PW*10+4;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_5)
			{
				PW=PW*10+5;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_6)
			{
				PW=PW*10+6;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_7)
			{
				PW=PW*10+7;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_8)
			{
				PW=PW*10+8;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_9)
			{
				PW=PW*10+9;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_0)
			{
				PW=PW*10+0;
				LCD_ShowString(2,++location,"*");
			}
			if(Command==IR_USD)
			{
				for(i=0;i<3;i++)
					{
					LCD_ShowString(1,13,"OK!");
					Buzzer_Time(500);
					LCD_ShowString(1,13,"      ");
					Delay(500);
					}
				LCD_ShowString(1,1,"Password:   ");
				LCD_ShowString(2,1,"                ");
				location=0;
				password=0;
				mode=0;	
			}
			if(Command==IR_RPT)
			{
				LCD_ShowString(2,location," ");
				PW=PW/10;
				location--;
			}				
		}	
					
	}
}		
        




/
/
/
/
/
作者才开始在CSDN上分享学习内容,写的不好请多多包涵。
欢迎大家在评论区和作者讨论。
码字不易,求各位看官点个关注/赞/收藏,新人博主真的很需要助力~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值