基于单片机的无线环境监控系统设计

发布时间:2015-6-25 11:36    发布者:designapp
关键词: 单片机 , 无线环境监测 , 温湿度传感器 , 继电器控制
传统方式中,对大型仓库、博物馆等无人环境的数据采集费时费力、效率低下,且实时性差,随机性大。科学技术的进步促进了自动检测系统的发展,而利用无线通信技术实现对无人环境的监测更是未来电子技术应用的发展趋势。造价低廉、使用方便的单片机在小型控制系统中获得了广泛的应用。凌阳公司推出的16位单片机SPCE061A处理速度快,独具语音识别的特色功能,是用作系统控制核心的理想选择;而传输速率高、成本低、功耗小的nRF24L01无线模块也是实现系统无线通信的最佳选择。

1 系统设计方案

系统分为主控端与监测端,通过无线模块进行数据通信,核心部分是需要对数据进行处理的主控端。主控端以SPCE061A单片机为控制核心,通过nRF24L01模块进行数据的收集,以12864液晶模块作为数据显示的平台。监测端采用8位的AT89S52单片机作为控制核心。使用DHT11数字温湿度传感器采集温湿度数据。监测端还设计有继电器电路,可以模拟在温度超过警戒值时自动打开 房间空调制冷。图1为系统整体框架图。


图1  系统整体框架图

2 硬件电路设计

2.1 微处理模块设计

主控端微处理器选用凌阳公司推出的SPCE061A单片机。SPCE061A是一款16位的微处理器,运算速度快,非常适合处理复杂的数字信号。CPU工作电压VDD 为 2.4~3.6V,CPU 时钟频率范围为0.32~49.152MHz,内置2K字SRAM以及32K字FLASH;具有2 个 16 位可编程定时器/计数器(可自动预置初始计数值);2个10位DAC(数/模转换)输出通道;32 位通用可编程输入/输出端口;具备触键唤醒的功能;7通道10位电压模/数转换器(ADC)和单通道声音模/数转换器;声音模/数转换器输入通道内置麦克风放大器和自动增益控制(AGC)功能;具备串行设备接口;具有低电压复位(LVR)功能和低电压监测(LVD)功能;内置在线仿真电路ICE(In-Circuit Emulator)接口;具有保密功能;具有看门狗功能。图2为SPCE061A内部结构图;图3为SPCE061A引脚图。


图2 SPCE061A内部结构图


图3 SPCE061A引脚图

监测端微处理器选用ATMEL公司的AT89S52单片机。AT89S52是一种低功耗、高性能的8位CMOS微控制器,具有8K 在系统可编程Flash 存储器,256字节RAM, 32 位I/O 口线,片内晶振及时钟电路,最高工作频率可达33MHZ;内部集成看门狗定时器,全双工UART串行口,6个中断源,3个16位定时器/计数器。图4为AT89S52单片机引脚及其最小系统图。


图4  AT89S52单片机引脚及其最小系统
        
2.2 温湿度模块

DHT11数字温湿度传感器,是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,具有很高的可靠性与稳定性。图5为DHT11应用电路。


图5 DHT11应用电路

DHT11采用单总线传输方式,供电电压为3V~5.5V。传感器上电后,要等待 1s 以越过不稳定状态。电源引脚(VDD,GND)之间可增加一个100nF 的电容,用以去耦滤波。

DATA引脚用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,当前小数部分用于以后扩展,现在读出均为零。本设计中将DHT11的DATA引脚连接AT89S52的P1.0脚。一次完整的数据传输为40bit,高位先出。数据格式:8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和。数据传送正确时校验和数据等于8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据所得结果的末8位。

2.3 无线模块

nRF24L01是一款工作在2.4~2.5 GHz世界通用ISM频段的单片无线收发器芯片,采用FSK调制,内部集成自己的协议,有自动应答、自动重发、地址及CRC检验功能,可实现点对点或1对6的无线通信,无线通信速度可达2 Mbps;电流消耗极低,当工作在发射模式下发射功率为-6 dBm时电流消耗为9 mA,接收模式下为12.3 mA。

nRF24L01有四种工作模式:收发模式、配置模式、空闲模式、关机模式。工作模式由PWR_UP register 、PRIM_RX register和CE决定。本设计中让NRF24L01工作于收发模式中的Enhanced ShockBurstTM收发模式下,这种工作模式下,系统的程序编制会更加简单,并且稳定性也会更高。

nRF24L01的所有配置工作都是通过SPI完成,共有30字节的配置字。

虽然nRF24L01模块工作于1.9~3.6V的低电压,但考虑到SPCE061A单片机及51单片机的IO口输出电流均较小,nRF24L01无线模块可以直接与其连接。图6为nRF24L01芯片及其外围电路。图7为nRF24L01与AT89S52引脚连接图。图8为nRF24L01与SPCE061A引脚连接图。


图6 nRF24L01芯片及其外围电路


图7 nRF24L01与AT89S52引脚连接图


图8 nRF24L01与SPCE061A引脚连接图
        
2.4 显示模块

系统显示模块采用带中文字库的12864液晶显示屏。12864主要由行驱动器/列驱动器及128x64全点阵液晶显示器组成。其显示分辨率为128×64, 内置8192个16*16点汉字,和128个16*8点ASCII字符集。该模块接口方式灵活,操作指令简单、方便,可以显示8×4行16×16点阵的汉字,也可完成图形显示,可构成全中文人机交互图形界面。低电压低功耗也是其又一显著特点。12864具有简单而功能较强的指令集,可实现字符移动、闪烁等显示功能,共有7条指令,单片机只需通过D/I、R/W、DB0~DB7送入数据或者指令便可显示其指定内容或显示方式。

本设计中,12864液晶屏采用并行通信方式与SPCE061A单片机进行数据通信。为了方便的操作12864液晶屏,我们将12864的4、5、6引脚与SPCE061A的IOB9、IOB8、IOB10引脚连接,并编写了能够直接操作SPCE061A单个IO口状态的函数,以方便操作12864显示屏而不影响其它IO口的数据通信。图9为12864液晶屏与SPCE061A的引脚连接图。


图9  12864液晶屏与SPCE061A的引脚连接图

2.5 键盘模块

SPCE061A开发板自身集成了三个按键K1、K2、K3,按键一端连接单片机的高电平,另一端分别连接了SPCE061A单片机的IOA0、IOA1、IOA2口。图10为SPCE061A开发板集成的三个按键电路图。其中按K1键进入调整报警温度模式,按K2键与K3键调整报警温度的上下限值。


图10  SPCE061A开发板按键电路图

2.6 继电器模块

当检测端检测到温度高于警戒值时,AT89S52单片机P1.1引脚输出高电平,通过继电器实现弱电控制强电,打开制冷空调,当温度低于警戒值时,AT89S52单片机P1.1引脚输出低电平,控制制冷空调停止运行。实现自动控制时要先把开关S1闭合,本系统将警戒值设置为35℃。图11为继电器自动控制电路图。


图11 继电器自动控制电路图

2.7 语音模块

凌阳的 SPCE061A 是 16 位单片机,具有很强的信息处理能力,最高时钟频率可达到

49MHz,具备运算速度高的优势,这些无疑为语音的播放、录放、合成及辨识提供了条件。 凌阳压缩算法中 SACM_A2000、SACM_S480 、SACM_S240 主要是用来放音,可用于语音提示,而 DVR 则用来录放音。SPCE061A单片机提供了相关API函数及程序代码范例,方便用C语言进行开发。本系统在编写软件时定义了SPCE061A相关寄存器的地址,通过调用相关定义即可方便进行操作。

软件设计时采用S480压缩算法将报警语音“有危险”进行压缩,用S480自动方式播放报警语音。该压缩算法压缩比为80:3,存储容量大,音质介于 A2000 和 S240 之间,适用于语音播放。图12为S480自动播放方式流程图


图12  S480自动播放方式流程图
        
3 系统软件设计流程

系统上电后,主控端软件初始化相关IO口,并初始化NRF24L01无线收发模块为接收模式,调用LCD字库初始化程序。希捷软件进入循环状态,读取RF24L01无线收发模块状态寄存器,判断是否接收到数据。如果接收到数据,将数据存储到预先定义的数组中,调用语音报警子函数,判断接收到的数据是否达到报警上下限,达到后液晶屏显示危险状态,并启用语音报警。没有危险时则只通过液晶屏显示当前温湿度数据及状态安全。

主控端软件执行完语音报警子函数后清除NRF24L01无线收发模块状态寄存器中断标志,清看门狗。判断报警温度调整键是否被按下,如果按下则调用报警温度调整子函数,调整完毕后进入循环模式,重复执行以上步骤。

监测端软件开始初始化相关IO口,并设置NRF24L01无线收发模块为发射模式,然后进入循环状态,开始调用温湿度采集子函数。采集完数据后,程序将数据放入NRF24L01无线收发模块的发射数据缓存器中。此时要检测温度数据是否超过设定的警戒值,如果超过警戒值则开启继电器,否则关闭继电器。下一步软件启动数据发射。发射完成后,读NRF24L01无线收发模块的状态寄存器并清除相关中断标志位,延时一段时间后再次进入循环采集发射状态,重复执行以上步骤。图13为主控端软件流程图,图14为监测端软件流程图。



3.1 主控端软件设计

3.1.1 主程序设计

void main()
{   
  Initial_IO();                //初始化IO口
  flag=0;                    //调温子程序标志位清0
  nRF24L01_Initial();          // NRF24L01初始化
  RX_Mode();                //设置NRF24L01为接收模式并开始接收数据
  initinal();                   //调用LCD字库初始化程序
  while(1)
    {
                sta=SPI_Read(STATUS);                   // 读取状态寄存器的值
                if(RX_DR)                                          // 如果接收到数据开启接收数据中断
                {        
                        SPI_RW_Reg(WRITE_REG+STATUS,sta);   //清除中断标志位
SPI_Read_Buf(RD_RX_PLOAD,Rx_Buffer,TX_PLOAD_WIDTH);   //从接收数据缓存器读取接收到的数据
                        baojing();                        //调用显示及报警子程序
                        *P_Watchdog_Clear=0x0001;        //清除看门狗
                }               
                SPI_RW_Reg(WRITE_REG+STATUS,sta);    //清除中断标志位
                *P_Watchdog_Clear=0x0001;               //清除看门狗
                if((*P_IOA_Data&0x0007)==0x0001)        //如果调温按键被按下
                {        
                        flag=1;                     //标志位置1
                        tiaowendu();                //调用调温子程序
                }
                delayms(10);                   //延时一段时间
        }
}

3.1.2 nRF24L01收发数据子程序

以下程序设置NRF24L01无线收发模块的工作方式,并开启数据接收

void RX_Mode(void)
{
        CE_Low;                  //CE=0;
        delay1us(1);
          SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
         SPI_Write_Buf(WRITE_REG + RX_ADDR_P1, TX_ADDRESS, TX_ADR_WIDTH);
          SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);       //开启自动应答
          SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);            
SPI_RW_Reg(WRITE_REG + RF_CH, 40);        // 选择无线频道40
          SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);
          SPI_RW_Reg(WRITE_REG + RX_PW_P1, TX_PLOAD_WIDTH);
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);  // 设置为数据接收模式,开启CRC检测等
          CE_High;              //CE = 1   设置CE引脚为高来开启模块的数据接收模式
    delay1us(1);
}

3.1.3 12864液晶屏显示子程序

void lcd_mesg(unsigned char *adder1)    //写满整屏!
{
        unsigned char i;
        TransferData(0x80,0); //设置图形显示存储器的地址
        delay(100);
        for(i=0;i<32;i++)

{

TransferData(*adder1,1);

adder1++;

}

TransferData(0x90,0); //设置图形显示存储器的地址

delay(100);

for(i=32;i<64;i++)

{

TransferData(*adder1,1);

adder1++;

}

}

void lcd_mesg1(unsigned char w_dizhi,unsigned char changdu,unsigned char *adder1)

//在任意位置写入要显示的任意长度的数据
{

unsigned char i;

TransferData(w_dizhi,0); //设置图形显示存储器的地址

delay(100);

for(i=0;i        {

TransferData(*adder1,1);

adder1++;

}

}

3.1.4 报警温度调整子程序

通过设置标志位,判断K1键被按下的次数。如果是第一次被按下,则可以通过K2、K3键调整报警温度上限;如果是第二次被按下,则可以通过K2、K3键调整报警温度下限;如果是第三次被按下,则调出报警温度调整子程序。

3.1.5 报警子程序

如果温度报警界限,主控端会在12864液晶屏上显示危险的字样,并进行“有危险”的语音提示。

SPCE061A以S480自动方式播放语音的程序如下:

void PlaySnd_Auto(unsigned int uiSndIndex,unsigned int uiDAC_Channel)

{

SACM_S480_Initial(1);        //初始化为自动播放方式

SACM_S480_Play(uiSndIndex,uiDAC_Channel,3); //播放

while((SACM_S480_Status() & 0x0001) != 0)

{        //判断播放状态,如还在播放则继续循环

SACM_S480_ServiceLoop();        //播放系统服务程序

*P_Watchdog_Clear=0x0001;

}

SACM_S480_Stop();        //停止播放

}
        
3.2 监测端软件设计

3.2.1 监测端主程序

void main(void)
{
        init_io();                // 初始化IO口
        TX_Mode();                // 设置NRF24L01无线收发模块为发射方式
        while(1)
        {
                RH();         //采集温湿度数据
                delay2(100);
                relay();   //控制继电器的状态
                tx_buf[0]=str[0];                           // 将检测到的数据保存到tx_buf[0]
                tx_buf[1]=str[1];                           // 将检测到的数据保存到tx_buf[1]        
                tx_buf[2]=str[2];                           // 将检测到的数据保存到tx_buf[2]        
                tx_buf[3]=str[3];                           // 将检测到的数据保存到tx_buf[3]        
                TX_Mode();                              //设置NRF24L01无线收发模块为发射方式并开始发射                        
sta=SPI_Read(STATUS);          // 调取状态寄存器的数值
                SPI_RW_Reg(WRITE_REG+STATUS,sta);   // 清除状态寄存器的中断标志位
                delay_ms(1000);
        }                                                         
}                        
        
3.2.2 Nrf24L01收发数据子程序

void TX_Mode(void)
{
        CE=0;
          SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);   
          SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
          SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); /
          SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);
          SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);
          SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a);
          SPI_RW_Reg(WRITE_REG + RF_CH, 40);        
          SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);
          SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);   
        CE=1;
}

3.2.3 温湿度检测子程序

void RH(void)
{
        dht_data=0;
        delay1(20);                    //主机拉低18ms
        dht_data=1;
        delay2(2);                   //总线由上拉电阻拉高 主机延时20us
        dht_data=1;                  //主机设为输入 判断从机响应信号
if(!dht_data)                    //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行
{
                U8FLAG=2;
while((!dht_data)&&U8FLAG++);   //判断从机是否发出 80us 的低电平响应信号是否结束
                U8FLAG=2;
                while((dht_data)&&U8FLAG++);
                COM();                   //开始进入数据接收状态
                U8RH_data_H_temp=U8comdata;
                COM();
                U8RH_data_L_temp=U8comdata;
                COM();
                U8T_data_H_temp=U8comdata;
                COM();
                U8T_data_L_temp=U8comdata;
                COM();
                U8checkdata_temp=U8comdata;
dht_data=1;                  //拉高为下一轮做好准备          U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);            //进行数据校验
                if(U8temp==U8checkdata_temp)
                {
                        U8RH_data_H=U8RH_data_H_temp;
                        U8RH_data_L=U8RH_data_L_temp;
                        U8T_data_H=U8T_data_H_temp;
                        U8T_data_L=U8T_data_L_temp;
                        U8checkdata=U8checkdata_temp;
                        str[0]=(U8T_data_H_temp/10)+0x30;
                        str[1]=(U8T_data_H_temp%10)+0x30;
                        str[2]=(U8RH_data_H_temp/10)+0x30;
                        str[3]=(U8RH_data_H_temp%10)+0x30;
                }
        }
}

3.2.4 继电器控制子程序

void relay()
{
        if(str[0]>0x03)
                relay_sta=0x01;             //打开继电器
else if(str[0]==0x03)
{
if(str[1]>0x05)
relay_sta=0x01;         //打开继电器
else
relay_sta=0x00;         //关闭继电器
}
else
relay_sta=0x00;           //关闭继电器
}

4 系统运行测试

按照以上方案设计出整个系统后上电运行,系统工作状态良好,能够满足生产生活中的要求,图15为系统整体运行情况,图16与图17为调整报警温度界面与系统报警界面。



5 结语

本系统使用处理速度快的16位单片机SPCE061A作为主控端核心,利用nRF24L01无线模块,设计完成了能够监控小型无人环境温湿度的人性化系统。经过测试,系统温湿度数据采集准确,nRF24L01模块传送数据稳定;当环境温度达到警戒值时,继电器闭合,可以模拟开启制冷空调的动作。本系统达到了预期设计目的,具有很高的实用价值。
本文地址:https://www.eechina.com/thread-150880-1-1.html     【打印本页】

本站部分文章为转载或网友发布,目的在于传递和分享信息,并不代表本网赞同其观点和对其真实性负责;文章版权归原作者及原出处所有,如涉及作品内容、版权和其它问题,我们将根据著作权人的要求,第一时间更正或删除。
您需要登录后才可以发表评论 登录 | 立即注册

厂商推荐

相关在线工具

相关视频

关于我们  -  服务条款  -  使用指南  -  站点地图  -  友情链接  -  联系我们
电子工程网 © 版权所有   京ICP备16069177号 | 京公网安备11010502021702
快速回复 返回顶部 返回列表