一、红外探测器需要实现的主要功能:

  • 红外报警检测
  • 电池低压检测
  • 防拆开关检测
  • OOK无线发射
  • 设备低功耗设计

二、搭建软件开发环境

本产品的主控芯片是STC15W204S

1. Keil软件的安装

关于Keil C51的安装我在这里就不给大家介绍了,这块视频教程大家直接在小破站搜无际单片机编程,看单片机c语言编程视频教程第4节即可。

2.安装STC的库文件到Keil软件里

①打开STC-ISP软件

②选择Keil仿真设置-> 增加型号和头文件到Keil中,如下图。

③选择Keil C51的安装目录,点击确定

④安装完成

3. 项目工程新建:

双击Keil 软件图标,打开软件

选择Project ->new uvision Project…

选择工程文件夹,给工程命名,然后点击确定

选择单片机对应的型号,如下图,点击OK

新建main.c 文件,并添加到工程中,在这里就给大家不介绍了。

三、软件设计

这里会对每个模块的代码进行详细讲解,整体源代码可以在公号无际单片机编程拿到。

1.红外报警检测

我们先看一下硬件接口:

  • 逻辑分析:

1. 无线红外报警触发的逻辑,我们在硬件设计中,已经有讲过, 如果红外报警PIR_ALARM 脚会有一个下降沿信号。

2. PIR_ALARM 连接到单片机的P3.6,也是单片机的外部中断2功能脚。

3. 单片机平时需要进入休眠状态,所有红外报警需要使用外部中断唤醒功能。

  • 我们先了解一下单片机的IO寄存器和外部中断2寄存器配置:

IO的寄存器介绍:

STC单片机的IO有3个寄存器。例如P3.6 包括P3, P3M0、P3M1。

其中P3M0、P3M1是用来配置单片机IO的模式的具体如下:

无线红外报警器的P3.6口,我们配置为准双向口即可。

P3 口和传统51单片机的功能是一样的,P3的输入输出端口。

外部中断2的寄存器介绍:

STC15W系列单片机的INT2只支持下降沿中断。详细的信息大家可以查阅STC15系列单片机的规格书。

外部中断2相关的寄存器INT_CLK0如下:

EX2= 1 打开外部中断2功能。

  • 软件程序开发:

程序初始化:

sbit PIR_ALARM P3^6 ///定义红外报警的端口为P3.6
unsigned char alarm_state; ///初始化为2 =0表示防拆报警 =1 表达红外报警///P3.6 配置成准双向IO口
P3M0 &= b10111111; //P3M0.6 = 0;
P3M1 &= b10111111; //P3M1.6 =0;
PIR_ALARM = 1; //准双向IO口是输入状态是,需要先把该端口置1///初始化外部中断2
INT_CLKO |= 0x10; //(EX2 = 1)使能INT2中断
EA = 1; //打开总中断开关
报警状态变量初始化
alarm_state = 2;

外部中断2的中断服务函数

void exint2() interrupt 10 //INT2中断入口
{ //无线红外报警
alarm_state = 1;//
}
报警信号处理程序
if(alarm_state==1)
{//红外报警
if(PIR_ALARM==0)
{
delay1ms(10); ///防抖延时
if(PIR_ALARM==0)
{
ALARM_LED = 1;//打开指示灯
ookSent(0x03);//发射开门信号
}
}
alarm_state=2; 初始化变量 alarm_state
}

2.电池低压检测

  • 我们先看一下硬件接口:

关于单片机的低压检测电路,在硬件设计中,我们已经做过介绍,是下降沿报警触发。

Low_vot 和单片机的NIT4(P3.0),连接,A1是一个跳线帽,是为了防止低压检测线路对单片机的烧录有影响,导致无法烧录。

在程序烧录的时候,需要拔掉A1,完成烧录后需要恢复A1跳线帽。

  • 相关寄存器介绍:

P3.6寄存器的功能关于单片机的低压检测电路,在硬件设计中,我们已经做过介绍,是下降沿报警触发。

P3.6IO的寄存器配置和2.1.3.1中的P3 端口的配置 一致,在这里就给大家不在重复讲解了。

电池低压检测的方式也是通过外部中,在这里用到的是外部中断INT4. 关于INT4的寄存器如下,配置方法和INT2一样:

  • 软件程序开发:

程序初始化:

sbit BAT_LOW_DC = P3^0; ///定义电池低压检测端口为P3.0
unsigned char vlotLow_flag; // =0 电池正常 1电池低压 2电池低压中
///P3.0 配置成准双向IO口
P3M0 &= b11111110; //P3M0.0 = 0;
P3M1 &= b11111110; //P3M1.0 =0;
BAT_LOW_DC = 1; //准双向IO口是输入状态是,需要先把该端口置1///初始化外部中断2
INT_CLKO |= 0x40; //(EX4 = 1)使能INT4中断
EA = 1; //打开总中断开关
低压报警状态变量初始化
alarm_state = 0;

外部中断4的中断服务函数

void exint4() interrupt 16 //INT4中断入口
{//低压中断报警
vlotLow_flag= 1;
}

报警信号处理程序

if(vlotLow_flag == 1)
{电池低压
delay1ms(10); ///防抖延时
if(BAT_LOW_DC == 0)
{电池第一次低压
vlotLow_flag = 2;
ALARM_LED = 1;///工作状态灯打开
ookSent(0x05);//发射低压信号
ALARM_LED = 0;///工作状态灯关闭
}
else
{
vlotLow_flag = 0;
}
}
if(vlotLow_flag == 2)
{电池低压提示
ALARM_LED = 1;///工作状态灯打开
delay1ms(100);
ALARM_LED = 0;///工作状态灯关闭
}

3.防拆开关检测

  • 我们先看一下硬件接口:

  • 逻辑分析:

防拆开关S1和R14 组成了产品的防拆功能。 其中R14是上拉作用。

防拆开关按下去防拆开关的1脚和2脚连接,单片机的P3.3是高电平,如果防拆开关松开,1脚和3脚连接,P3.3变成低电平。

即: 触发防拆开关,P3.3由高电平变成低电平(下降沿触发);

P3.3是单片机的外部中断1接口(INT1).检测红外防拆报警就是外部中断1的下降沿中断。

  • 相关寄存器介绍:

单片机P3.3 端口的配置

相关配置和低压检测,红外报警检测一致。

外部中断1 相关寄存器介绍

外部中断1 我们需要配置的寄存器包括IE中断允许寄存器,和TCON 定时器/计数器中断控制寄存器。详细如下:

在我们的防拆程序中使用的外部中断1的控制为EX1  需要置为1,打开外部中断1.

单片机的外部中断1 可以配置成上升沿触发,或下降沿触发。  该寄存器中的IT1=1表示外部中断1为下降沿触发 ;IT1=0 表示为上升沿触发。我们产品中使用的是下降沿触发,所有IT1 需要配置成1。

  • 软件程序开发:

程序初始化:

sbit TEMPER_ALARM = P3^3; ///定义防拆检测端口为P3.3///P3.3 配置成准双向IO口
P3M0 &= b11110111; //P3M0.3 = 0;
P3M1 &= b11110111; //P3M1.3 =0;
TEMPER_ALARM = 1; //准双向IO口是输入状态是,需要先把该端口置1///初始化外部中断1
EX1 = 1; //取用P3^3(INT1)中断
IT1 = 1; //外部中断1为边沿触发方式

外部中断1的中断服务函数

void exint1() interrupt 2 //外部中断1/INT1中断入口
{//防拆按钮
alarm_state = 0;//
}
报警信号处理程序

if(alarm_state==0)
{//防拆开关报警
if(TEMPER_ALARM==0)
{
delay1ms(10);
if(TEMPER_ALARM==0)
{
ookSent(0x0b);//发射防拆报警
}
}
alarm_state=2;
}
4.OOK无线发射
  • 我们先看一下硬件接口:

从原理图的图纸大家可以看到,无线发射数据和单片机的P3.2脚位连接。

  • 学习了解一些EV1527 OOK的无线数据

在程序开发之前,大家首先要学习一下无线数据发射的格式和定义。大家可以在网上百度下载ev1527 芯片资料 ,然后对照我们后面的内容浏览,可以帮助更有效的理解OOK无线数据发射。

我们先看一下数据格式,如下图。

从上图我们可以看出,芯片的数据内容是 :同步码+20bit地址+4bit数据码。

20bit +4bit =24bit  = 3byte。

从上图,我们可以看到有一个单位LCK.    那LCK的定义是什么,时间是多久?

1LCK = 8个0SC CLOKC.

我们在看一个表格,如下,这个表格定义了16个LCK的时间,从而我们就可以算出1个CLK的时间:

从表格可以看出,LCK的时间和 工作电源,以及前面的振荡电阻(47K-360K)有关。

本产品选择的是330K的振荡电阻,工作电压是12V。 所有我们可以锁定16LCK的时间为1.44ms.     那一个LCK= 90微妙。

我们计算一下同步信号,1,0 的信号。

同步信号:  4LCK高电平,128LCK 低电平   即:  360us 高电平     11.52ms低电平

数据1:    12LCK 高电平,4LCK 低电平     即: 1.08ms高电平    360us 低电平

数据0:       4LCK 高电平,12LCK 低电平     即: 360ms高电平  1.08ms 低电平

OOKSent 脚位发出的波形如下:

  • 程序代码设计

需要实现OOK无线数据的发射,需要使用到单片机的定时器 和IO输出两个功能。

单片机的IO 配置

单片机的IO 默认是 准双向输入输出端口,我们在程序里就不配置了,我们直接将OOKSent 拉低即可。

程序如下:

sbit OOK_SENT = P3^2; ///无线数据发射端口定义
OOK_SENT = 0;
定时器配置

本产品中我们使用的是单片机的定时器0.  我们先了解一下单片机相关的寄存器

定时器的相关寄存器:

  • 寄存器AUXR
  • 配置定时器0的工作频率,T0X12 = 0  12T模式,=1为1T模式。我们选择12T模式

  • 寄存器TMOD 定时器工作模式寄存器

我们产品中配置为16为自动重装定时器.  C/T 和GATE 直接置0 即可。

  • TH0 TL0寄存器

定时器0的计数器,数据自动增加到FFFF 溢出,发生中断。

  • 定时器控制寄存器TCON

TF0:定时器0中断溢出位。TH0 TL0中的数据增加到FFFF时,TF0 就置为1,需要手动清0

TR0:  定时器0 的开关控制位。=1打开定时器0   =1 关闭定时器0

  • 中断允许寄存器IE

ET0 = 0:  定时器0溢出标志位TF0=1 的时候,程序就不会自动进入中断服务函数

ET0 = 1:  定时器0溢出标志位TF0=1 的时候,程序就会自动进入中断服务函数

  • 定时器初始化程序设计

定时器初始化:

AUXR &= 0x7F; //定时器时钟12T模式
TMOD = 0; //中断后手动填写TL0 TH0的值。
TL0 = 0; //设置定时初值
TH0 =0; //设置定时初值
TR0 = 0; //定时器0开始计时
ET0=0; //关闭定时器中断
注意,我们初始化的时候,定时器0 是关闭的,再我们使用的时候再打开。

无线数据中同步信号,数据1 、数据0数据长度的计算。

上小节分析了同步信号,和数据1 ,数据0的数据的时间长度如下:

同步信号:  4LCK高电平,128LCK 低电平   即:  360us 高电平     11.52ms低电平

数据1    12LCK 高电平,4LCK 低电平     即: 1.08ms高电平    360us 低电平

数据0:       4LCK 高电平,12LCK 低电平     即: 360us高电平  1.08ms 低电平

从上面我们简单的总结一下,我们需要做3个延时 分别是: 360us  1.08ms  11.52ms。

下面我们计算一下3个延时定时器0的TH0 TL0 分别需要填充的数值:

360us 延时TH0 TL0对应的数值.(重要)

我们选择的是单片机的内部时钟5.5296Mhz,定时器时钟是12T  ,我们可以计算出定时器一个计数值的时间,计算公式如下:

1S/5.5296MHZ*12  = 1S/5529600M0HZ*12 = 0.0000217S = 2.17uS。

360uS 延时需要的定时器的计数值  =  360/2.17 = 166.

那TH0 TL0填写的数值是多少?  TH0 TL0的数值增加到0xFFFF 再增加1定时器溢出。

0xFFFF对应的65535,定时器0是计数到65536溢出。

所以我们需要用65536减去166 ,65536-166 = 65370。

然后转换成16进制,填充到TH0 TL0,

65370是十进制,我们需要转换成16进制  0xFF5A

TH0 = 65370/256;   //FFH

TL0 = 65370%256;  //5AH

1.08ms 延时TH0 TL0对应的数值

同样的原理,我们计算出1.08ms 对应的TH0 TL0寄存器对应的值

1.08ms/2.17us = 1080us/2.17us= 498    65536-498 = 65038

TH0 = 65038/256;   //FEH

THL = 65038%256;  //0EH

11.52ms 延时TH0 TL0对应的数值

同样的原理,我们计算出11.52ms 对应的TH0 TL0寄存器对应的值

11.52ms/2.17us = 11520us/2.17us =5309     65536-5309 = 60227

TH0 =60227/256;   //EBH

THL = 60227%256;  //43H

我们用宏定义来定义一下同步信号,数据1 和数据0。

//同步信号:
#define SYN_SIGNAL_H_TH0 0xFF // 4LCK高电平 360us
#define SYN_SIGNAL_H_TL0 0x5A
#define SYN_SIGNAL_L_TH0 0xEB//128LCK 低电平 11.52ms
#define SYN_SIGNAL_L_TL0 0x43//数据1:
#define SIGNAL_1_H_TH0 0xFE // 12LCK 高电平,1.08ms
#define SIGNAL_1_H_TL0 0x0E
#define SIGNAL_1_L_TH0 0xFF //4LCK 低电平, 360us
#define SIGNAL_1_L_TL0 0x5A//数据0:
#define SIGNAL_0_H_TH0 0xFF // 4LCK 高电平,360us
#define SIGNAL_0_H_TL0 0x5A
#define SIGNAL_0_L_TH0 0xFE //12LCK 低电平, 1.08ms
#define SIGNAL_0_L_TL0 0x0E

OOK 无线发射数据的转换

上节计算出了同步数据,数据1,数据0的高低电平,以及对用的定时器填充的数据,接下来我们就需要把需要发射的数据转换成以下的波形。

在上面的章节中,我们分析了,OOK的无线发射数据内容是 :同步码+20bit地址+4bit数据码。

计算OOK无线发射数据,定时器0的寄存器TH0 TL0 需要的字节

同步码的 高电平和低电平,分别需要定时器0精准定时,分别占用2个字节,共4个字节.

20个地址+4位数据码 =24bit 数据。

每个数据要么是0,要么是1,0和1和同步信号一样,需要分别精准定时高电平和电平的持续时间,1个数字需要4个,共24位,则24*4 =96个字节。

所以存储一帧数据需要定时器的字节数位100个。

程序设计如下:


unsigned char timerbuffer[100]; ///用来存储OOK无线数据对应的定时器的值
void ookSent(unsigned char comd)// cmd无线数据的操作码
{
unsigned char temp,i;
unsigned char data0,data1,data2; ///无线发射数据的地址 20位 data0,data1,data2高4位。
data0=CBYTE[0xFF8];
data1=CBYTE[0xFF7];
data2=CBYTE[0xFF6]; ///获取无线的地址码
data2 &=0xF0;
data2 |= (cmd&0x0F);
for(i=0;i<100;i++)
{
if(i==0)
{同步信号
timerbuffer[i]=SYN_SIGNAL_H_TH0;
i++;
timerbuffer[i]=SYN_SIGNAL_H_TL0;
i++;
timerbuffer[i]=SYN_SIGNAL_L_TH0;
i++;
timerbuffer[i]=SYN_SIGNAL_L_TL0;
}
else
{
if(i==4)
{
temp=data0;
}
else if(i==36)
{
temp=data1;
}
else if(i==68)
{
temp=data2;
}
for(n=0;n<8;n++)
{
if((temp&b10000000)==b10000000)
{//=1
timerbuffer[i]=SIGNAL_1_H_TH0;
i++;
timerbuffer[i]=SIGNAL_1_H_TL0;
i++;
timerbuffer[i]=SIGNAL_1_L_TH0;
i++;
timerbuffer[i]=SIGNAL_1_L_TL0;
}
else
{//数据0:
timerbuffer[i]=SIGNAL_0_H_TH0;
i++;
timerbuffer[i]=SIGNAL_0_H_TL0;
i++;
timerbuffer[i]=SIGNAL_0_L_TH0;
i++;
timerbuffer[i]=SIGNAL_0_L_TL0;
}
i++;
temp=temp<<1;
}
i--;
}
}
}

无线数据发射代码:

P3M0|=b00000100;
ALARM_LED=0;
OOK_SENT=1;
TR0 = 1; //定时器0开始计时
ET0 = 0; //使能定时器0中断
{
for(temp=0;temp<28;temp++)
{//发射时间
for(i=0;i<100;i++)
{
TF0=0;
OOK_SENT=!OOK_SENT;
TH0 =timerbuffer[i];
i++;
TL0=timerbuffer[i];
while(!TF0)
{
}
}
}
TF0 = 0;
TR0 = 0;
ALARM_LED=1;
P3M0&=b11111011;
OOK_SENT=0;
}

5. 设备低功耗设计

因我们的产品是电池供电,所以我们的程序需要做低功耗设计。

  • STC15W单片机的工作模式。

STC15单片机支持3种省电模式,分别是:低速模式,空闲模式,和掉电模式。三种模式的典型功耗分别是 2.7mA-7mA,  1.8mA,<0.1A。  掉电模式的最小,我们选择的就是掉电模式。

  • 掉电模式对应的寄存器介绍:
  • 掉电控制寄存器PCON

  • 程序设计:
{
PCON=0X02;//进入掉电模式
_nop_();
_nop_();
_nop_();
_nop_();
}

至此,红外探测器代码部分就讲解完了,感谢对无际单片机编程的支持!

无线红外探测器03-环境搭建及程序详解相关推荐

  1. 华维单片机编程-无线红外探测器03-环境搭建及程序详解

    大家好,我是华维,专注10年单片机实战/教学/辅导 一.红外探测器需要实现的主要功能: 红外报警检测 电池低压检测 防拆开关检测 OOK无线发射 设备低功耗设计 二.搭建软件开发环境 本产品的主控芯片 ...

  2. pycharm+python3.7+pyqt配置_Python3+Pycharm+PyQt5环境搭建步骤图文详解

    搭建环境: 操作系统:Win10 64bit Python版本:3.7 Pycharm:社区免费版 一.Python3.7安装 下载到安装包后打开,如果想安装到默认路径(C盘)的话一直点下一步就可以了 ...

  3. phonegap安装 环境搭建与配置详解(3.4 完整版 提供下载地址)

    phonegap安装 环境搭建与配置详解(3.4 完整版 提供下载地址) 原文连接:http://blog.csdn.net/aaawqqq/article/details/19755179 phon ...

  4. pycharm python3.7环境_Python3+Pycharm+PyQt5环境搭建步骤图文详解

    搭建环境: 操作系统:Win10 64bit Python版本:3.7 Pycharm:社区免费版 一.Python3.7安装 下载到安装包后打开,如果想安装到默认路径(C盘)的话一直点下一步就可以了 ...

  5. Tomcat环境搭建与常见问题详解

    Tomcat环境搭建和常见问题详解 Tomcat介绍 环境搭建流程 配置Java 注意事项 下载Java 安装Java 配置环境变量 测试Java 配置Tomcat 下载Tomcat 安装Tomcat ...

  6. Redis环境搭建以及常见问题详解

    Redis环境搭建以及常见问题详解 环境的搭建 Redis是什么??? Redis起源 Redis 简介 Redis优势 Redis与其他key-value存储数据库的区别 Redis 下载和安装 R ...

  7. 学习笔记之-Kubernetes(K8S)介绍,集群环境搭建,Pod详解,Pod控制器详解,Service详解,数据存储,安全认证,DashBoard

    笔记来源于观看黑马程序员Kubernetes(K8S)教程 第一章 kubernetes介绍 应用部署方式演变 在部署应用程序的方式上,主要经历了三个时代: 传统部署:互联网早期,会直接将应用程序部署 ...

  8. 【Spring】Spring第一天 - 环境搭建、IoC 详解、DI 详解等

    一.Spring 框架简介及官方压缩包目录 介绍 1.主要发明者:Rod Johnson 2.轮子理论推崇者: 2.1 轮子理论:不用重复发明轮子. 2.2 IT 行业:直接使用写好的代码. 3.Sp ...

  9. 看完就能独自把集群搭起来!Hadoop HDFS完全分布式环境搭建以及技术详解

    作者 | 慢慢变成大佬 责编 | Carol 出品 | CSDN云计算(ID:CSDNcloud) 在文章开始之前,作者想要告诉大家:读懂本篇文章,能让小白快速入门,并且能够搭建完全分布式的集群,以及 ...

最新文章

  1. ISME:根系招募特异型菌群增强植物对盐胁迫的抗性
  2. CentOS7.3下Jenkins+docker自动化部署solo站点
  3. Linux下的docker容器安装教程
  4. Python 怎么样在函数内部对全局变量进行修改
  5. ubuntu 设置开机执行脚本_Ubuntu 16.04设置rc.local开机启动命令/脚本的方法
  6. Ubuntu14.04如何使用root登录
  7. 某少儿不宜网站图片拍摄位置分析,Python批量读取图片GPS位置!
  8. css3 如何动态画一条直线_素描基础学习课:素描长直线的画法!把直线画直的关键!...
  9. 利用Sigar获取系统信息
  10. mysql打开数据库控制台_在控制台中操作MYSQL数据库步骤以及一些小问题
  11. Mac电脑隔空投递怎么添加到菜单栏?
  12. java服务器 protobuf_服务器端用PHP,客户端用JAVA,通过protobuf互相通信[原创] | 学步园...
  13. 数学模型——Logistic回归模型(含Matlab代码)
  14. Element DatePicker 日期选择器限定日期选择范围
  15. OPNsense - 多功能高可靠易使用的防火墙(四)
  16. Python常用库汇总
  17. 机器学习数据集-MNIST
  18. 2013年09月27日
  19. 总谐波失真80_总谐波失真怎么计算啊
  20. python能代替cad吗_免费且强大的CAD软件_DraftSight V1R5.1 可直接用来代替autoCAD

热门文章

  1. SPU表管理之更新SPU表数据
  2. TensorFlow介绍之TF数据流图
  3. Pytorch中的序列化容器-度消失和梯度爆炸-nn.Sequential-nn.BatchNorm1d-nn.Dropout
  4. 利用python将数据写入CSV文件中
  5. kali linux解决:ping: www.baidu.com: 未知的名称或服务(亲测有效)(走了两个弯路,浪费了好多时间)
  6. 详解 | SLAM回环检测问题
  7. 最新综述:车辆重识别技术
  8. 使用 Python 的基于边缘和基于区域的分割
  9. 3D 视觉 相关知识-SLAM框架-常见方案对比
  10. SAX解析XML文档——(二)