stc89c52+1602+nrf2401温湿度监测
时间:10-02
整理:3721RD
点击:
板子弄好了 ,但是只是液晶亮了而已 。其他没反应 附上电路图 和程序 新人求解
#include <reg52.h>
#include <intrins.h>
typedef unsigned char uchar;
typedef unsigned char uint;
typedef unsigned char U8;
/*variable 无符号8位整型变量 */
typedef signed char S8;
/* variable 有符号8位整型变量 */
typedef unsigned int U16;
/*variable 无符号16位整型变量 */
typedef signed int S16;
/*variable 有符号16位整型变量 */
typedef unsigned long U32;
/*variable 无符号32位整型变量 */
typedef signed long S32;
/*variable 有符号32位整型变量 */
typedef float F32;
/*variable (32bits) 单精度浮点数(32位长度) */
typedef double F64;
/*variable (64bits) 双精度浮点数(64位长度) */
//***************************IO端口定*********************************
sbit MISO =P1^3;
sbit MOSI =P1^1;
sbit SCK =P1^4;
sbit CE =P3^2;
sbit CSN =P1^0;
sbit IRQ =P1^2;
sbit LCD_RS = P2^7 ;
sbit LCD_RW = P2^6 ;
sbit LCD_EN = P2^5 ;
//**************************DHT11端口设******************************
sbit P2_0 = P2^0 ;
U8 U8FLAG,k;
U8 U8count,U8temp;
U8 U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
U8 U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
U8 U8comdata;
uchar data temp_data[2]={0x00,0x00}; //温度湿度采集数据缓冲区
uchar dispaly[4]; //显示缓冲区
uint bdata sta; //NRF24L01状态标志
sbit RX_DR =sta^6;
sbit TX_DS =sta^5;
sbit MAX_RT =sta^4;
//*************************************NRF24L01***********************
#define TX_ADR_WIDTH 5 // 本机地址宽度设置
#define RX_ADR_WIDTH 5 // 接收方地址宽度设置
#define TX_PLOAD_WIDTH 10 // 4 字节数据长度
#define RX_PLOAD_WIDTH 10 // 4 字节数据长度
uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址
uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
//***************NRF24L01寄存器指令****************
#define READ_REG 0x00 // 读寄存器指令
#define WRITE_REG 0x20 // 写寄存器指令
#define RD_RX_PLOAD 0x61 // 读取接收数据指令
#define WR_TX_PLOAD 0xA0 // 写待发数据指令
#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令
#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令
#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令
#define NOP 0xFF // 保留
//*************SPI(nRF24L01)寄存器地址**************
#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA 0x01 // 自动应答功能设置
#define EN_RXADDR 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 // 接收频道0接收数据长度
#define RX_PW_P2 0x13 // 接收频道0接收数据长度
#define RX_PW_P3 0x14 // 接收频道0接收数据长度
#define RX_PW_P4 0x15 // 接收频道0接收数据长度
#define RX_PW_P5 0x16 // 接收频道0接收数据长度
#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置
#define delayNOP() ; {_nop_() ;_nop_() ;_nop_() ;_nop_() ;} ;
//************************************NRF24L01函数申明****************
void Delay(unsigned int s);
void inerDelay_us(unsigned char n);
void init_NRF24L01(void);
uint SPI_RW(uint uchar);
uchar SPI_Read(uchar reg);
void SetRX_Mode(void);
uint SPI_RW_Reg(uchar reg, uchar value);
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);
void nRF24L01_TxPacket(unsigned char * tx_buf);
//**************************DHT11函数申明************************
void Delay1(U16 j);
void Delay_10us(void);
void COM(void);
void RH(void);
//***************************LCD1602函数声明*************************
void delay2(int ms);
bit lcd_busy();
void lcd_wcmd(uchar cmd);
void lcd_wdat(uchar dat);
void lcd_init();
void lcd_pos(uchar pos);
void LCD_disp_char(uchar x,uchar y,uchar dat);
void LCD_disp_str(uchar x,uchar y,uchar *str);
//***************************LCD1602相关函数************************
void delay2(int ms)
{
unsigned char y ;
while(ms--)
{
for(y = 0 ; y<250 ; y++)
{
_nop_() ;
_nop_() ;
_nop_() ;
_nop_() ;
}
}
}
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
bit lcd_busy()
{
bit result ;
LCD_RS = 0 ;
LCD_RW = 1 ;
LCD_EN = 1 ;
delayNOP() ;
result = (bit)(P0&0x80) ;
LCD_EN = 0 ;
return(result) ;
}
/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
void lcd_wcmd(uchar cmd)
{
while(lcd_busy()) ;
LCD_RS = 0 ;
LCD_RW = 0 ;
LCD_EN = 0 ;
_nop_() ;
_nop_() ;
P0 = cmd ;
delayNOP() ;
LCD_EN = 1 ;
delayNOP() ;
LCD_EN = 0 ;
}
/*写显示数据到LCD */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
void lcd_wdat(uchar dat)
{
while(lcd_busy()) ;
LCD_RS = 1 ;
LCD_RW = 0 ;
LCD_EN = 0 ;
P0 = dat ;
delayNOP() ;
LCD_EN = 1 ;
delayNOP() ;
LCD_EN = 0 ;
}
/* LCD初始化设定 */
void lcd_init()
{
delay2(15) ;
lcd_wcmd(0x01) ; //清除LCD的显示内容
lcd_wcmd(0x38) ; //16*2显示,5*7点阵,8位数据
delay2(5) ;
lcd_wcmd(0x38) ;
delay2(5) ;
lcd_wcmd(0x38) ;
delay2(5) ;
lcd_wcmd(0x0c) ; //显示开,关光标
delay2(5) ;
lcd_wcmd(0x06) ; //移动光标
delay2(5) ;
lcd_wcmd(0x01) ; //清除LCD的显示内容
delay2(5) ;
}
/* 设定显示位置 */
void lcd_pos(uchar pos)
{
lcd_wcmd(pos | 0x80) ; //数据指针=80+地址变量
}
void LCD_disp_char(uchar x,uchar y,uchar dat)
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
lcd_wcmd(address);
lcd_wdat(dat);
}
/*模块名称:LCD_disp_str();
/*功 能:LCD1602显示字符串函数,在某个屏幕起始位置{X(0-15),y (1-2)}上显示一个字符串。
void LCD_disp_str(uchar x,uchar y,uchar *str)
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
lcd_wcmd(address);
while(*str!='\0')
{
lcd_wdat(*str);
str++;
}
}
//*******************LCD1602相关函数结束*********************
//**************************长延时****************************
void Delay(unsigned int s)
{
unsigned int i;
for(i=0; i<s; i++);
for(i=0; i<s; i++);
}
/*延时函数
void inerDelay_us(unsigned char n)
{
for(;n>0;n--)
_nop_();
}
/*NRF24L01初始化
void init_NRF24L01(void)
{
inerDelay_us(100);
CE=0;
CSN=1;
SCK=0;
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 频道0自动 ACK应答允许
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0
SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为4字节
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1Mkbps,发射功率为最大值0dB
}
/*函数:uint SPI_RW(uint uchar)
/*功能:NRF24L01的SPI写时序
uint SPI_RW(uint uchar)
{
uint bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++)
{
MOSI = (uchar & 0x80); I
uchar = (uchar << 1);
SCK = 1;
uchar |= MISO;
SCK = 0;
}
return(uchar);
}
/*函数:uchar SPI_Read(uchar reg)
/*功能:NRF24L01的SPI时序
uchar SPI_Read(uchar reg)
{
uchar reg_val;
CSN = 0;
SPI_RW(reg);
reg_val = SPI_RW(0);
CSN = 1;
return(reg_val);
}
/*功能:NRF24L01读写寄存器函数,
uint SPI_RW_Reg(uchar reg, uchar value)
{
uint status;
CSN = 0;
status = SPI_RW(reg);
SPI_RW(value);
CSN = 1;
return(status);
}
/*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uint status,uchar_ctr;
CSN = 0;
status = SPI_RW(reg);
status uchar
for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)
pBuf[uchar_ctr] = SPI_RW(0);
CSN = 1;
return(status); // return nRF24L01 status uchar
}
/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uint status,uchar_ctr;
CSN = 0; //SPI使能
status = SPI_RW(reg);
for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
SPI_RW(*pBuf++);
CSN = 1; //关闭SPI
return(status);
}
/*函数:void SetRX_Mode(void)
/*功能:数据接收配置
void SetRX_Mode(void)
{
CE=0;
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收
CE = 1;
inerDelay_us(130);
}
函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
/*功能:数据读取后放如rx_buf接收缓冲区中
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
{
unsigned char revale=0;
sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况
if(RX_DR) // 判断是否接收到数据
{
CE = 0; //SPI使能
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);
revale =1; //读取数据完成标志
}
SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
return revale;
}
*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
/*功能:发送 tx_buf中数据
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
CE=0; //StandBy I模式
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 + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
CE=1; //置高CE,激发数据发送
inerDelay_us(10);
}
/*以下是DHT11温度传感相关函数
void Delay1(U16 j)
{
U8 i;
for(;j>0;j--)
{
for(i=0;i<27;i++);
}
}
void Delay_10us(void)
{
U8 i;
i--;
i--;
i--;
i--;
i--;
i--;
}
void COM(void)
{
U8 i;
for(i=0;i<8;i++)
{
U8FLAG=2;
while((!P2_0)&&U8FLAG++);
Delay_10us();
Delay_10us();
Delay_10us();
U8temp=0;
if(P2_0)U8temp=1;
U8FLAG=2;
while((P2_0)&&U8FLAG++);
//超时则跳出for循环
if(U8FLAG==1)break;
//判断数据位是0还是1
// 如果高电平高过预定0高电平值则数据位为 1
U8comdata<<=1;
U8comdata|=U8temp; //0
}//rof
}
void RH(void)
{
//主机拉低18ms
P2_0=0;
Delay1(180);
P2_0=1;
//总线由上拉电阻拉高 主机延时20us
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
//主机设为输入 判断从机响应信号
P2_0=1;
//判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行
if(!P2_0) //T !
{
U8FLAG=2;
//判断从机是否发出 80us 的低电平响应信号是否结束
while((!P2_0)&&U8FLAG++);
U8FLAG=2;
//判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
while((P2_0)&&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;
P2_0=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;
}//fi
}//fi
}
//****************************温湿度处理*****************************
void work_temp()
{
dispaly[0]=U8T_data_H_temp/10;
dispaly[1]=U8T_data_H_temp%10;
dispaly[2]=U8RH_data_H/10;
dispaly[3]=U8RH_data_H%10;
//dispaly[0]=1;
//dispaly[1]=2;
//dispaly[2]=3;
//dispaly[3]=4;
}
void lcd_display()
{
LCD_disp_char(0,1,U8T_data_H/10+'0');
LCD_disp_char(1,1,U8T_data_H%10+'0');
LCD_disp_char(2,1,0x2e);
LCD_disp_char(3,1,U8T_data_L/10+'0'); LCD_disp_char(3,1,U8T_data_L/10+'0');
LCD_disp_char(4,1,0xdf);
LCD_disp_char(5,1,0x43);
LCD_disp_char(0,2,U8RH_data_H/10+'0');
LCD_disp_char(1,2,U8RH_data_H%10+'0');
LCD_disp_char(2,2,0x2e);
LCD_disp_char(3,2,U8RH_data_L/10+'0');
LCD_disp_char(4,2,0x25);
LCD_disp_char(5,2,0x52);
LCD_disp_char(6,2,0x48);
}
/*******************************主函数***************************/
void main(void)
{
uchar i=0;
P1=0xff;
P3=0xff;
init_NRF24L01() ;//NRF24L01初始化配置
lcd_init();
Delay(6000);
while(1)
{
if(i==3)
{
i=0;
RH();
work_temp();
Delay1(500);
}
i++;
lcd_display();//温度湿度显示
nRF24L01_TxPacket(dispaly); //发送数据
Delay1(500);
SPI_RW_Reg(WRITE_REG+STATUS,0XFF); //清状态寄存器
}
}
接受程序::::
#include <reg52.h>
#include <intrins.h>
typedef unsigned char uchar;
typedef unsigned char uint;
//**********************************IO端口定义*********************
sbit MISO =P1^3;
sbit MOSI =P1^1;
sbit SCK =P1^4;
sbit CE =P3^2;
sbit CSN =P1^0;
sbit IRQ =P1^2;
sbit LCD_RS = P2^7 ;
sbit LCD_RW = P2^6 ;
sbit LCD_EN = P2^5 ;
uchar temp[6];
uchar temp1[6];
uchar RxBuf[20]={0};
//**********************************NRF24L01**************************
#define TX_ADR_WIDTH 5 // 5 uints TX address width
#define RX_ADR_WIDTH 5 // 5 uints RX address width
#define TX_PLOAD_WIDTH 10 // 20 uints TX payload
#define RX_PLOAD_WIDTH 10 // 20 uints TX payload
uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址
uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
//**********************NRF24L01寄存器指令**************************
#define READ_REG 0x00 // 读寄存器指令
#define WRITE_REG 0x20 // 写寄存器指令
#define RD_RX_PLOAD 0x61 // 读取接收数据指令
#define WR_TX_PLOAD 0xA0 // 写待发数据指令
#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令
#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令
#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令
#define NOP 0xFF // 保留
//********************SPI(nRF24L01)寄存器地址*******************
#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响 应方式
#define EN_AA 0x01 // 自动应答功能设置
#define EN_RXADDR 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 // 接收频道0接收数据长度
#define RX_PW_P2 0x13 // 接收频道0接收数据长度
#define RX_PW_P3 0x14 // 接收频道0接收数据长度
#define RX_PW_P4 0x15 // 接收频道0接收数据长度
#define RX_PW_P5 0x16 // 接收频道0接收数据长度
#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置
#define delayNOP() ; {_nop_() ;_nop_() ;_nop_() ;_nop_() ;} ;
void Delay(unsigned int s);
void inerDelay_us(unsigned char n);
void init_NRF24L01(void);
uint SPI_RW(uint uchar);
uchar SPI_Read(uchar reg);
void SetRX_Mode(void);
uint SPI_RW_Reg(uchar reg, uchar value);
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);
void nRF24L01_TxPacket(unsigned char * tx_buf);
//*************************LCD1602函数声明***********************
void delay2(int ms);
bit lcd_busy();
void lcd_wcmd(uchar cmd);
void lcd_wdat(uchar dat);
void lcd_init();
void lcd_pos(uchar pos);
void LCD_disp_char(uchar x,uchar y,uchar dat);
void LCD_disp_str(uchar x,uchar y,uchar *str);
//**********************************长延时**********************
void Delay(unsigned int s)
{
unsigned int i;
for(i=0; i<s; i++);
for(i=0; i<s; i++);
}
uint bdata sta; //状态标志
sbit RX_DR =sta^6;
sbit TX_DS =sta^5;
sbit MAX_RT =sta^4;
/*延时函数
void inerDelay_us(unsigned char n)
{
for(;n>0;n--)
_nop_();
}
/*NRF24L01初始化
void init_NRF24L01(void)
{
inerDelay_us(100);
CE=0; // chip enable
CSN=1; // Spi disable
SCK=0; // Spi clock line init high
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 频道0自动 ACK应答允许
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0
SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32位
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1MHZ,发射功率为最大值0dB
}
/*函数:uint SPI_RW(uint uchar)
/*功能:NRF24L01的SPI写时序
uint SPI_RW(uint uchar)
{
uint bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++)
{
MOSI = (uchar & 0x80);
uchar = (uchar << 1);
SCK = 1;
uchar |= MISO;
SCK = 0;
}
return(uchar);
}
/*函数:uchar SPI_Read(uchar reg)
/*功能:NRF24L01的SPI时序
uchar SPI_Read(uchar reg)
{
uchar reg_val;
CSN = 0;
SPI_RW(reg);
reg_val = SPI_RW(0);
CSN = 1;
return(reg_val);
}
/*功能:NRF24L01读写寄存器函数
uint SPI_RW_Reg(uchar reg, uchar value)
{
uint status;
CSN = 0;
status = SPI_RW(reg);
SPI_RW(value);
CSN = 1;
return(status);
}
/*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uint status,uchar_ctr;
CSN = 0;
status = SPI_RW(reg);
status uchar
for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)
pBuf[uchar_ctr] = SPI_RW(0);
CSN = 1;
return(status);
}
/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uint status,uchar_ctr;
CSN = 0; //SPI使能
status = SPI_RW(reg);
for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++)
SPI_RW(*pBuf++);
CSN = 1; //关闭SPI
return(status);
}
/*功能:数据接收配置
void SetRX_Mode(void)
{
CE=0;
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收
CE = 1;
inerDelay_us(130);
}
/*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
/*功能:数据读取后放如rx_buf接收缓冲区中
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
{
unsigned char revale=0;
sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况
if(RX_DR) // 判断是否接收到数据
{
CE = 0;
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
revale =1; //读取数据完成标志
}
SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来其清除中断标志
return revale;
}
/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
/*功能:发送 tx_buf中数据
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
CE=0; //StandBy I模式
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 + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
CE=1; //置高CE,激发数据发送
inerDelay_us(10);
}
//****************LCD1602相关函数*************************************
void delay2(int ms)
{
unsigned char y ;
while(ms--)
{
for(y = 0 ; y<250 ; y++)
{
_nop_() ;
_nop_() ;
_nop_() ;
_nop_() ;
}
}
}
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
bit lcd_busy()
{
bit result ;
LCD_RS = 0 ;
LCD_RW = 1 ;
LCD_EN = 1 ;
delayNOP() ;
result = (bit)(P0&0x80) ;
LCD_EN = 0 ;
return(result) ;
}
/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
void lcd_wcmd(uchar cmd)
{
while(lcd_busy()) ;
LCD_RS = 0 ;
LCD_RW = 0 ;
LCD_EN = 0 ;
_nop_() ;
_nop_() ;
P0 = cmd ;
delayNOP() ;
LCD_EN = 1 ;
delayNOP() ;
LCD_EN = 0 ;
}
/*写显示数据到LCD */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
void lcd_wdat(uchar dat)
{
while(lcd_busy()) ;
LCD_RS = 1 ;
LCD_RW = 0 ;
LCD_EN = 0 ;
P0 = dat ;
delayNOP() ;
LCD_EN = 1 ;
delayNOP() ;
LCD_EN = 0 ;
}
/* LCD初始化设定 */
void lcd_init()
{
delay2(15) ;
lcd_wcmd(0x01) ; //清除LCD的显示内容
lcd_wcmd(0x38) ; //16*2显示,5*7点阵,8位数据
delay2(5) ;
lcd_wcmd(0x38) ;
delay2(5) ;
lcd_wcmd(0x38) ;
delay2(5) ;
lcd_wcmd(0x0c) ; //显示开,关光标
delay2(5) ;
lcd_wcmd(0x06) ; //移动光标
delay2(5) ;
lcd_wcmd(0x01) ; //清除LCD的显示内容
delay2(5) ;
}
/* 设定显示位置 */
void lcd_pos(uchar pos)
{
lcd_wcmd(pos | 0x80) ; //数据指针=80+地址变量
}
void LCD_disp_char(uchar x,uchar y,uchar dat)
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
lcd_wcmd(address);
lcd_wdat(dat);
}
/*模块名称:LCD_disp_str();
/*功 能:LCD1602显示字符串函数,在某个屏幕起始位置{X(0-15),y (1-2)}上显示一个字符串。
void LCD_disp_str(uchar x,uchar y,uchar *str)
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
lcd_wcmd(address);
while(*str!='\0')
{
lcd_wdat(*str);
str++;
}
}
//*******************LCD1602相关函数****************************
//**************************显示************************************
void lcd_display()
{
LCD_disp_char(0,1,temp[0]+0x30);
LCD_disp_char(1,1,temp[1]+0x30);
//LCD_disp_char(2,1,0x2e);
//LCD_disp_char(3,1,U8T_data_L/10+'0');
//LCD_disp_char(4,1,0xdf);
//LCD_disp_char(5,1,0x43);
LCD_disp_char(0,2,temp[3]+0x30);
LCD_disp_char(1,2,temp[2]+0x30);
//LCD_disp_char(2,2,0x2e);
//LCD_disp_char(3,2,U8RH_data_L/10+'0');
//LCD_disp_char(4,2,0x25);
//LCD_disp_char(5,2,0x52);
//LCD_disp_char(6,2,0x48);
}
/****************************主函数*********************/
void main(void)
{
uchar i=0;
P1=0xff;
P3=0xff;
init_NRF24L01() ; //NRF24L01初始化
lcd_init();
//Delay(6000);
while(1)
{
SetRX_Mode();
if(nRF24L01_RxPacket(RxBuf))
{
//temp[0]=RxBuf[1]; //温度个位
//temp[1]=RxBuf[0]; //温度十位
//temp[2]=RxBuf[3]; //湿度个位
//temp[3]=RxBuf[2]; //湿度十位
temp[0]=RxBuf[0]; //温度个位
temp[1]=RxBuf[1]; //温度十位
temp[2]=RxBuf[2]; //湿度个位
temp[3]=RxBuf[3]; //湿度十位
lcd_display(); //lcd显示温湿度
}
//lcd_display(); //lcd显示温湿度
}
}
#include <reg52.h>
#include <intrins.h>
typedef unsigned char uchar;
typedef unsigned char uint;
typedef unsigned char U8;
/*variable 无符号8位整型变量 */
typedef signed char S8;
/* variable 有符号8位整型变量 */
typedef unsigned int U16;
/*variable 无符号16位整型变量 */
typedef signed int S16;
/*variable 有符号16位整型变量 */
typedef unsigned long U32;
/*variable 无符号32位整型变量 */
typedef signed long S32;
/*variable 有符号32位整型变量 */
typedef float F32;
/*variable (32bits) 单精度浮点数(32位长度) */
typedef double F64;
/*variable (64bits) 双精度浮点数(64位长度) */
//***************************IO端口定*********************************
sbit MISO =P1^3;
sbit MOSI =P1^1;
sbit SCK =P1^4;
sbit CE =P3^2;
sbit CSN =P1^0;
sbit IRQ =P1^2;
sbit LCD_RS = P2^7 ;
sbit LCD_RW = P2^6 ;
sbit LCD_EN = P2^5 ;
//**************************DHT11端口设******************************
sbit P2_0 = P2^0 ;
U8 U8FLAG,k;
U8 U8count,U8temp;
U8 U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
U8 U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
U8 U8comdata;
uchar data temp_data[2]={0x00,0x00}; //温度湿度采集数据缓冲区
uchar dispaly[4]; //显示缓冲区
uint bdata sta; //NRF24L01状态标志
sbit RX_DR =sta^6;
sbit TX_DS =sta^5;
sbit MAX_RT =sta^4;
//*************************************NRF24L01***********************
#define TX_ADR_WIDTH 5 // 本机地址宽度设置
#define RX_ADR_WIDTH 5 // 接收方地址宽度设置
#define TX_PLOAD_WIDTH 10 // 4 字节数据长度
#define RX_PLOAD_WIDTH 10 // 4 字节数据长度
uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址
uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
//***************NRF24L01寄存器指令****************
#define READ_REG 0x00 // 读寄存器指令
#define WRITE_REG 0x20 // 写寄存器指令
#define RD_RX_PLOAD 0x61 // 读取接收数据指令
#define WR_TX_PLOAD 0xA0 // 写待发数据指令
#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令
#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令
#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令
#define NOP 0xFF // 保留
//*************SPI(nRF24L01)寄存器地址**************
#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA 0x01 // 自动应答功能设置
#define EN_RXADDR 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 // 接收频道0接收数据长度
#define RX_PW_P2 0x13 // 接收频道0接收数据长度
#define RX_PW_P3 0x14 // 接收频道0接收数据长度
#define RX_PW_P4 0x15 // 接收频道0接收数据长度
#define RX_PW_P5 0x16 // 接收频道0接收数据长度
#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置
#define delayNOP() ; {_nop_() ;_nop_() ;_nop_() ;_nop_() ;} ;
//************************************NRF24L01函数申明****************
void Delay(unsigned int s);
void inerDelay_us(unsigned char n);
void init_NRF24L01(void);
uint SPI_RW(uint uchar);
uchar SPI_Read(uchar reg);
void SetRX_Mode(void);
uint SPI_RW_Reg(uchar reg, uchar value);
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);
void nRF24L01_TxPacket(unsigned char * tx_buf);
//**************************DHT11函数申明************************
void Delay1(U16 j);
void Delay_10us(void);
void COM(void);
void RH(void);
//***************************LCD1602函数声明*************************
void delay2(int ms);
bit lcd_busy();
void lcd_wcmd(uchar cmd);
void lcd_wdat(uchar dat);
void lcd_init();
void lcd_pos(uchar pos);
void LCD_disp_char(uchar x,uchar y,uchar dat);
void LCD_disp_str(uchar x,uchar y,uchar *str);
//***************************LCD1602相关函数************************
void delay2(int ms)
{
unsigned char y ;
while(ms--)
{
for(y = 0 ; y<250 ; y++)
{
_nop_() ;
_nop_() ;
_nop_() ;
_nop_() ;
}
}
}
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
bit lcd_busy()
{
bit result ;
LCD_RS = 0 ;
LCD_RW = 1 ;
LCD_EN = 1 ;
delayNOP() ;
result = (bit)(P0&0x80) ;
LCD_EN = 0 ;
return(result) ;
}
/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
void lcd_wcmd(uchar cmd)
{
while(lcd_busy()) ;
LCD_RS = 0 ;
LCD_RW = 0 ;
LCD_EN = 0 ;
_nop_() ;
_nop_() ;
P0 = cmd ;
delayNOP() ;
LCD_EN = 1 ;
delayNOP() ;
LCD_EN = 0 ;
}
/*写显示数据到LCD */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
void lcd_wdat(uchar dat)
{
while(lcd_busy()) ;
LCD_RS = 1 ;
LCD_RW = 0 ;
LCD_EN = 0 ;
P0 = dat ;
delayNOP() ;
LCD_EN = 1 ;
delayNOP() ;
LCD_EN = 0 ;
}
/* LCD初始化设定 */
void lcd_init()
{
delay2(15) ;
lcd_wcmd(0x01) ; //清除LCD的显示内容
lcd_wcmd(0x38) ; //16*2显示,5*7点阵,8位数据
delay2(5) ;
lcd_wcmd(0x38) ;
delay2(5) ;
lcd_wcmd(0x38) ;
delay2(5) ;
lcd_wcmd(0x0c) ; //显示开,关光标
delay2(5) ;
lcd_wcmd(0x06) ; //移动光标
delay2(5) ;
lcd_wcmd(0x01) ; //清除LCD的显示内容
delay2(5) ;
}
/* 设定显示位置 */
void lcd_pos(uchar pos)
{
lcd_wcmd(pos | 0x80) ; //数据指针=80+地址变量
}
void LCD_disp_char(uchar x,uchar y,uchar dat)
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
lcd_wcmd(address);
lcd_wdat(dat);
}
/*模块名称:LCD_disp_str();
/*功 能:LCD1602显示字符串函数,在某个屏幕起始位置{X(0-15),y (1-2)}上显示一个字符串。
void LCD_disp_str(uchar x,uchar y,uchar *str)
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
lcd_wcmd(address);
while(*str!='\0')
{
lcd_wdat(*str);
str++;
}
}
//*******************LCD1602相关函数结束*********************
//**************************长延时****************************
void Delay(unsigned int s)
{
unsigned int i;
for(i=0; i<s; i++);
for(i=0; i<s; i++);
}
/*延时函数
void inerDelay_us(unsigned char n)
{
for(;n>0;n--)
_nop_();
}
/*NRF24L01初始化
void init_NRF24L01(void)
{
inerDelay_us(100);
CE=0;
CSN=1;
SCK=0;
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 频道0自动 ACK应答允许
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0
SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为4字节
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1Mkbps,发射功率为最大值0dB
}
/*函数:uint SPI_RW(uint uchar)
/*功能:NRF24L01的SPI写时序
uint SPI_RW(uint uchar)
{
uint bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++)
{
MOSI = (uchar & 0x80); I
uchar = (uchar << 1);
SCK = 1;
uchar |= MISO;
SCK = 0;
}
return(uchar);
}
/*函数:uchar SPI_Read(uchar reg)
/*功能:NRF24L01的SPI时序
uchar SPI_Read(uchar reg)
{
uchar reg_val;
CSN = 0;
SPI_RW(reg);
reg_val = SPI_RW(0);
CSN = 1;
return(reg_val);
}
/*功能:NRF24L01读写寄存器函数,
uint SPI_RW_Reg(uchar reg, uchar value)
{
uint status;
CSN = 0;
status = SPI_RW(reg);
SPI_RW(value);
CSN = 1;
return(status);
}
/*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uint status,uchar_ctr;
CSN = 0;
status = SPI_RW(reg);
status uchar
for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)
pBuf[uchar_ctr] = SPI_RW(0);
CSN = 1;
return(status); // return nRF24L01 status uchar
}
/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uint status,uchar_ctr;
CSN = 0; //SPI使能
status = SPI_RW(reg);
for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
SPI_RW(*pBuf++);
CSN = 1; //关闭SPI
return(status);
}
/*函数:void SetRX_Mode(void)
/*功能:数据接收配置
void SetRX_Mode(void)
{
CE=0;
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收
CE = 1;
inerDelay_us(130);
}
函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
/*功能:数据读取后放如rx_buf接收缓冲区中
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
{
unsigned char revale=0;
sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况
if(RX_DR) // 判断是否接收到数据
{
CE = 0; //SPI使能
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);
revale =1; //读取数据完成标志
}
SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
return revale;
}
*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
/*功能:发送 tx_buf中数据
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
CE=0; //StandBy I模式
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 + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
CE=1; //置高CE,激发数据发送
inerDelay_us(10);
}
/*以下是DHT11温度传感相关函数
void Delay1(U16 j)
{
U8 i;
for(;j>0;j--)
{
for(i=0;i<27;i++);
}
}
void Delay_10us(void)
{
U8 i;
i--;
i--;
i--;
i--;
i--;
i--;
}
void COM(void)
{
U8 i;
for(i=0;i<8;i++)
{
U8FLAG=2;
while((!P2_0)&&U8FLAG++);
Delay_10us();
Delay_10us();
Delay_10us();
U8temp=0;
if(P2_0)U8temp=1;
U8FLAG=2;
while((P2_0)&&U8FLAG++);
//超时则跳出for循环
if(U8FLAG==1)break;
//判断数据位是0还是1
// 如果高电平高过预定0高电平值则数据位为 1
U8comdata<<=1;
U8comdata|=U8temp; //0
}//rof
}
void RH(void)
{
//主机拉低18ms
P2_0=0;
Delay1(180);
P2_0=1;
//总线由上拉电阻拉高 主机延时20us
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
//主机设为输入 判断从机响应信号
P2_0=1;
//判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行
if(!P2_0) //T !
{
U8FLAG=2;
//判断从机是否发出 80us 的低电平响应信号是否结束
while((!P2_0)&&U8FLAG++);
U8FLAG=2;
//判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
while((P2_0)&&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;
P2_0=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;
}//fi
}//fi
}
//****************************温湿度处理*****************************
void work_temp()
{
dispaly[0]=U8T_data_H_temp/10;
dispaly[1]=U8T_data_H_temp%10;
dispaly[2]=U8RH_data_H/10;
dispaly[3]=U8RH_data_H%10;
//dispaly[0]=1;
//dispaly[1]=2;
//dispaly[2]=3;
//dispaly[3]=4;
}
void lcd_display()
{
LCD_disp_char(0,1,U8T_data_H/10+'0');
LCD_disp_char(1,1,U8T_data_H%10+'0');
LCD_disp_char(2,1,0x2e);
LCD_disp_char(3,1,U8T_data_L/10+'0'); LCD_disp_char(3,1,U8T_data_L/10+'0');
LCD_disp_char(4,1,0xdf);
LCD_disp_char(5,1,0x43);
LCD_disp_char(0,2,U8RH_data_H/10+'0');
LCD_disp_char(1,2,U8RH_data_H%10+'0');
LCD_disp_char(2,2,0x2e);
LCD_disp_char(3,2,U8RH_data_L/10+'0');
LCD_disp_char(4,2,0x25);
LCD_disp_char(5,2,0x52);
LCD_disp_char(6,2,0x48);
}
/*******************************主函数***************************/
void main(void)
{
uchar i=0;
P1=0xff;
P3=0xff;
init_NRF24L01() ;//NRF24L01初始化配置
lcd_init();
Delay(6000);
while(1)
{
if(i==3)
{
i=0;
RH();
work_temp();
Delay1(500);
}
i++;
lcd_display();//温度湿度显示
nRF24L01_TxPacket(dispaly); //发送数据
Delay1(500);
SPI_RW_Reg(WRITE_REG+STATUS,0XFF); //清状态寄存器
}
}
接受程序::::
#include <reg52.h>
#include <intrins.h>
typedef unsigned char uchar;
typedef unsigned char uint;
//**********************************IO端口定义*********************
sbit MISO =P1^3;
sbit MOSI =P1^1;
sbit SCK =P1^4;
sbit CE =P3^2;
sbit CSN =P1^0;
sbit IRQ =P1^2;
sbit LCD_RS = P2^7 ;
sbit LCD_RW = P2^6 ;
sbit LCD_EN = P2^5 ;
uchar temp[6];
uchar temp1[6];
uchar RxBuf[20]={0};
//**********************************NRF24L01**************************
#define TX_ADR_WIDTH 5 // 5 uints TX address width
#define RX_ADR_WIDTH 5 // 5 uints RX address width
#define TX_PLOAD_WIDTH 10 // 20 uints TX payload
#define RX_PLOAD_WIDTH 10 // 20 uints TX payload
uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址
uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
//**********************NRF24L01寄存器指令**************************
#define READ_REG 0x00 // 读寄存器指令
#define WRITE_REG 0x20 // 写寄存器指令
#define RD_RX_PLOAD 0x61 // 读取接收数据指令
#define WR_TX_PLOAD 0xA0 // 写待发数据指令
#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令
#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令
#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令
#define NOP 0xFF // 保留
//********************SPI(nRF24L01)寄存器地址*******************
#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响 应方式
#define EN_AA 0x01 // 自动应答功能设置
#define EN_RXADDR 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 // 接收频道0接收数据长度
#define RX_PW_P2 0x13 // 接收频道0接收数据长度
#define RX_PW_P3 0x14 // 接收频道0接收数据长度
#define RX_PW_P4 0x15 // 接收频道0接收数据长度
#define RX_PW_P5 0x16 // 接收频道0接收数据长度
#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置
#define delayNOP() ; {_nop_() ;_nop_() ;_nop_() ;_nop_() ;} ;
void Delay(unsigned int s);
void inerDelay_us(unsigned char n);
void init_NRF24L01(void);
uint SPI_RW(uint uchar);
uchar SPI_Read(uchar reg);
void SetRX_Mode(void);
uint SPI_RW_Reg(uchar reg, uchar value);
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);
void nRF24L01_TxPacket(unsigned char * tx_buf);
//*************************LCD1602函数声明***********************
void delay2(int ms);
bit lcd_busy();
void lcd_wcmd(uchar cmd);
void lcd_wdat(uchar dat);
void lcd_init();
void lcd_pos(uchar pos);
void LCD_disp_char(uchar x,uchar y,uchar dat);
void LCD_disp_str(uchar x,uchar y,uchar *str);
//**********************************长延时**********************
void Delay(unsigned int s)
{
unsigned int i;
for(i=0; i<s; i++);
for(i=0; i<s; i++);
}
uint bdata sta; //状态标志
sbit RX_DR =sta^6;
sbit TX_DS =sta^5;
sbit MAX_RT =sta^4;
/*延时函数
void inerDelay_us(unsigned char n)
{
for(;n>0;n--)
_nop_();
}
/*NRF24L01初始化
void init_NRF24L01(void)
{
inerDelay_us(100);
CE=0; // chip enable
CSN=1; // Spi disable
SCK=0; // Spi clock line init high
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 频道0自动 ACK应答允许
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0
SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32位
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1MHZ,发射功率为最大值0dB
}
/*函数:uint SPI_RW(uint uchar)
/*功能:NRF24L01的SPI写时序
uint SPI_RW(uint uchar)
{
uint bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++)
{
MOSI = (uchar & 0x80);
uchar = (uchar << 1);
SCK = 1;
uchar |= MISO;
SCK = 0;
}
return(uchar);
}
/*函数:uchar SPI_Read(uchar reg)
/*功能:NRF24L01的SPI时序
uchar SPI_Read(uchar reg)
{
uchar reg_val;
CSN = 0;
SPI_RW(reg);
reg_val = SPI_RW(0);
CSN = 1;
return(reg_val);
}
/*功能:NRF24L01读写寄存器函数
uint SPI_RW_Reg(uchar reg, uchar value)
{
uint status;
CSN = 0;
status = SPI_RW(reg);
SPI_RW(value);
CSN = 1;
return(status);
}
/*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uint status,uchar_ctr;
CSN = 0;
status = SPI_RW(reg);
status uchar
for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)
pBuf[uchar_ctr] = SPI_RW(0);
CSN = 1;
return(status);
}
/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uint status,uchar_ctr;
CSN = 0; //SPI使能
status = SPI_RW(reg);
for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++)
SPI_RW(*pBuf++);
CSN = 1; //关闭SPI
return(status);
}
/*功能:数据接收配置
void SetRX_Mode(void)
{
CE=0;
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收
CE = 1;
inerDelay_us(130);
}
/*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
/*功能:数据读取后放如rx_buf接收缓冲区中
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
{
unsigned char revale=0;
sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况
if(RX_DR) // 判断是否接收到数据
{
CE = 0;
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
revale =1; //读取数据完成标志
}
SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来其清除中断标志
return revale;
}
/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
/*功能:发送 tx_buf中数据
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
CE=0; //StandBy I模式
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 + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
CE=1; //置高CE,激发数据发送
inerDelay_us(10);
}
//****************LCD1602相关函数*************************************
void delay2(int ms)
{
unsigned char y ;
while(ms--)
{
for(y = 0 ; y<250 ; y++)
{
_nop_() ;
_nop_() ;
_nop_() ;
_nop_() ;
}
}
}
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
bit lcd_busy()
{
bit result ;
LCD_RS = 0 ;
LCD_RW = 1 ;
LCD_EN = 1 ;
delayNOP() ;
result = (bit)(P0&0x80) ;
LCD_EN = 0 ;
return(result) ;
}
/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
void lcd_wcmd(uchar cmd)
{
while(lcd_busy()) ;
LCD_RS = 0 ;
LCD_RW = 0 ;
LCD_EN = 0 ;
_nop_() ;
_nop_() ;
P0 = cmd ;
delayNOP() ;
LCD_EN = 1 ;
delayNOP() ;
LCD_EN = 0 ;
}
/*写显示数据到LCD */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
void lcd_wdat(uchar dat)
{
while(lcd_busy()) ;
LCD_RS = 1 ;
LCD_RW = 0 ;
LCD_EN = 0 ;
P0 = dat ;
delayNOP() ;
LCD_EN = 1 ;
delayNOP() ;
LCD_EN = 0 ;
}
/* LCD初始化设定 */
void lcd_init()
{
delay2(15) ;
lcd_wcmd(0x01) ; //清除LCD的显示内容
lcd_wcmd(0x38) ; //16*2显示,5*7点阵,8位数据
delay2(5) ;
lcd_wcmd(0x38) ;
delay2(5) ;
lcd_wcmd(0x38) ;
delay2(5) ;
lcd_wcmd(0x0c) ; //显示开,关光标
delay2(5) ;
lcd_wcmd(0x06) ; //移动光标
delay2(5) ;
lcd_wcmd(0x01) ; //清除LCD的显示内容
delay2(5) ;
}
/* 设定显示位置 */
void lcd_pos(uchar pos)
{
lcd_wcmd(pos | 0x80) ; //数据指针=80+地址变量
}
void LCD_disp_char(uchar x,uchar y,uchar dat)
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
lcd_wcmd(address);
lcd_wdat(dat);
}
/*模块名称:LCD_disp_str();
/*功 能:LCD1602显示字符串函数,在某个屏幕起始位置{X(0-15),y (1-2)}上显示一个字符串。
void LCD_disp_str(uchar x,uchar y,uchar *str)
{
uchar address;
if(y==1)
address=0x80+x;
else
address=0xc0+x;
lcd_wcmd(address);
while(*str!='\0')
{
lcd_wdat(*str);
str++;
}
}
//*******************LCD1602相关函数****************************
//**************************显示************************************
void lcd_display()
{
LCD_disp_char(0,1,temp[0]+0x30);
LCD_disp_char(1,1,temp[1]+0x30);
//LCD_disp_char(2,1,0x2e);
//LCD_disp_char(3,1,U8T_data_L/10+'0');
//LCD_disp_char(4,1,0xdf);
//LCD_disp_char(5,1,0x43);
LCD_disp_char(0,2,temp[3]+0x30);
LCD_disp_char(1,2,temp[2]+0x30);
//LCD_disp_char(2,2,0x2e);
//LCD_disp_char(3,2,U8RH_data_L/10+'0');
//LCD_disp_char(4,2,0x25);
//LCD_disp_char(5,2,0x52);
//LCD_disp_char(6,2,0x48);
}
/****************************主函数*********************/
void main(void)
{
uchar i=0;
P1=0xff;
P3=0xff;
init_NRF24L01() ; //NRF24L01初始化
lcd_init();
//Delay(6000);
while(1)
{
SetRX_Mode();
if(nRF24L01_RxPacket(RxBuf))
{
//temp[0]=RxBuf[1]; //温度个位
//temp[1]=RxBuf[0]; //温度十位
//temp[2]=RxBuf[3]; //湿度个位
//temp[3]=RxBuf[2]; //湿度十位
temp[0]=RxBuf[0]; //温度个位
temp[1]=RxBuf[1]; //温度十位
temp[2]=RxBuf[2]; //湿度个位
temp[3]=RxBuf[3]; //湿度十位
lcd_display(); //lcd显示温湿度
}
//lcd_display(); //lcd显示温湿度
}
}
有时间就帮你看看
板子弄好了 ,但是只是液晶亮了而已 。
------------------
调一下RP电位器 有可能是液晶屏的对比度没调好
小编做好了?单路的么?我的是多路采集。还有其他数据要一起传过去。蛋疼死了
小编一句液晶亮了,就发这么一大堆程序给我们看,我们也很难找出原因。这个还得你自己一步步去分析到地问题出在哪里。首先液晶亮了是正常显示还是只有背光。如果没有正常显示就烧一个简单的显示程序进去。看看液晶是硬件问题还是软件问题。如果液晶正常显示,那就看看DHT11和nrf2401能不能显示。一步步缩小问题的范围才能找到问题的所在,才能对症下药。另外提一点。DHT11的数据端口DATA接一个5k的上拉电阻.
第一步:检查lcd1602的外围电路设置
第二步:单个程序调试,先看看最基本的lcd驱动是否正常,再去做程序的叠加。
第三步:遇到问题要一步一步跟踪调试是最好的解决办法
谢谢小编分享,学习中。
这是求助好吧,你是不为了积分去的啊,有没有看啊!
请问你现在做好了没?急求啊,做好了可以给我发一份不。蛋疼啊!感激不尽
小编现在做好没?
有可能是,模块没有搞好,有没有可能呢
网上有搞好的程序,
可以发份给我吗?
我现在也在做这个,但是没有程序、、、
好好学习好好学习
参考下小编的谢谢