> 文章列表 > 51电动车报警器.md

51电动车报警器.md

51电动车报警器.md

1.项目接线

接线示意图和实物图

示意图:

51电动车报警器.md

实物图:

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口,变量名vibrate2.sbit指令找到P1这个I/O口组的第2位,将p1.2口作为输入口,接入433接收模块的DO口,这个口对应遥控器的按键A,变量名是remote433_D03.sbit指令找到P1这个I/O口组的第3位,将p1.3口作为输入口,接入433接收模块的D1口,这个口对应遥控器的按键B,变量名是remote433_D14.sbit指令找到P1这个I/O口组的第1位,将P1.1口作为输出口,接上继电器的IN引脚,变量名是relayf1. 延时函数,用于进入警报模式后长响2s: void Delay2000ms();
    f2. 延时函数,用于进入警报模式后长响1s: void Delay1000ms();
    f3. 延时函数,用于警报模式下受到振动后长响5s: int Delay5000ms(); //针对BUG对其进行了修改1. while死循环,查询法,/* 如果按下遥控器的A按键,设定为报警模式 */1.1 判断是否按下按键A: 判据是 remote433_D0 == remote_ON1.1.1 如果是,则说明按下修改代表警报是否开启的标志位循环变量alarmFlag: alarmFlag = alarm_ON;接通继电器: relay = 0;让喇叭响两秒,作为提示音: Delay2000ms();断开继电器: relay = 1;1.1.2 否则,就啥也不干/* 如果按下遥控器的B按键,设定为关闭报警模式 */1.2 判断是否按下按键B: 判据是 remote433_D1 == remote_ON1.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 == 01.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);
    }