51电动车报警器.md

1.项目接线

接线示意图和实物图

示意图:

image-20230416140422175

实物图:

image-20230416162747903

信号传输路线

路线1: 433遥控信号 ——> 433接收模块D0引脚以及D1引脚 ——> 单片机P1^2引脚以及P1^3引脚 ——> 单片机P1^1引脚 ——> 继电器IN引脚 ——> 继电器COM口和NO口 ——> 高功率喇叭(负载)所在电路

路线2:振动信号 ——> 振动传感器DO引脚 ——> 单片机P3^3引脚 ——> 单片机P1^1引脚 ——> 继电器IN引脚 ——> 继电器COM口和NO口 ——> 高功率喇叭(负载)所在电路


2.项目实现流程

基本控制逻辑

  1. 业务需求
  • 功能1:遥控器按下按键,上锁,并长响一声示意。

  • 功能2:上锁后,如果振动传感器检测到振动后(被人骑走,被人推倒),导通继电器,继电器控制高功率喇叭开始报警。

  • 功能3:遥控器按下按键,解锁,并短响一声示意,之后发生振动也不会报警。

  • 功能4:电动车被人偷走,手机app打开地图显示电动车位置(高阶功能,现在不考虑

  1. 控制逻辑: 可以看出本简易项目包含两种模式
  • 警报模式
    • 振动后报警
    • 强制解除报警
  • 解除警报模式

Debug成功,完事

代码心得:

  • 本代码使用查询法,查询法中加入警报标志位alarmFlag。(也可以不定义警报标志位)
  • I/O口连得一多(负载多的时候),我的51单片机中间那部分VCC和GND引脚如果出于连接状态好像会阻止程序烧录,所以需要停止下载,然后拔掉那部分杜邦线,等到程序烧录完成后再接回去。

可以优化的地方:

  • 假如你多次重复按下同一个按键,提示音不会继续响。
  • BUG:我们面对“警报模式中一直受到振动后无法用按键立马解除警报模式”这一问题,也就是信号丢失问题,我们以下代码的解决方法对从STC-ISP的程序延时计算器中拷贝来的延时函数进行修改,加一个判断。更好的解决方法是用中断的方法,因为一直振动导致的结果不就是程序一直在数数嘛,那么我们遇到变故后先把数数这段代码挂起,强制去执行别的代码。我们以后会学到。
  1. 思路:

    宏定义:
        #define remote_ON  1    //根据433接收模块信号表现,高电平代表接收到信号,代表按键按下
    	#define alarm_ON   1	//代表进入警报模式
    	#define alarm_OFF  0	//代表关闭警报模式
    全局变量:
    	1.sbit指令找到P3这个I/O口组的第3位,将p3.3口作为输入口,接入振动传感器的DO口,变量名vibrate
        2.sbit指令找到P1这个I/O口组的第2位,将p1.2口作为输入口,接入433接收模块的DO口,这个口对应遥控器的按键A,变量名是remote433_D0
        3.sbit指令找到P1这个I/O口组的第3位,将p1.3口作为输入口,接入433接收模块的D1口,这个口对应遥控器的按键B,变量名是remote433_D1
        4.sbit指令找到P1这个I/O口组的第1位,将P1.1口作为输出口,接上继电器的IN引脚,变量名是relay
    
    f1. 延时函数,用于进入警报模式后长响2s: void Delay2000ms();
    f2. 延时函数,用于进入警报模式后长响1s: void Delay1000ms();
    f3. 延时函数,用于警报模式下受到振动后长响5s: int Delay5000ms(); //针对BUG对其进行了修改
            
    1. while死循环,查询法,
        /* 如果按下遥控器的A按键,设定为报警模式 */
        1.1 判断是否按下按键A: 判据是 remote433_D0 == remote_ON
            1.1.1 如果是,则说明按下
            		 修改代表警报是否开启的标志位循环变量alarmFlag: alarmFlag = alarm_ON;
                	 接通继电器: relay = 0;
    				 让喇叭响两秒,作为提示音: Delay2000ms();
    				 断开继电器: relay = 1;
            1.1.2 否则,就啥也不干
        /* 如果按下遥控器的B按键,设定为关闭报警模式 */
        1.2 判断是否按下按键B: 判据是 remote433_D1 == remote_ON
            1.2.1 如果是,则说明按下
            	  	 修改代表警报是否开启的标志位循环变量alarmFlag: alarmFlag = alarm_OFF;
                	 接通继电器: relay = 0;
    				 让喇叭响一秒,作为提示音: Delay1000ms();
    				 断开继电器: relay = 1;
            1.2.2 否则,就啥也不干(不管有没有受到振动)
        /* 如果警报模式下发生振动,喇叭响 */
        1.3 通过alarmFlag判断是否处于报警状态
            1.3.1 如果是,
            	1.3.1.1 接着判断是否感应到振动: 判据是 vibrate == 0
                    1.3.1.1.1 如果是,则说明需要警报
                    	 接通继电器: relay = 0;
    					 让喇叭响五秒: Delay5000ms();
    					 让喇叭响五秒: Delay5000ms();
    				1.2.1.1.2 否则,说明没有受到振动
                         断开继电器: relay = 1;
            1.3.2 否则,就啥也不干
    
    
    
  2. 代码:

    #include "reg52.h"
    #include "intrins.h"
    
    #define remote_ON  1    //根据433接收模块信号表现,高电平代表接收到信号,代表按键按下
    #define alarm_ON   1	//代表进入警报模式
    #define alarm_OFF  0	//代表关闭警报模式
    
    sbit vibrate      = P3^3; //p3.3口作为输入口,接入振动传感器的DO口
    sbit remote433_D0 = P1^2; //P1.2口作为输入口,接入433接收模块的DO口,这个口对应遥控器的按键A
    sbit remote433_D1 = P1^3; //P1.3口作为输入口,接入433接收模块的D1口,这个口对应遥控器的按键B
    sbit relay        = P1^1; //P1.1口作为输出口,将电平信号输出给继电器(低电平触发)
    
    /* API1: 延时函数,用于进入警报模式后长响1s */
    void Delay2000ms();
    /* API2: 延时函数,用于解除警报模式后短响0.5s */
    void Delay1000ms();
    /* API3: 延时函数,用于警报模式下受到振动后长响4s */
    int Delay5000ms();
    
    int main(void)
    {
    	char alarmFlag = alarm_OFF;
        /* 查询法 */
        while(1){
    		/* 如果按下遥控器的A按键,设定为报警模式 */
            if(remote433_D0 == remote_ON){
    			alarmFlag = alarm_ON;
                relay = 0;  
    			Delay2000ms();
    			relay = 1;
            }
    		/* 如果按下遥控器的B按键,设定为关闭报警模式 */
    		if(remote433_D1 == remote_ON){
                alarmFlag = alarm_OFF;
                relay = 0;  
    			Delay1000ms();
    			relay = 1;
            }
    		/* 如果警报模式下发生振动,喇叭响 */
    		if(alarmFlag == alarm_ON){
    			if(vibrate == 0){
    				relay = 0;
    				Delay5000ms();
    				relay = 1;
    			}else{
    				relay = 1;
    			}
    		}
        }
        return 0;
    }
    
    void Delay2000ms()		//@11.0592MHz
    {
    	unsigned char i, j, k;
    
    	_nop_();
    	i = 15;
    	j = 2;
    	k = 235;
    	do
    	{
    		do
    		{
    			while (--k);
    		} while (--j);
    	} while (--i);
    }
    
    void Delay1000ms()		//@11.0592MHz
    {
    	unsigned char i, j, k;
    
    	_nop_();
    	i = 8;
    	j = 1;
    	k = 243;
    	do
    	{
    		do
    		{
    			while (--k);
    		} while (--j);
    	} while (--i);
    }
    
    int Delay5000ms()		//@11.0592MHz
    {
    	unsigned char i, j, k;
    
    	_nop_();
    	i = 36;
    	j = 5;
    	k = 211;
    	do
    	{
    		if(remote433_D1 == remote_ON){
    			return 0;
    		}
    		do
    		{
    			while (--k);
    		} while (--j);
    	} while (--i);
    }
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值