无线温度监测

摘要:通过使用DS18B20温度模块采集数据,将数据通过51单片机控制模块使用NRF24L01无线模块进行传输,在接收端通过液晶显示模块LCD1602显示温度模块传输的温度数据,本设计具有发射距离远,精度高的优点,能满足我们课程设计的要求。

关键词:温度模块DS18B20 无线模块NRF24L01 LCD1602

1、设计目的、要求及方案

1.1设计目的

在工业生产中, 温度是一个非常重要的指标。为了保证安全生产, 需要对温度进行采集与测量, 并根据采集到的数据控制输出。传统的数据传输方式是通过敷设有线的通信线路来传递数据信息(常见的有RS485总线结构等), 这种方式不仅施工麻烦、费用高, 而且出现故障时不易排查, 越来越不能满足现代工业快速发展的需求。而无线数据传输方式具有不用布线、实时性高、容易重新部署等优点, 非常适用于现代工业监控系统[1]。

在本系统中把温度传感器DS18B20所采集到的温度值送给单片机进行处理, 通过NRF2401无线模块实现远程无线传输,使用数码管或液晶屏显示所采集的温度。故设计本系统,既能准确的测量温度, 又能解决测量距离上的问题。

1.2设计要求

(1)实时获取被测对象温度,温度测量范围:-10℃ ~+45℃;

测量精度:±0.1℃。

(2)无线传输实时获取的温度值,传输距离≥10m 。

(3)实时显示接收到的温度值。

(4)基于单片机实现。

(5)电路制作时,必须有学号或姓名。

(6)能够切换信道,用数码管显示信道(0—5)。

1.3设计方案

1.3.1控制模块

采用宏晶科技有限公司的STC89C52作为主控芯片。此芯片内置ADC 和SPI 总线接口,且内部时钟不分频,达到1MPS 。而且价格适中,方便制作电路板及焊接工作,能达到设计要求的性能[1]。

1.3.2无线通信模块方案

由于NRF24L01是一款高速低功耗的无线通信模块,能传输上百米的距离,而且价格较便宜,采用SPI 总线通信模式电路简单,操作方便。符合设计要求,故采用NRF24L01无线射频模块进行通信

1.3.3温度传感方案

采用美国DALLAS 公司生产的DS18B20可组网数字温度传感器芯片,具有耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。经济,方便。线路简单,编程容易,考虑到电路的设计,成本,还有多点通信,采用DS18B20作为本系统的温度传感器[2]。

1.3.4显示模块方案

由于只需要显示温度,还有学号,故选择采用字符液晶LCD1602当作显示器较为合适,LCD1602是一款比较通用的字符液晶模块,能显示字符、数字等信息,且价格便宜,容易控制[2]。

1.3.5信道选择方案

直接使用按键接单片机的I/O口,进行信道的选择,通过数码管模块显示信道的序号。

1.3.6设计方案框图

综合以上几点设计方案,设计出方案框图如图1发送模块方案框图,图2接收模块方案框图

图1发送模块方案框图

图2接收模块方案框图

2. 基本原理

无线温度监控系统由发送模块和接收两大模块组成,其原理如下:

发送模块:温度传感器DS18B20将采集到的信号送到单片机控制模块存储,通过按键使控制模块将信号处理然后送到无线模块NRF24L01经行数据传输,数码管显示出所选择的通信信道。

接收模块:通过按键使无线模块NRF24L01接收到发送模块的数据,把数据送到51控制模块,控制模块将数据处理后通过LCD1602把温度显示出来,数码管显示出所选择的通信信道。

系统组成方框图如图3无线温度监测器系统组成方框图所示:

图3无线温度监测器系统组成方框图

3. 硬件电路设计

3.1 温度模块

温度模块设计分析:

根据DS18B20的设计原理,第1个引脚接GND ;第2个引脚接单片机的P2.2口;第2个引脚再串联一个4.7k 到VCC ;第3个引脚直接接VCC 。[3]

电路连接原理图如图4温度模块原理图所示

图4温度模块原理图

3.2 无线收发模块

无线收发模块NRF24L01的各引脚与单片机的P1口相连,电路连接原理图如图5无线模块收发原理图所示

图5无线模块收发原理图

无线收发模块NRF24L01引脚功能:

CSN(P1.0):芯片的片选线,CSN 为低电平芯片工作。

SCK(P1.4):芯片控制的时钟线(SPI 时钟)。

MISO(P1.3):芯片控制数据线(Master input slave output)。

MOSI(P1.1):芯片控制数据线(Master output slave input)。

IRQ(P1.2):中断信号。无线通信过程中MCU 主要是通过IRQ 与NRF24L01

进行通信。 的CONFIG 寄存器共同决定NRF24L01的状态。 CE(P1.5):芯片的模式控制线。在CSN 为低的情况下,CE 协同NRF24L01

3.3 液晶显示模块

液晶显示模块设计,数据口DB0-DB7连接单片机的P0口;RS 、R/W、E 这3条控制线分别接单片机的P2.3、P2.4和P2.5口。电阻R3用来调节背光的亮度。电路连接原理图如图6显示模块原理图所示

图6显示模块原理图

3.4系统原理图及PCB 图

发送端原理图如图7无线发送系统原理图所示:

图7无线发送系统原理图

接收端原理图如图8线接收系统原理图所示:

图8无线接收系统原理图

4、软件程序设计

4.1无线收发模块NRF24L01的编程

4.1.1NRF24L01编程的基本思路

(1) 置CSN 为低,使能芯片,配置芯片各个参数。配置参数在Power Down

状态中完成。

(2)如果是Tx 模式,填充Tx FIFO。

(3)配置完成以后,通过CE 与CONFIG 中的PWR_UP与PRIM_RX参数确定

NRF24L01要切换到的状态。

Tx Mode:PWR_UP=1;PRIM_RX=0; CE=1(保持超过10us 就可以) ; Rx Mode:PWR_UP=1;PRIM_RX=1; CE=1;

(4) IRQ引脚会在以下三种情况变低:

① Tx FIFO 发完并且收到ACK (使能ACK 情况下)

② Rx FIFO收到数据

③ 达到最大重发次数

4.1.2 Tx与Rx 的配置过程

Tx 模式初始化过程

(1)写Tx 节点的地址 TX_ADDR

(2)写Rx 节点的地址(主要是为了使能Auto Ack) RX_ADDR_P0

(3)使能AUTO ACK EN_AA

(4)使能PIPE 0 EN_RXADDR

(5)配置自动重发次数 SETUP_RETR

(6)选择通信频率 RF_CH

(7)配置发射参数(低噪放大器增益、发射功率、无线速率) RF_SETUP

(8)选择通道0有效数据宽度 Rx_Pw_P0

(9)配置24L01的基本参数以及切换工作模式 CONFIG。

4.1.3NRF24L01数据信道的切换

NRF24L01配置为接收模式时,可以接收6路不同地址相同频率的数据,每个数据通道拥有自己的地址,并且可以通过寄存器来进行分别配置。数据通道是通过寄存器EN_RXADDR来设置的默认状态下只有数据通道0和数据通道1是开启状态的每一个数据通道的地址是通过寄存RX_ADDR_Px来配置的,通常情况下不允许不同的数据通道设置完全相同的地址。数据通道0有40位可配置地址,数据通道1-5的地址:为32位共用地址+各自的地址(最低字节),1-5数据通道的最低位必须不同。

发送端通过按键把数据通道从0-5经行切换,选择不同的地址经行通信,接收端同样经行对应的处理以便通信。

发送端切换通道的程序:

接收端的选择程序

uchar code dizhi[]={0x01,0x02,0x04,0x08,0x10,0x20}; //接收通道和使能通道的切换

通过按键的选择,通道能从0到5进行切换,然后只有通道相同才可以传输数据,显示屏上才有数据更新。

4.2 DS18B20温度模块

温度模块读取温度程序流程图如图9读取温度程序流程图所示

图9读取温度程序流程图

程序见附录A

5、PCB 板的设计与制作:

5.1 PCB图设计

PCB 图如图10所示:

PCB 图的设计如图10 PCB图所示

图10 PCB图所示

6、电路的调试及调试结果

把PCB 板制作完毕之后,拿到元器件之后,开始进行焊接,对安装焊接工艺要求是:电阻,电容尽可能卧式安装,减少虚焊,脱焊现象,贴片元器件等需要快速焊接,避免元器件由于温度过高而损坏。

进行测试的时候发现LCD 没有显示数据,然后对LCD1602进行测试,没有问题;对照资料才发现数据口反过来接了,然后用杜邦线进行重新连接,测试通过了[3]。

接着排查无线模块,温度模块,进行资料的查询,发现DS18B20引脚接反了,然后把DS18B20调转插在底座上面。

无线模块也没有正常工作,是因为没有正常的供电,缺少AMS1117降压模块,然后手工焊接了一个降压模块,无线模块也正常工作了,然后进行整体测试,硬件测试通过。

接着就是程序测试,一开始是数据不能正确显示,有一些字符乱码,通过调试程序,优化LCD 显示,完成测试。[3]

由于设计要求需要进行信道的切换,一开始写了数组进行信道的选择,但是达不到所需要的效果,只能有通道0和1可以单独通信,其他通道无法进行通信。后来才知道信道的使能端也需要进行选择处理,才可以对数据进行单独处理。 因为一开始对无线模块的使能通道处理不妥当,发送端和接收端全打开(0x3f )处理, 所以进行通信的时候,只有0和1可以切换,其他通道时会出现错误,当接收端为0时,发送端每一个通道都可以传输数据,所以一直在找原因。最后才知道要在接收端进行使能端的选择,才能使通道单独选择,而不收其他通道的影响。

发送端原处理程序如下:

SPI_W_Reg(W_REGISTER+EN_AA,0x30);/*接收通道自动应答*/

SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x30);/*使能接收通道*/

修改后把0x30改为0x3f, 把通道使能全打开,程序如下:

SPI_W_Reg(W_REGISTER+EN_AA,0x3f);/*接收全通道自动应答*/

SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x3f);/*使能接收权通道*/

接收端的使能端进行按键选择,原程序如下:

SPI_W_Reg(W_REGISTER+EN_AA,0x3f);

SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x3f);

调试之后程序为:

uchar code dizhi[]={0x01,0x02,0x04,0x08,0x10,0x20}; [3]

SPI_W_Reg(W_REGISTER+EN_AA,dizhi[xuan]);

SPI_W_Reg(W_REGISTER+EN_RX_ADDR,dizhi[xuan]);

7、实验总结及心得体会

这次课程设计一共做了几个PCB 才成功,由于第一个缺陷太多,所以重新修改原理图及PCB ,制作第二个PCB 板,把元器件拆卸下来重新焊接到第二板子上,出现了不少错误,后来在切换信道的功能上,又进行了第三个板子制作,终于调通了。所以在刚动手之前就要想清楚原理图,最好进行仿真,以免出现过多的错误,导致损坏元器件。

在实验过程中,通过选取元件、确定电路形式、以及计算等等,同时通过调试来发现自己的错误并分析及排除这些故障。

焊接电路板更要注意,要先检查所有的元件是否可用,焊接二极管电接电容时应分清正负极焊接时要注意防止虚焊,电容电感尽量卧式安装,焊接完成后尽量缩短元件引线,但不用剪太短,否则不容易更改。

参考文献

[1] 付聪,付慧生,李益青. 基于NRF24L01无线温度采集控制系统的设计[J].工业自动化.2010年1月,第一期:73-74

[2] 王振,胡清,黄杰. 基于NRF24L01无线温度采集系统设计[J].电子设计工程.2009年12月,第十二期第17卷:24-25

[3] 郭天祥著. 51单片机C 语言教程[M].北京:电子工业出版社.2012年: 148-156, 342-354

附录A

无线温度发送模块程序代码:

#include

#include

#define uint unsigned int

#define uchar unsigned char

#define TX_ADDR_WITDH 5//发送地址宽度设置为5个字节

#define RX_ADDR_WITDH 5

#define TX_DATA_WITDH 5

#define RX_DATA_WITDH 5

/****************************************************************** // nRF24L01指令格式:

*******************************************************************/ #define R_REGISTER 0x00 // 读寄存器

#define W_REGISTER 0x20 // 写寄存器

#define R_RX_PLOAD 0x61 // 读RX FIFO有效数据,1-32字节,当读数据完成后,数据被清除,应用于接收模式

#define W_TX_PLOAD 0xA0 // 写TX FIFO 有效数据,1-32字节,写操作从字节0开始,应用于发射模式

#define FLUSH_TX 0xE1 // 清除TX FIFO寄存器,应用于发射模式

#define FLUSH_RX 0xE2 // 清除RX FIFO寄存器,应用于接收模式

#define REUSE_TX_PL 0xE3 // 重新使用上一包有效数据,当CE 为高过程中,数据包被不断的重新发射

#define NOP 0xFF // 空操作,可以用来读状态寄存器

/****************************************************************** // nRF24L01寄存器地址

*******************************************************************/ #define CONFIG 0x00 // 配置寄存器

#define EN_AA 0x01 // “自动应答”功能寄存

#define EN_RX_ADDR 0x02 // 接收通道使能寄存器

#define SETUP_AW 0x03 // 地址宽度设置寄存器

#define SETUP_RETR 0x04 // 自动重发设置寄存器

#define RF_CH 0x05 // 射频通道频率设置寄存器

#define RF_SETUP 0x06 // 射频设置寄存器

#define STATUS 0x07 // 状态寄存器

#define OBSERVE_TX 0x08 // 发送检测寄存器

#define CD 0x09 // 载波检测寄存器

#define RX_ADDR_P0 0x0A // 数据通道0接收地址寄存器

#define RX_ADDR_P1 0x0B // 数据通道1接收地址寄存器

#define RX_ADDR_P2 0x0C // 数据通道2接收地址寄存器

#define RX_ADDR_P3 0x0D // 数据通道3接收地址寄存器

#define RX_ADDR_P4 0x0E // 数据通道4接收地址寄存器

#define RX_ADDR_P5 0x0F // 数据通道5接收地址寄存器

#define TX_ADDR 0x10 // 发送地址寄存器

#define RX_PW_P0 0x11 // 数据通道0有效数据宽度设置寄存器

#define RX_PW_P1 0x12 // 数据通道1有效数据宽度设置寄存器

#define RX_PW_P2 0x13 // 数据通道2有效数据宽度设置寄存器

#define RX_PW_P3 0x14 // 数据通道3有效数据宽度设置寄存器

#define RX_PW_P4 0x15 // 数据通道4有效数据宽度设置寄存器

#define RX_PW_P5 0x16 // 数据通道5有效数据宽度设置寄存器

#define FIFO_STATUS 0x17 // FIFO状态寄存器

//*********************************************************************************

uchar sta; // 状态变量

#define RX_DR (sta & 0x40) // 接收成功中断标志

#define TX_DS (sta & 0x20) // 发射成功中断标志

#define MAX_RT (sta & 0x10) // 重发溢出中断标志

sbit CE=P1^5;

sbit IRQ=P1^2;

sbit CSN=P1^0;

sbit MOSI=P1^1;

sbit MISO=P1^3;

sbit SCK=P1^4;

sbit DQ=P2^2;

sbit key=P2^6;

uchar code TX_Addr[]={0x34,0x43,0x10,0x10,0x01};

uchar code TX_Addr1[]={0x33,0x42,0x11,0x11,0x21}; //++++++++

uchar code TX_Addr2[]={0xb1,0x42,0x11,0x11,0x21};

uchar code TX_Addr3[]={0xb2,0x42,0x11,0x11,0x21};

uchar code TX_Addr4[]={0xb3,0x42,0x11,0x11,0x21};

uchar code TX_Addr5[]={0xb4,0x42,0x11,0x11,0x21};

uchar code shuma[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92};

uchar counter=0;

uchar RX_Buffer[RX_DATA_WITDH];

uchar Temp_Value[]={0x00,0x00};

uchar Temp=0;

uchar Display_Digit[]={0,0,0,0};

bit DS18B20_IS_OK=1;

uchar code df_tab[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};//decimal fraction

void _delay_tus(uint x)

{

while(--x);

}

void _delay_us(uint x)

{

uint i,j;

for (j=0;j

for (i=0;i

}

void _delay_ms(uint x)

{

uint i,j;

for (j=0;j

for (i=0;i

}

/**************************************************/

/*函数功能:DS18B20初始化 */

/*入口参数:无 */

/*出口函数:status */

/**************************************************/

uchar DS18B20_Init(void)

{

uchar status;

DQ=1;

_delay_tus(10);

DQ=0;

_delay_tus(90);

DQ=1;

_delay_tus(8);

status=DQ;

_delay_tus(100);

DQ=1;

return status;

}

/**************************************************/

/*函数功能:从DS18B20读取一字节 */

/*入口参数:无 */

/*出口函数:dat(返回读取到数据) */

/**************************************************/

uchar Read_One_Byte(void)

{

uchar i,dat=0;

DQ=1;

_nop_();

for(i=8;i>0;i--)

{

DQ=0;

dat>>=1;

DQ=1;

_nop_();_nop_();

if(DQ)

dat|=0x80;

_delay_tus(30);

DQ=1;

}

return dat;

}

/**************************************************/

/*函数功能:向DS18B20写一字节 */

/*入口参数:dat(把dat 写入DS18B20) */

/*出口函数:无 */

/**************************************************/

void Write_One_Byte(uchar dat)

{

uchar i;

for(i=8;i>0;i--)

{

DQ=0;

DQ=dat&0x01;

_delay_tus(5);

DQ=1;

dat>>=1;

}

}

/**************************************************/

/*函数功能:从DS18B20读取数据(数据) */

/*入口参数:无 */

/*出口函数:无 */

/**************************************************/

void Read_Temp(void)

{

uchar ng=0;

if(DS18B20_Init()==1)

DS18B20_IS_OK=0;

else

{

Write_One_Byte(0xcc);

Write_One_Byte(0x44);

DS18B20_Init();

Write_One_Byte(0xcc);

Write_One_Byte(0xbe);

Temp_Value[0]=Read_One_Byte();

Temp_Value[1]=Read_One_Byte();

DS18B20_IS_OK=1;

}

if((Temp_Value[1]&0xf8)==0xf8)

{

Temp_Value[1]=~Temp_Value[1];

Temp_Value[0]=~Temp_Value[0]+1;

if(Temp_Value[0]==0x00)

Temp_Value[1]++;

ng=1;

}

Display_Digit[0]=df_tab[Temp_Value[0]&0x0f];

Temp=((Temp_Value[0]&0xf0)>>4)|((Temp_Value[1]&0x07)

Display_Digit[3]=Temp/100;

Display_Digit[2]=Temp%100/10;

Display_Digit[1]=Temp%10;

}

/*nRF24L01初始化*/

void nRF24L01_Init(void)

{

_delay_us(2000);

CE=0;//待机模式Ⅰ

CSN=1;

SCK=0;

IRQ=1;

}

/*SPI时序函数*/

uchar SPI_RW(uchar byte)

{

uchar i;

for(i=0;i

{

if(byte&0x80)//如果数据最高位是1//当访问多字节寄存器时首先要读/写的是最低字节的高位?

MOSI=1;//向NRF24L01写1

else //否则写0

MOSI=0;

byte

SCK=1;//SCK拉高,写入一位数据,同时读取一位数据

if(MISO)

byte|=0x01;

SCK=0;//SCK拉低

}

return byte;//返回读取一字节

}

/*SPI写寄存器一字节函数*/

/*reg:寄存器地址*/

/*value:一字节(值)*/

uchar SPI_W_Reg(uchar reg,uchar value)

{

uchar status;//返回状态

CSN=0;//SPI片选

status=SPI_RW(reg);//写入寄存器地址,同时读取状态

SPI_RW(value);//写入一字节

CSN=1;//

return status;//返回状态

}

/*SPI*/

uchar SPI_R_byte(uchar reg)

{

uchar reg_value;

CSN=0;//SPI片选

SPI_RW(reg);//写入地址

reg_value=SPI_RW(0);//读取寄存器的值

CSN=1;

return reg_value;//返回读取的值

}

/*SPI读取RXFIFO 寄存器数据*/

/*reg:寄存器地址*/

/**Dat_Buffer:用来存读取的数据*/

/*DLen:数据长度*/

uchar SPI_R_DBuffer(uchar reg,uchar *Dat_Buffer,uchar Dlen)

{

uchar status,i;

CSN=0;//SPI片选

status=SPI_RW(reg);//写入寄存器地址,同时状态

for(i=0;i

{

Dat_Buffer[i]=SPI_RW(0);//存储数据

}

CSN=1;

return status;

}

/*SPI向TXFIFO 寄存器写入数据*/

/*reg:写入寄存器地址*/

/*TX_Dat_Buffer:存放需要发送的数据*/

/*Dlen:数据长度*/

uchar SPI_W_DBuffer(uchar reg,uchar *TX_Dat_Buffer,uchar Dlen)

{

uchar status,i;

CSN=0;//SPI片选,启动时序

status=SPI_RW(reg);

for(i=0;i

{

SPI_RW(TX_Dat_Buffer[i]);//发送数据

}

CSN=1;

return status;

}

/*设置发送模式*/

void nRF24L01_Set_TX_Mode(uchar *TX_Data)

{

CE=0;//待机(写寄存器之前一定要进入待机模式或掉电模式)

CSN=0;

SPI_RW(FLUSH_TX);

CSN=1;

/*信道的选择, 按键切换*/

if(key==0)

{

_delay_ms(20);

if(key==0)

{

P0=shuma[counter];

_delay_ms(50);

switch(counter)

{

case 0 :

SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr,TX_ADDR_WITDH);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P0,TX_Addr,TX_ADDR_WITDH);

break;

case 1 :

SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr1,TX_ADDR_WITDH);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P1,TX_Addr1,TX_ADDR_WITDH);

break;

case 2 :

SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr2,TX_ADDR_WITDH);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P2,TX_Addr2,TX_ADDR_WITDH);

break;

case 3 :

SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr3,TX_ADDR_WITDH);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P3,TX_Addr3,TX_ADDR_WITDH);

break;

case 4 :

SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr4,TX_ADDR_WITDH);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P4,TX_Addr4,TX_ADDR_WITDH);

break;

case 5 :

SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr5,TX_ADDR_WITDH);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P5,TX_Addr5,TX_ADDR_WITDH);

break;

}

counter++;

if(counter==6)

counter=0;

}

}

SPI_W_DBuffer(W_TX_PLOAD,TX_Data,TX_DATA_WITDH);/*写有效数据地址+有效数据+有效数据宽度*/

SPI_W_Reg(W_REGISTER+EN_AA,0x3f);/*接收全通道自动应答*/

SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x3f);/*使能接收全通道*/

SPI_W_Reg(W_REGISTER+SETUP_RETR,0x0a);/*自动重发延时250US+86US,重发10次*/ SPI_W_Reg(W_REGISTER+RF_CH,0x27);/*(2400+39)MHZ选择射频通道0X27*/

SPI_W_Reg(W_REGISTER+RF_SETUP,0x07);/*1Mbps速率, 发射功率:0DBM,低噪声放大器增益*/

SPI_W_Reg(W_REGISTER+CONFIG,0x0e);/*发送模式, 上电,16位CRC 校验,CRC 使能*/ CE=1;//启动发射

_delay_ms(5);/*CE高电平持续时间最少10US 以上*/

}

uchar Check_Rec(void)

{

uchar status;

sta=SPI_R_byte(R_REGISTER+STATUS);

if(RX_DR)

{

CE=0;

SPI_R_DBuffer(R_RX_PLOAD,RX_Buffer,RX_DATA_WITDH);

status=1;

}

SPI_W_Reg(W_REGISTER+STATUS,0xff);

return status;

}

/*检测应答信号*/

uchar Check_Ack(void)

{

sta=SPI_R_byte(R_REGISTER+STATUS);/*读取寄存状态*/

if(TX_DS||MAX_RT)/*如果TX_DS或MAX_RT为1, 则清除中断和清除TX_FIFO寄存器的值*/

{

SPI_W_Reg(W_REGISTER+STATUS,0xff);

CSN=0;

SPI_RW(FLUSH_TX);

CSN=1;

return 0;

}

else

return 1;

}

void main(void)

{

uchar i;

P0=0xff;

P1=0xff;

P2=0xff;

P3=0xff;

nRF24L01_Init();

Read_Temp();

_delay_ms(1000);

while(1)

{

Read_Temp();

if(DS18B20_IS_OK)

{

for(i=0;i

nRF24L01_Set_TX_Mode(&Display_Digit[i]);

_delay_ms(100);

while(Check_Ack());

}

}

}

}

无线温度接收模块程序代码:

#include

#include

#define uint unsigned int

#define uchar unsigned char

#define TX_ADDR_WITDH 5//发送地址宽度设置为5个字节

#define RX_ADDR_WITDH 5

#define TX_DATA_WITDH 5

#define RX_DATA_WITDH 5

/******************************************************************

// nRF24L01指令格式:

*******************************************************************/

#define R_REGISTER 0x00 // 读寄存器

#define W_REGISTER 0x20 // 写寄存器

#define R_RX_PLOAD 0x61 // 读RX FIFO有效数据,1-32字节,当读数据完成后,数据被清除,应用于接收模式

#define W_TX_PLOAD 0xA0 // 写TX FIFO 有效数据,1-32字节,写操作从字节0开始,应用于发射模式

#define FLUSH_TX 0xE1 // 清除TX FIFO寄存器,应用于发射模式

#define FLUSH_RX 0xE2 // 清除RX FIFO寄存器,应用于接收模式

#define REUSE_TX_PL 0xE3 // 重新使用上一包有效数据,当CE 为高过程中,数据包被不断的重新发射

#define NOP 0xFF // 空操作,可以用来读状态寄存器

/******************************************************************

// nRF24L01寄存器地址

*******************************************************************/

#define CONFIG 0x00 // 配置寄存器

#define EN_AA 0x01 // “自动应答”功能寄存器

#define EN_RX_ADDR 0x02 // 接收通道使能寄存器

#define SETUP_AW 0x03 // 地址宽度设置寄存器

#define SETUP_RETR 0x04 // 自动重发设置寄存器

#define RF_CH 0x05 // 射频通道频率设置寄存器

#define RF_SETUP 0x06 // 射频设置寄存器

#define STATUS 0x07 // 状态寄存器

#define OBSERVE_TX 0x08 // 发送检测寄存器

#define CD 0x09 // 载波检测寄存器

#define RX_ADDR_P0 0x0A // 数据通道0接收地址寄存器

#define RX_ADDR_P1 0x0B // 数据通道1接收地址寄存器

#define RX_ADDR_P2 0x0C // 数据通道2接收地址寄存器

#define RX_ADDR_P3 0x0D // 数据通道3接收地址寄存器

#define RX_ADDR_P4 0x0E // 数据通道4接收地址寄存器

#define RX_ADDR_P5 0x0F // 数据通道5接收地址寄存器

#define TX_ADDR 0x10 // 发送地址寄存器

#define RX_PW_P0 0x11 // 数据通道0有效数据宽度设置寄存器

#define RX_PW_P1 0x12 // 数据通道1有效数据宽度设置寄存器

#define RX_PW_P2 0x13 // 数据通道2有效数据宽度设置寄存器

#define RX_PW_P3 0x14 // 数据通道3有效数据宽度设置寄存器

#define RX_PW_P4 0x15 // 数据通道4有效数据宽度设置寄存器

#define RX_PW_P5 0x16 // 数据通道5有效数据宽度设置寄存器

#define FIFO_STATUS 0x17 // FIFO状态寄存器

//*********************************************************************************

uchar sta; // 状态变量

#define RX_DR (sta & 0x40) // 接收成功中断标志

#define TX_DS (sta & 0x20) // 发射成功中断标志

#define MAX_RT (sta & 0x10) // 重发溢出中断标志

sbit CE=P1^5;

sbit IRQ=P1^2;

sbit CSN=P1^0;

sbit MOSI=P1^1;

sbit MISO=P1^3;

sbit SCK=P1^4;

sbit key1=P1^6;

sbit key2=P1^7;

sbit deng=P2^0;

sbit LCD_RS=P2^3;

sbit LCD_RW=P2^4;

sbit LCD_EN=P2^5;

uchar code TX_Addr[]={0x34,0x43,0x10,0x10,0x01};

uchar code TX_Addr1[]={0x33,0x42,0x11,0x11,0x21}; //++++++++

uchar code TX_Addr2[]={0xb1};

uchar code TX_Addr3[]={0xb2};

uchar code TX_Addr4[]={0xb3};

uchar code TX_Addr5[]={0xb4};

uchar code dizhi[]={0x01,0x02,0x04,0x08,0x10,0x20}; //+++++++

uchar code shuma[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92};//++++++

uchar code TX_Buffer[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

uchar RX_Buffer[RX_DATA_WITDH];

uchar code Display_LINE0[]={"ID:110709 06/14 "};

uchar Display_LINE1[]={" TEMP: "};

uchar counter=0;

uchar xuan=0;

void _delay_us(uint x)

{

uint i,j;

for (j=0;j

for (i=0;i

}

void _delay_ms(uint x)

{

uint i,j;

for (j=0;j

for (i=0;i

}

bit LCD_Busy(void)//测忙

{

bit LCD_Status;//返回值变量

LCD_RS=0;//读取状态

LCD_RW=1;

LCD_EN=1;

_nop_();_nop_();_nop_();_nop_();

LCD_Status=(bit)(P0&0x80);

LCD_EN=0;

return LCD_Status;

}

void LCD_Write_Command(uchar cmd)//写指令

{

LCD_RS=0;

LCD_RW=0;

LCD_EN=0;

_nop_();_nop_();

P0=cmd;

_nop_();_nop_();_nop_();_nop_();

LCD_EN=1;

_nop_();_nop_();_nop_();_nop_();

LCD_EN=0;

}

void LCD_Write_Data(uchar dat)//写数据

{

//每次写数据操作之前均需要检测忙信号

LCD_RS=1;

LCD_RW=0;

LCD_EN=0;

P0=dat;

_nop_();_nop_();_nop_();_nop_();

LCD_EN=1;

_nop_();_nop_();_nop_();_nop_();

LCD_EN=0;

}

void Init_LCD(void)//液晶初始化

{

_delay_ms(15);//延时15MS

LCD_Write_Command(0x38);

_delay_ms(5);

LCD_Write_Command(0x38);

_delay_ms(5);

LCD_Write_Command(0x38);//以后每次写指令操作之前均需要检测忙信号 _delay_ms(5);

LCD_Write_Command(0x01);//清屏

_delay_ms(5);

LCD_Write_Command(0x38);//设置16*2显示,5*7点阵,8位数据接口 _delay_ms(5);

LCD_Write_Command(0x0c);//开显示, 不显示光标

_delay_ms(5);

LCD_Write_Command(0x06);//当读或写一个字符后地址指针加一, 且光标加一 }

void LCD_POS(uchar pos)//字符显示位置

{

LCD_Write_Command(0x80|pos);

}

void Show_String(uchar *str)//显示字符串

{

while(*str!='\0')

LCD_Write_Data(*str++);

}

void nRF24L01_Init(void)

{

_delay_us(2000);

CE=0;

CSN=1;

SCK=0;

IRQ=1;

}

uchar SPI_RW(uchar byte)

{

uchar i;

for(i=0;i

{

if(byte&0x80)

MOSI=1;

else

byte

SCK=1;

if(MISO)

byte|=0x01;

SCK=0;

}

return byte;

}

uchar SPI_W_Reg(uchar reg,uchar value)

{

uchar status;

CSN=0;

status=SPI_RW(reg);

SPI_RW(value);

CSN=1;

return status;

}

uchar SPI_R_byte(uchar reg)

{

uchar status;

CSN=0;

SPI_RW(reg);

status=SPI_RW(0);

CSN=1;

return status;

}

uchar SPI_R_DBuffer(uchar reg,uchar *Dat_Buffer,uchar Dlen)

{

uchar reg_value,i;

CSN=0;

reg_value=SPI_RW(reg);

for(i=0;i

{

Dat_Buffer[i]=SPI_RW(0);

}

CSN=1;

return reg_value;

}

uchar SPI_W_DBuffer(uchar reg,uchar *TX_Dat_Buffer,uchar Dlen)

{

uchar reg_value,i;

reg_value=SPI_RW(reg);

for(i=0;i

{

SPI_RW(TX_Dat_Buffer[i]);

}

CSN=1;

return reg_value;

}

void nRF24L01_Set_RX_Mode(void)

{

CE=0;//待机

/*信道的选择, 按键切换*/

if(key1==0)

{

_delay_ms(20);

if(key1==0)

{

switch(counter)

{

case 0 : P3=shuma[counter];

_delay_ms(1000);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P0,TX_Addr,TX_ADDR_WITDH);

SPI_W_Reg(W_REGISTER+RX_PW_P0,RX_DATA_WITDH); break;

case 1 : P3=shuma[counter];

_delay_ms(1000);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P1,TX_Addr1,TX_ADDR_WITDH);

SPI_W_Reg(W_REGISTER+RX_PW_P1,RX_DATA_WITDH); break;

case 2 : P3=shuma[counter];

_delay_ms(1000);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P2,TX_Addr2,1); SPI_W_Reg(W_REGISTER+RX_PW_P2,RX_DATA_WITDH); break;

case 3 : P3=shuma[counter];

_delay_ms(1000);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P3,TX_Addr3,1); SPI_W_Reg(W_REGISTER+RX_PW_P3,RX_DATA_WITDH); break;

case 4 : P3=shuma[counter];

_delay_ms(1000);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P4,TX_Addr4,1); SPI_W_Reg(W_REGISTER+RX_PW_P4,RX_DATA_WITDH); break;

case 5 : P3=shuma[counter];

_delay_ms(1000);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P5,TX_Addr5,1); SPI_W_Reg(W_REGISTER+RX_PW_P5,RX_DATA_WITDH); break;

}

counter++;

if(counter==6)

counter=0;

}

}

if(key2==0)

{

_delay_ms(20);

if(key2==0)

{

deng=~deng;

_delay_ms(1000);

xuan++;

}

}

SPI_W_Reg(W_REGISTER+EN_AA,dizhi[xuan]);

SPI_W_Reg(W_REGISTER+EN_RX_ADDR,dizhi[xuan]);

SPI_W_Reg(W_REGISTER+RF_CH,0x27);

SPI_W_Reg(W_REGISTER+RF_SETUP,0x07);

SPI_W_Reg(W_REGISTER+CONFIG,0x0f);

CE=1;

_delay_ms(5);

if(xuan==6)

xuan=0;

}

uchar nRF24L01_RX_Data(void)

{

sta=SPI_R_byte(R_REGISTER+STATUS);

if(RX_DR)

{

CE=0;

SPI_R_DBuffer(R_RX_PLOAD,RX_Buffer,RX_DATA_WITDH);

SPI_W_Reg(W_REGISTER+STATUS,0xff);

CSN=0;

SPI_RW(FLUSH_RX);

CSN=1;

return 1;

}

else

return 0;

}

void main(void)

{

uchar i,RX_Temp_Value[RX_DATA_WITDH]; P0=0xff;

P1=0xff;

P2=0xff;

P3=0xff;

Init_LCD();

nRF24L01_Init();

_delay_us(1000);

LCD_POS(0);

Show_String(Display_LINE0);

while(1)

{

nRF24L01_Set_RX_Mode();

if(nRF24L01_RX_Data())

{

for(i=0;i

RX_Temp_Value[i]=RX_Buffer[i]; }

}

Display_LINE1[7]=RX_Temp_Value[3]+'0'; Display_LINE1[8]=RX_Temp_Value[2]+'0'; Display_LINE1[9]=RX_Temp_Value[1]+'0'; Display_LINE1[10]='.';

Display_LINE1[11]=RX_Temp_Value[0]+'0'; Display_LINE1[12]=0xdf;

Display_LINE1[13]=0x43;

if(RX_Temp_Value[3]==0)

Display_LINE1[7]=' ';

LCD_POS(0x40);

Show_String(Display_LINE1);

}

}

摘要:通过使用DS18B20温度模块采集数据,将数据通过51单片机控制模块使用NRF24L01无线模块进行传输,在接收端通过液晶显示模块LCD1602显示温度模块传输的温度数据,本设计具有发射距离远,精度高的优点,能满足我们课程设计的要求。

关键词:温度模块DS18B20 无线模块NRF24L01 LCD1602

1、设计目的、要求及方案

1.1设计目的

在工业生产中, 温度是一个非常重要的指标。为了保证安全生产, 需要对温度进行采集与测量, 并根据采集到的数据控制输出。传统的数据传输方式是通过敷设有线的通信线路来传递数据信息(常见的有RS485总线结构等), 这种方式不仅施工麻烦、费用高, 而且出现故障时不易排查, 越来越不能满足现代工业快速发展的需求。而无线数据传输方式具有不用布线、实时性高、容易重新部署等优点, 非常适用于现代工业监控系统[1]。

在本系统中把温度传感器DS18B20所采集到的温度值送给单片机进行处理, 通过NRF2401无线模块实现远程无线传输,使用数码管或液晶屏显示所采集的温度。故设计本系统,既能准确的测量温度, 又能解决测量距离上的问题。

1.2设计要求

(1)实时获取被测对象温度,温度测量范围:-10℃ ~+45℃;

测量精度:±0.1℃。

(2)无线传输实时获取的温度值,传输距离≥10m 。

(3)实时显示接收到的温度值。

(4)基于单片机实现。

(5)电路制作时,必须有学号或姓名。

(6)能够切换信道,用数码管显示信道(0—5)。

1.3设计方案

1.3.1控制模块

采用宏晶科技有限公司的STC89C52作为主控芯片。此芯片内置ADC 和SPI 总线接口,且内部时钟不分频,达到1MPS 。而且价格适中,方便制作电路板及焊接工作,能达到设计要求的性能[1]。

1.3.2无线通信模块方案

由于NRF24L01是一款高速低功耗的无线通信模块,能传输上百米的距离,而且价格较便宜,采用SPI 总线通信模式电路简单,操作方便。符合设计要求,故采用NRF24L01无线射频模块进行通信

1.3.3温度传感方案

采用美国DALLAS 公司生产的DS18B20可组网数字温度传感器芯片,具有耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。经济,方便。线路简单,编程容易,考虑到电路的设计,成本,还有多点通信,采用DS18B20作为本系统的温度传感器[2]。

1.3.4显示模块方案

由于只需要显示温度,还有学号,故选择采用字符液晶LCD1602当作显示器较为合适,LCD1602是一款比较通用的字符液晶模块,能显示字符、数字等信息,且价格便宜,容易控制[2]。

1.3.5信道选择方案

直接使用按键接单片机的I/O口,进行信道的选择,通过数码管模块显示信道的序号。

1.3.6设计方案框图

综合以上几点设计方案,设计出方案框图如图1发送模块方案框图,图2接收模块方案框图

图1发送模块方案框图

图2接收模块方案框图

2. 基本原理

无线温度监控系统由发送模块和接收两大模块组成,其原理如下:

发送模块:温度传感器DS18B20将采集到的信号送到单片机控制模块存储,通过按键使控制模块将信号处理然后送到无线模块NRF24L01经行数据传输,数码管显示出所选择的通信信道。

接收模块:通过按键使无线模块NRF24L01接收到发送模块的数据,把数据送到51控制模块,控制模块将数据处理后通过LCD1602把温度显示出来,数码管显示出所选择的通信信道。

系统组成方框图如图3无线温度监测器系统组成方框图所示:

图3无线温度监测器系统组成方框图

3. 硬件电路设计

3.1 温度模块

温度模块设计分析:

根据DS18B20的设计原理,第1个引脚接GND ;第2个引脚接单片机的P2.2口;第2个引脚再串联一个4.7k 到VCC ;第3个引脚直接接VCC 。[3]

电路连接原理图如图4温度模块原理图所示

图4温度模块原理图

3.2 无线收发模块

无线收发模块NRF24L01的各引脚与单片机的P1口相连,电路连接原理图如图5无线模块收发原理图所示

图5无线模块收发原理图

无线收发模块NRF24L01引脚功能:

CSN(P1.0):芯片的片选线,CSN 为低电平芯片工作。

SCK(P1.4):芯片控制的时钟线(SPI 时钟)。

MISO(P1.3):芯片控制数据线(Master input slave output)。

MOSI(P1.1):芯片控制数据线(Master output slave input)。

IRQ(P1.2):中断信号。无线通信过程中MCU 主要是通过IRQ 与NRF24L01

进行通信。 的CONFIG 寄存器共同决定NRF24L01的状态。 CE(P1.5):芯片的模式控制线。在CSN 为低的情况下,CE 协同NRF24L01

3.3 液晶显示模块

液晶显示模块设计,数据口DB0-DB7连接单片机的P0口;RS 、R/W、E 这3条控制线分别接单片机的P2.3、P2.4和P2.5口。电阻R3用来调节背光的亮度。电路连接原理图如图6显示模块原理图所示

图6显示模块原理图

3.4系统原理图及PCB 图

发送端原理图如图7无线发送系统原理图所示:

图7无线发送系统原理图

接收端原理图如图8线接收系统原理图所示:

图8无线接收系统原理图

4、软件程序设计

4.1无线收发模块NRF24L01的编程

4.1.1NRF24L01编程的基本思路

(1) 置CSN 为低,使能芯片,配置芯片各个参数。配置参数在Power Down

状态中完成。

(2)如果是Tx 模式,填充Tx FIFO。

(3)配置完成以后,通过CE 与CONFIG 中的PWR_UP与PRIM_RX参数确定

NRF24L01要切换到的状态。

Tx Mode:PWR_UP=1;PRIM_RX=0; CE=1(保持超过10us 就可以) ; Rx Mode:PWR_UP=1;PRIM_RX=1; CE=1;

(4) IRQ引脚会在以下三种情况变低:

① Tx FIFO 发完并且收到ACK (使能ACK 情况下)

② Rx FIFO收到数据

③ 达到最大重发次数

4.1.2 Tx与Rx 的配置过程

Tx 模式初始化过程

(1)写Tx 节点的地址 TX_ADDR

(2)写Rx 节点的地址(主要是为了使能Auto Ack) RX_ADDR_P0

(3)使能AUTO ACK EN_AA

(4)使能PIPE 0 EN_RXADDR

(5)配置自动重发次数 SETUP_RETR

(6)选择通信频率 RF_CH

(7)配置发射参数(低噪放大器增益、发射功率、无线速率) RF_SETUP

(8)选择通道0有效数据宽度 Rx_Pw_P0

(9)配置24L01的基本参数以及切换工作模式 CONFIG。

4.1.3NRF24L01数据信道的切换

NRF24L01配置为接收模式时,可以接收6路不同地址相同频率的数据,每个数据通道拥有自己的地址,并且可以通过寄存器来进行分别配置。数据通道是通过寄存器EN_RXADDR来设置的默认状态下只有数据通道0和数据通道1是开启状态的每一个数据通道的地址是通过寄存RX_ADDR_Px来配置的,通常情况下不允许不同的数据通道设置完全相同的地址。数据通道0有40位可配置地址,数据通道1-5的地址:为32位共用地址+各自的地址(最低字节),1-5数据通道的最低位必须不同。

发送端通过按键把数据通道从0-5经行切换,选择不同的地址经行通信,接收端同样经行对应的处理以便通信。

发送端切换通道的程序:

接收端的选择程序

uchar code dizhi[]={0x01,0x02,0x04,0x08,0x10,0x20}; //接收通道和使能通道的切换

通过按键的选择,通道能从0到5进行切换,然后只有通道相同才可以传输数据,显示屏上才有数据更新。

4.2 DS18B20温度模块

温度模块读取温度程序流程图如图9读取温度程序流程图所示

图9读取温度程序流程图

程序见附录A

5、PCB 板的设计与制作:

5.1 PCB图设计

PCB 图如图10所示:

PCB 图的设计如图10 PCB图所示

图10 PCB图所示

6、电路的调试及调试结果

把PCB 板制作完毕之后,拿到元器件之后,开始进行焊接,对安装焊接工艺要求是:电阻,电容尽可能卧式安装,减少虚焊,脱焊现象,贴片元器件等需要快速焊接,避免元器件由于温度过高而损坏。

进行测试的时候发现LCD 没有显示数据,然后对LCD1602进行测试,没有问题;对照资料才发现数据口反过来接了,然后用杜邦线进行重新连接,测试通过了[3]。

接着排查无线模块,温度模块,进行资料的查询,发现DS18B20引脚接反了,然后把DS18B20调转插在底座上面。

无线模块也没有正常工作,是因为没有正常的供电,缺少AMS1117降压模块,然后手工焊接了一个降压模块,无线模块也正常工作了,然后进行整体测试,硬件测试通过。

接着就是程序测试,一开始是数据不能正确显示,有一些字符乱码,通过调试程序,优化LCD 显示,完成测试。[3]

由于设计要求需要进行信道的切换,一开始写了数组进行信道的选择,但是达不到所需要的效果,只能有通道0和1可以单独通信,其他通道无法进行通信。后来才知道信道的使能端也需要进行选择处理,才可以对数据进行单独处理。 因为一开始对无线模块的使能通道处理不妥当,发送端和接收端全打开(0x3f )处理, 所以进行通信的时候,只有0和1可以切换,其他通道时会出现错误,当接收端为0时,发送端每一个通道都可以传输数据,所以一直在找原因。最后才知道要在接收端进行使能端的选择,才能使通道单独选择,而不收其他通道的影响。

发送端原处理程序如下:

SPI_W_Reg(W_REGISTER+EN_AA,0x30);/*接收通道自动应答*/

SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x30);/*使能接收通道*/

修改后把0x30改为0x3f, 把通道使能全打开,程序如下:

SPI_W_Reg(W_REGISTER+EN_AA,0x3f);/*接收全通道自动应答*/

SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x3f);/*使能接收权通道*/

接收端的使能端进行按键选择,原程序如下:

SPI_W_Reg(W_REGISTER+EN_AA,0x3f);

SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x3f);

调试之后程序为:

uchar code dizhi[]={0x01,0x02,0x04,0x08,0x10,0x20}; [3]

SPI_W_Reg(W_REGISTER+EN_AA,dizhi[xuan]);

SPI_W_Reg(W_REGISTER+EN_RX_ADDR,dizhi[xuan]);

7、实验总结及心得体会

这次课程设计一共做了几个PCB 才成功,由于第一个缺陷太多,所以重新修改原理图及PCB ,制作第二个PCB 板,把元器件拆卸下来重新焊接到第二板子上,出现了不少错误,后来在切换信道的功能上,又进行了第三个板子制作,终于调通了。所以在刚动手之前就要想清楚原理图,最好进行仿真,以免出现过多的错误,导致损坏元器件。

在实验过程中,通过选取元件、确定电路形式、以及计算等等,同时通过调试来发现自己的错误并分析及排除这些故障。

焊接电路板更要注意,要先检查所有的元件是否可用,焊接二极管电接电容时应分清正负极焊接时要注意防止虚焊,电容电感尽量卧式安装,焊接完成后尽量缩短元件引线,但不用剪太短,否则不容易更改。

参考文献

[1] 付聪,付慧生,李益青. 基于NRF24L01无线温度采集控制系统的设计[J].工业自动化.2010年1月,第一期:73-74

[2] 王振,胡清,黄杰. 基于NRF24L01无线温度采集系统设计[J].电子设计工程.2009年12月,第十二期第17卷:24-25

[3] 郭天祥著. 51单片机C 语言教程[M].北京:电子工业出版社.2012年: 148-156, 342-354

附录A

无线温度发送模块程序代码:

#include

#include

#define uint unsigned int

#define uchar unsigned char

#define TX_ADDR_WITDH 5//发送地址宽度设置为5个字节

#define RX_ADDR_WITDH 5

#define TX_DATA_WITDH 5

#define RX_DATA_WITDH 5

/****************************************************************** // nRF24L01指令格式:

*******************************************************************/ #define R_REGISTER 0x00 // 读寄存器

#define W_REGISTER 0x20 // 写寄存器

#define R_RX_PLOAD 0x61 // 读RX FIFO有效数据,1-32字节,当读数据完成后,数据被清除,应用于接收模式

#define W_TX_PLOAD 0xA0 // 写TX FIFO 有效数据,1-32字节,写操作从字节0开始,应用于发射模式

#define FLUSH_TX 0xE1 // 清除TX FIFO寄存器,应用于发射模式

#define FLUSH_RX 0xE2 // 清除RX FIFO寄存器,应用于接收模式

#define REUSE_TX_PL 0xE3 // 重新使用上一包有效数据,当CE 为高过程中,数据包被不断的重新发射

#define NOP 0xFF // 空操作,可以用来读状态寄存器

/****************************************************************** // nRF24L01寄存器地址

*******************************************************************/ #define CONFIG 0x00 // 配置寄存器

#define EN_AA 0x01 // “自动应答”功能寄存

#define EN_RX_ADDR 0x02 // 接收通道使能寄存器

#define SETUP_AW 0x03 // 地址宽度设置寄存器

#define SETUP_RETR 0x04 // 自动重发设置寄存器

#define RF_CH 0x05 // 射频通道频率设置寄存器

#define RF_SETUP 0x06 // 射频设置寄存器

#define STATUS 0x07 // 状态寄存器

#define OBSERVE_TX 0x08 // 发送检测寄存器

#define CD 0x09 // 载波检测寄存器

#define RX_ADDR_P0 0x0A // 数据通道0接收地址寄存器

#define RX_ADDR_P1 0x0B // 数据通道1接收地址寄存器

#define RX_ADDR_P2 0x0C // 数据通道2接收地址寄存器

#define RX_ADDR_P3 0x0D // 数据通道3接收地址寄存器

#define RX_ADDR_P4 0x0E // 数据通道4接收地址寄存器

#define RX_ADDR_P5 0x0F // 数据通道5接收地址寄存器

#define TX_ADDR 0x10 // 发送地址寄存器

#define RX_PW_P0 0x11 // 数据通道0有效数据宽度设置寄存器

#define RX_PW_P1 0x12 // 数据通道1有效数据宽度设置寄存器

#define RX_PW_P2 0x13 // 数据通道2有效数据宽度设置寄存器

#define RX_PW_P3 0x14 // 数据通道3有效数据宽度设置寄存器

#define RX_PW_P4 0x15 // 数据通道4有效数据宽度设置寄存器

#define RX_PW_P5 0x16 // 数据通道5有效数据宽度设置寄存器

#define FIFO_STATUS 0x17 // FIFO状态寄存器

//*********************************************************************************

uchar sta; // 状态变量

#define RX_DR (sta & 0x40) // 接收成功中断标志

#define TX_DS (sta & 0x20) // 发射成功中断标志

#define MAX_RT (sta & 0x10) // 重发溢出中断标志

sbit CE=P1^5;

sbit IRQ=P1^2;

sbit CSN=P1^0;

sbit MOSI=P1^1;

sbit MISO=P1^3;

sbit SCK=P1^4;

sbit DQ=P2^2;

sbit key=P2^6;

uchar code TX_Addr[]={0x34,0x43,0x10,0x10,0x01};

uchar code TX_Addr1[]={0x33,0x42,0x11,0x11,0x21}; //++++++++

uchar code TX_Addr2[]={0xb1,0x42,0x11,0x11,0x21};

uchar code TX_Addr3[]={0xb2,0x42,0x11,0x11,0x21};

uchar code TX_Addr4[]={0xb3,0x42,0x11,0x11,0x21};

uchar code TX_Addr5[]={0xb4,0x42,0x11,0x11,0x21};

uchar code shuma[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92};

uchar counter=0;

uchar RX_Buffer[RX_DATA_WITDH];

uchar Temp_Value[]={0x00,0x00};

uchar Temp=0;

uchar Display_Digit[]={0,0,0,0};

bit DS18B20_IS_OK=1;

uchar code df_tab[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};//decimal fraction

void _delay_tus(uint x)

{

while(--x);

}

void _delay_us(uint x)

{

uint i,j;

for (j=0;j

for (i=0;i

}

void _delay_ms(uint x)

{

uint i,j;

for (j=0;j

for (i=0;i

}

/**************************************************/

/*函数功能:DS18B20初始化 */

/*入口参数:无 */

/*出口函数:status */

/**************************************************/

uchar DS18B20_Init(void)

{

uchar status;

DQ=1;

_delay_tus(10);

DQ=0;

_delay_tus(90);

DQ=1;

_delay_tus(8);

status=DQ;

_delay_tus(100);

DQ=1;

return status;

}

/**************************************************/

/*函数功能:从DS18B20读取一字节 */

/*入口参数:无 */

/*出口函数:dat(返回读取到数据) */

/**************************************************/

uchar Read_One_Byte(void)

{

uchar i,dat=0;

DQ=1;

_nop_();

for(i=8;i>0;i--)

{

DQ=0;

dat>>=1;

DQ=1;

_nop_();_nop_();

if(DQ)

dat|=0x80;

_delay_tus(30);

DQ=1;

}

return dat;

}

/**************************************************/

/*函数功能:向DS18B20写一字节 */

/*入口参数:dat(把dat 写入DS18B20) */

/*出口函数:无 */

/**************************************************/

void Write_One_Byte(uchar dat)

{

uchar i;

for(i=8;i>0;i--)

{

DQ=0;

DQ=dat&0x01;

_delay_tus(5);

DQ=1;

dat>>=1;

}

}

/**************************************************/

/*函数功能:从DS18B20读取数据(数据) */

/*入口参数:无 */

/*出口函数:无 */

/**************************************************/

void Read_Temp(void)

{

uchar ng=0;

if(DS18B20_Init()==1)

DS18B20_IS_OK=0;

else

{

Write_One_Byte(0xcc);

Write_One_Byte(0x44);

DS18B20_Init();

Write_One_Byte(0xcc);

Write_One_Byte(0xbe);

Temp_Value[0]=Read_One_Byte();

Temp_Value[1]=Read_One_Byte();

DS18B20_IS_OK=1;

}

if((Temp_Value[1]&0xf8)==0xf8)

{

Temp_Value[1]=~Temp_Value[1];

Temp_Value[0]=~Temp_Value[0]+1;

if(Temp_Value[0]==0x00)

Temp_Value[1]++;

ng=1;

}

Display_Digit[0]=df_tab[Temp_Value[0]&0x0f];

Temp=((Temp_Value[0]&0xf0)>>4)|((Temp_Value[1]&0x07)

Display_Digit[3]=Temp/100;

Display_Digit[2]=Temp%100/10;

Display_Digit[1]=Temp%10;

}

/*nRF24L01初始化*/

void nRF24L01_Init(void)

{

_delay_us(2000);

CE=0;//待机模式Ⅰ

CSN=1;

SCK=0;

IRQ=1;

}

/*SPI时序函数*/

uchar SPI_RW(uchar byte)

{

uchar i;

for(i=0;i

{

if(byte&0x80)//如果数据最高位是1//当访问多字节寄存器时首先要读/写的是最低字节的高位?

MOSI=1;//向NRF24L01写1

else //否则写0

MOSI=0;

byte

SCK=1;//SCK拉高,写入一位数据,同时读取一位数据

if(MISO)

byte|=0x01;

SCK=0;//SCK拉低

}

return byte;//返回读取一字节

}

/*SPI写寄存器一字节函数*/

/*reg:寄存器地址*/

/*value:一字节(值)*/

uchar SPI_W_Reg(uchar reg,uchar value)

{

uchar status;//返回状态

CSN=0;//SPI片选

status=SPI_RW(reg);//写入寄存器地址,同时读取状态

SPI_RW(value);//写入一字节

CSN=1;//

return status;//返回状态

}

/*SPI*/

uchar SPI_R_byte(uchar reg)

{

uchar reg_value;

CSN=0;//SPI片选

SPI_RW(reg);//写入地址

reg_value=SPI_RW(0);//读取寄存器的值

CSN=1;

return reg_value;//返回读取的值

}

/*SPI读取RXFIFO 寄存器数据*/

/*reg:寄存器地址*/

/**Dat_Buffer:用来存读取的数据*/

/*DLen:数据长度*/

uchar SPI_R_DBuffer(uchar reg,uchar *Dat_Buffer,uchar Dlen)

{

uchar status,i;

CSN=0;//SPI片选

status=SPI_RW(reg);//写入寄存器地址,同时状态

for(i=0;i

{

Dat_Buffer[i]=SPI_RW(0);//存储数据

}

CSN=1;

return status;

}

/*SPI向TXFIFO 寄存器写入数据*/

/*reg:写入寄存器地址*/

/*TX_Dat_Buffer:存放需要发送的数据*/

/*Dlen:数据长度*/

uchar SPI_W_DBuffer(uchar reg,uchar *TX_Dat_Buffer,uchar Dlen)

{

uchar status,i;

CSN=0;//SPI片选,启动时序

status=SPI_RW(reg);

for(i=0;i

{

SPI_RW(TX_Dat_Buffer[i]);//发送数据

}

CSN=1;

return status;

}

/*设置发送模式*/

void nRF24L01_Set_TX_Mode(uchar *TX_Data)

{

CE=0;//待机(写寄存器之前一定要进入待机模式或掉电模式)

CSN=0;

SPI_RW(FLUSH_TX);

CSN=1;

/*信道的选择, 按键切换*/

if(key==0)

{

_delay_ms(20);

if(key==0)

{

P0=shuma[counter];

_delay_ms(50);

switch(counter)

{

case 0 :

SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr,TX_ADDR_WITDH);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P0,TX_Addr,TX_ADDR_WITDH);

break;

case 1 :

SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr1,TX_ADDR_WITDH);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P1,TX_Addr1,TX_ADDR_WITDH);

break;

case 2 :

SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr2,TX_ADDR_WITDH);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P2,TX_Addr2,TX_ADDR_WITDH);

break;

case 3 :

SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr3,TX_ADDR_WITDH);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P3,TX_Addr3,TX_ADDR_WITDH);

break;

case 4 :

SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr4,TX_ADDR_WITDH);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P4,TX_Addr4,TX_ADDR_WITDH);

break;

case 5 :

SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr5,TX_ADDR_WITDH);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P5,TX_Addr5,TX_ADDR_WITDH);

break;

}

counter++;

if(counter==6)

counter=0;

}

}

SPI_W_DBuffer(W_TX_PLOAD,TX_Data,TX_DATA_WITDH);/*写有效数据地址+有效数据+有效数据宽度*/

SPI_W_Reg(W_REGISTER+EN_AA,0x3f);/*接收全通道自动应答*/

SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x3f);/*使能接收全通道*/

SPI_W_Reg(W_REGISTER+SETUP_RETR,0x0a);/*自动重发延时250US+86US,重发10次*/ SPI_W_Reg(W_REGISTER+RF_CH,0x27);/*(2400+39)MHZ选择射频通道0X27*/

SPI_W_Reg(W_REGISTER+RF_SETUP,0x07);/*1Mbps速率, 发射功率:0DBM,低噪声放大器增益*/

SPI_W_Reg(W_REGISTER+CONFIG,0x0e);/*发送模式, 上电,16位CRC 校验,CRC 使能*/ CE=1;//启动发射

_delay_ms(5);/*CE高电平持续时间最少10US 以上*/

}

uchar Check_Rec(void)

{

uchar status;

sta=SPI_R_byte(R_REGISTER+STATUS);

if(RX_DR)

{

CE=0;

SPI_R_DBuffer(R_RX_PLOAD,RX_Buffer,RX_DATA_WITDH);

status=1;

}

SPI_W_Reg(W_REGISTER+STATUS,0xff);

return status;

}

/*检测应答信号*/

uchar Check_Ack(void)

{

sta=SPI_R_byte(R_REGISTER+STATUS);/*读取寄存状态*/

if(TX_DS||MAX_RT)/*如果TX_DS或MAX_RT为1, 则清除中断和清除TX_FIFO寄存器的值*/

{

SPI_W_Reg(W_REGISTER+STATUS,0xff);

CSN=0;

SPI_RW(FLUSH_TX);

CSN=1;

return 0;

}

else

return 1;

}

void main(void)

{

uchar i;

P0=0xff;

P1=0xff;

P2=0xff;

P3=0xff;

nRF24L01_Init();

Read_Temp();

_delay_ms(1000);

while(1)

{

Read_Temp();

if(DS18B20_IS_OK)

{

for(i=0;i

nRF24L01_Set_TX_Mode(&Display_Digit[i]);

_delay_ms(100);

while(Check_Ack());

}

}

}

}

无线温度接收模块程序代码:

#include

#include

#define uint unsigned int

#define uchar unsigned char

#define TX_ADDR_WITDH 5//发送地址宽度设置为5个字节

#define RX_ADDR_WITDH 5

#define TX_DATA_WITDH 5

#define RX_DATA_WITDH 5

/******************************************************************

// nRF24L01指令格式:

*******************************************************************/

#define R_REGISTER 0x00 // 读寄存器

#define W_REGISTER 0x20 // 写寄存器

#define R_RX_PLOAD 0x61 // 读RX FIFO有效数据,1-32字节,当读数据完成后,数据被清除,应用于接收模式

#define W_TX_PLOAD 0xA0 // 写TX FIFO 有效数据,1-32字节,写操作从字节0开始,应用于发射模式

#define FLUSH_TX 0xE1 // 清除TX FIFO寄存器,应用于发射模式

#define FLUSH_RX 0xE2 // 清除RX FIFO寄存器,应用于接收模式

#define REUSE_TX_PL 0xE3 // 重新使用上一包有效数据,当CE 为高过程中,数据包被不断的重新发射

#define NOP 0xFF // 空操作,可以用来读状态寄存器

/******************************************************************

// nRF24L01寄存器地址

*******************************************************************/

#define CONFIG 0x00 // 配置寄存器

#define EN_AA 0x01 // “自动应答”功能寄存器

#define EN_RX_ADDR 0x02 // 接收通道使能寄存器

#define SETUP_AW 0x03 // 地址宽度设置寄存器

#define SETUP_RETR 0x04 // 自动重发设置寄存器

#define RF_CH 0x05 // 射频通道频率设置寄存器

#define RF_SETUP 0x06 // 射频设置寄存器

#define STATUS 0x07 // 状态寄存器

#define OBSERVE_TX 0x08 // 发送检测寄存器

#define CD 0x09 // 载波检测寄存器

#define RX_ADDR_P0 0x0A // 数据通道0接收地址寄存器

#define RX_ADDR_P1 0x0B // 数据通道1接收地址寄存器

#define RX_ADDR_P2 0x0C // 数据通道2接收地址寄存器

#define RX_ADDR_P3 0x0D // 数据通道3接收地址寄存器

#define RX_ADDR_P4 0x0E // 数据通道4接收地址寄存器

#define RX_ADDR_P5 0x0F // 数据通道5接收地址寄存器

#define TX_ADDR 0x10 // 发送地址寄存器

#define RX_PW_P0 0x11 // 数据通道0有效数据宽度设置寄存器

#define RX_PW_P1 0x12 // 数据通道1有效数据宽度设置寄存器

#define RX_PW_P2 0x13 // 数据通道2有效数据宽度设置寄存器

#define RX_PW_P3 0x14 // 数据通道3有效数据宽度设置寄存器

#define RX_PW_P4 0x15 // 数据通道4有效数据宽度设置寄存器

#define RX_PW_P5 0x16 // 数据通道5有效数据宽度设置寄存器

#define FIFO_STATUS 0x17 // FIFO状态寄存器

//*********************************************************************************

uchar sta; // 状态变量

#define RX_DR (sta & 0x40) // 接收成功中断标志

#define TX_DS (sta & 0x20) // 发射成功中断标志

#define MAX_RT (sta & 0x10) // 重发溢出中断标志

sbit CE=P1^5;

sbit IRQ=P1^2;

sbit CSN=P1^0;

sbit MOSI=P1^1;

sbit MISO=P1^3;

sbit SCK=P1^4;

sbit key1=P1^6;

sbit key2=P1^7;

sbit deng=P2^0;

sbit LCD_RS=P2^3;

sbit LCD_RW=P2^4;

sbit LCD_EN=P2^5;

uchar code TX_Addr[]={0x34,0x43,0x10,0x10,0x01};

uchar code TX_Addr1[]={0x33,0x42,0x11,0x11,0x21}; //++++++++

uchar code TX_Addr2[]={0xb1};

uchar code TX_Addr3[]={0xb2};

uchar code TX_Addr4[]={0xb3};

uchar code TX_Addr5[]={0xb4};

uchar code dizhi[]={0x01,0x02,0x04,0x08,0x10,0x20}; //+++++++

uchar code shuma[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92};//++++++

uchar code TX_Buffer[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

uchar RX_Buffer[RX_DATA_WITDH];

uchar code Display_LINE0[]={"ID:110709 06/14 "};

uchar Display_LINE1[]={" TEMP: "};

uchar counter=0;

uchar xuan=0;

void _delay_us(uint x)

{

uint i,j;

for (j=0;j

for (i=0;i

}

void _delay_ms(uint x)

{

uint i,j;

for (j=0;j

for (i=0;i

}

bit LCD_Busy(void)//测忙

{

bit LCD_Status;//返回值变量

LCD_RS=0;//读取状态

LCD_RW=1;

LCD_EN=1;

_nop_();_nop_();_nop_();_nop_();

LCD_Status=(bit)(P0&0x80);

LCD_EN=0;

return LCD_Status;

}

void LCD_Write_Command(uchar cmd)//写指令

{

LCD_RS=0;

LCD_RW=0;

LCD_EN=0;

_nop_();_nop_();

P0=cmd;

_nop_();_nop_();_nop_();_nop_();

LCD_EN=1;

_nop_();_nop_();_nop_();_nop_();

LCD_EN=0;

}

void LCD_Write_Data(uchar dat)//写数据

{

//每次写数据操作之前均需要检测忙信号

LCD_RS=1;

LCD_RW=0;

LCD_EN=0;

P0=dat;

_nop_();_nop_();_nop_();_nop_();

LCD_EN=1;

_nop_();_nop_();_nop_();_nop_();

LCD_EN=0;

}

void Init_LCD(void)//液晶初始化

{

_delay_ms(15);//延时15MS

LCD_Write_Command(0x38);

_delay_ms(5);

LCD_Write_Command(0x38);

_delay_ms(5);

LCD_Write_Command(0x38);//以后每次写指令操作之前均需要检测忙信号 _delay_ms(5);

LCD_Write_Command(0x01);//清屏

_delay_ms(5);

LCD_Write_Command(0x38);//设置16*2显示,5*7点阵,8位数据接口 _delay_ms(5);

LCD_Write_Command(0x0c);//开显示, 不显示光标

_delay_ms(5);

LCD_Write_Command(0x06);//当读或写一个字符后地址指针加一, 且光标加一 }

void LCD_POS(uchar pos)//字符显示位置

{

LCD_Write_Command(0x80|pos);

}

void Show_String(uchar *str)//显示字符串

{

while(*str!='\0')

LCD_Write_Data(*str++);

}

void nRF24L01_Init(void)

{

_delay_us(2000);

CE=0;

CSN=1;

SCK=0;

IRQ=1;

}

uchar SPI_RW(uchar byte)

{

uchar i;

for(i=0;i

{

if(byte&0x80)

MOSI=1;

else

byte

SCK=1;

if(MISO)

byte|=0x01;

SCK=0;

}

return byte;

}

uchar SPI_W_Reg(uchar reg,uchar value)

{

uchar status;

CSN=0;

status=SPI_RW(reg);

SPI_RW(value);

CSN=1;

return status;

}

uchar SPI_R_byte(uchar reg)

{

uchar status;

CSN=0;

SPI_RW(reg);

status=SPI_RW(0);

CSN=1;

return status;

}

uchar SPI_R_DBuffer(uchar reg,uchar *Dat_Buffer,uchar Dlen)

{

uchar reg_value,i;

CSN=0;

reg_value=SPI_RW(reg);

for(i=0;i

{

Dat_Buffer[i]=SPI_RW(0);

}

CSN=1;

return reg_value;

}

uchar SPI_W_DBuffer(uchar reg,uchar *TX_Dat_Buffer,uchar Dlen)

{

uchar reg_value,i;

reg_value=SPI_RW(reg);

for(i=0;i

{

SPI_RW(TX_Dat_Buffer[i]);

}

CSN=1;

return reg_value;

}

void nRF24L01_Set_RX_Mode(void)

{

CE=0;//待机

/*信道的选择, 按键切换*/

if(key1==0)

{

_delay_ms(20);

if(key1==0)

{

switch(counter)

{

case 0 : P3=shuma[counter];

_delay_ms(1000);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P0,TX_Addr,TX_ADDR_WITDH);

SPI_W_Reg(W_REGISTER+RX_PW_P0,RX_DATA_WITDH); break;

case 1 : P3=shuma[counter];

_delay_ms(1000);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P1,TX_Addr1,TX_ADDR_WITDH);

SPI_W_Reg(W_REGISTER+RX_PW_P1,RX_DATA_WITDH); break;

case 2 : P3=shuma[counter];

_delay_ms(1000);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P2,TX_Addr2,1); SPI_W_Reg(W_REGISTER+RX_PW_P2,RX_DATA_WITDH); break;

case 3 : P3=shuma[counter];

_delay_ms(1000);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P3,TX_Addr3,1); SPI_W_Reg(W_REGISTER+RX_PW_P3,RX_DATA_WITDH); break;

case 4 : P3=shuma[counter];

_delay_ms(1000);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P4,TX_Addr4,1); SPI_W_Reg(W_REGISTER+RX_PW_P4,RX_DATA_WITDH); break;

case 5 : P3=shuma[counter];

_delay_ms(1000);

SPI_W_DBuffer(W_REGISTER+RX_ADDR_P5,TX_Addr5,1); SPI_W_Reg(W_REGISTER+RX_PW_P5,RX_DATA_WITDH); break;

}

counter++;

if(counter==6)

counter=0;

}

}

if(key2==0)

{

_delay_ms(20);

if(key2==0)

{

deng=~deng;

_delay_ms(1000);

xuan++;

}

}

SPI_W_Reg(W_REGISTER+EN_AA,dizhi[xuan]);

SPI_W_Reg(W_REGISTER+EN_RX_ADDR,dizhi[xuan]);

SPI_W_Reg(W_REGISTER+RF_CH,0x27);

SPI_W_Reg(W_REGISTER+RF_SETUP,0x07);

SPI_W_Reg(W_REGISTER+CONFIG,0x0f);

CE=1;

_delay_ms(5);

if(xuan==6)

xuan=0;

}

uchar nRF24L01_RX_Data(void)

{

sta=SPI_R_byte(R_REGISTER+STATUS);

if(RX_DR)

{

CE=0;

SPI_R_DBuffer(R_RX_PLOAD,RX_Buffer,RX_DATA_WITDH);

SPI_W_Reg(W_REGISTER+STATUS,0xff);

CSN=0;

SPI_RW(FLUSH_RX);

CSN=1;

return 1;

}

else

return 0;

}

void main(void)

{

uchar i,RX_Temp_Value[RX_DATA_WITDH]; P0=0xff;

P1=0xff;

P2=0xff;

P3=0xff;

Init_LCD();

nRF24L01_Init();

_delay_us(1000);

LCD_POS(0);

Show_String(Display_LINE0);

while(1)

{

nRF24L01_Set_RX_Mode();

if(nRF24L01_RX_Data())

{

for(i=0;i

RX_Temp_Value[i]=RX_Buffer[i]; }

}

Display_LINE1[7]=RX_Temp_Value[3]+'0'; Display_LINE1[8]=RX_Temp_Value[2]+'0'; Display_LINE1[9]=RX_Temp_Value[1]+'0'; Display_LINE1[10]='.';

Display_LINE1[11]=RX_Temp_Value[0]+'0'; Display_LINE1[12]=0xdf;

Display_LINE1[13]=0x43;

if(RX_Temp_Value[3]==0)

Display_LINE1[7]=' ';

LCD_POS(0x40);

Show_String(Display_LINE1);

}

}


相关文章

  • 无线测温方案书
  • 山东正瑞电子有限公司开关柜温度在线监测系统技术方案书 关键词:开关柜无线测温.无线测温.触头测温.无源无线测温 1. 开关柜无线测温综述 现代社会对电能的依赖性极高,用电密度越大的地区对电的依赖性越高,因而对供电设备的可靠性提出了越来越高的 ...查看


  • 声表面波传感器产品简介(温度传感器)
  • 江苏声立传感技术有限公司 SAW无源无线温度监测系统 -智能电网测温的最优解决方案 江苏声立传感技术有限公司 SAW无源无线温度监测系统 系统概述 电力系统中,各类设备的开断接触点可能因为松动.老化.电弧冲击等原因造成接触电阻增大.这会使触 ...查看


  • 无线传感器网络应用实例荟萃
  • 无线传感器网络应用实例荟萃 陈建峰 西安成峰科技有限公司,西安市高新一路 16 号创业大厦 B 座 706 室, 电话:8825 7625 无线传感器网络具有可快速部署.可自组织.隐蔽 性强和高容错性的特点,因此非常适合在军事上应用. 利用 ...查看


  • 环网柜无源无线测温管理系统设计
  • 第13卷第25期2013年9月 科学技术与工程 ScienceTechnologyand V01.13No.25 Sep.2013 1671-1815(2013)25-7516-05En舀neefing⑥2013 Sci.Tech.Engr ...查看


  • 一种基于Zigbee的中压馈线柜无线测温系统
  • 摘 要:文章提出一种基于Zigbee的中压馈线柜无线测温系统的方案,该系统中含有一体化热电偶温度变送器.Zigbee无线传输模块JN5139芯片.测温仪系统.PC监测站.供能CT电源.所述的JN5139芯片包括MCU.MODEM和天线,MC ...查看


  • 疫苗冷链温度实时监控系统解决方案v2
  • 疫苗冷链温度实时 监控系统 解决方案 珠海飞企软件有限公司 2013年3月12日 版权声明 本文档版权属珠海飞企软件有限公司所有,任何其他组织单位及个人,未经珠海飞企软件有限公司书面许可,均不得传播.散发.印制给其他单位及个人 目录 1. ...查看


  • 物联网课程设计
  • 课程设计 班 级: 通信10-2 姓 名: 王佩 学 号: 1006030219 指导教师: 杨春玲 成 绩: 报告 电子与信息工程学院 信息与通信工程系 基于物联网的远程环境监测系统的设计 摘要 针对当前监控系统在室内环境监控中存在的弊端 ...查看


  • 基于单片机的无线网络传输温度
  • 2010年第06期(下) 科技目向导 ◇高教论述◇ 基于单片机的无线网络传输温度 采集系统的研究 万 毅 (中南大学土木建筑学院 张翠 湖南长沙410075) [摘要]本研究是基于51单片机的无线传输温度采集系统.系统采用51单片机进行控制 ...查看


  • 渔业水质在线监测系统
  • 渔业水质在线监测系统 天津智易时代科技发展有限公司 2016年11月11日 目 录 目录 公司简介....................................................................... ...查看


  • 农业物联网解决方案
  • 农业物联网解决方案设计和项目实施 一.概念 物联网概念在1999年提出,是将所有物品通过各种信息传感设备,如射频识别装置.基于光声电磁的传感器.3S技术.激光扫描器等各类装置与互联网结合起来,实现数据采集.融合.处理,并通过操作终端,实现智 ...查看


热门内容