#include<reg51.h>
#include<intrins.h>
#include "lcd1602.h"
//
typedef unsigned char U8; /* defined for unsigned 8-bits integer variable 无符号8位整型变量 */
typedef signed char S8; /* defined for signed 8-bits integer variable 有符号8位整型变量 */
typedef unsigned int U16; /* defined for unsigned 16-bits integer variable 无符号16位整型变量 */
typedef signed int S16; /* defined for signed 16-bits integer variable 有符号16位整型变量 */
typedef unsigned long U32; /* defined for unsigned 32-bits integer variable 无符号32位整型变量 */
typedef signed long S32; /* defined for signed 32-bits integer variable 有符号32位整型变量 */
typedef float F32; /* single precision floating point variable (32bits) 单精度浮点数(32位长度) */
typedef double F64; /* double precision floating point variable (64bits) 双精度浮点数(64位长度) */
//
#define uchar unsigned char
#define uint unsigned int
const uchar TX_ADDRESS[TX_ADR_WIDTH]={0xFF,0xFF,0xFF,0xFF,0xFF}; //发送地址
const uchar RX_ADDRESS[RX_ADR_WIDTH]={0xFF,0xFF,0xFF,0xFF,0xFF}; //发送地址
sbit NRF_CE = P1^5;
sbit NRF_SCK = P1^4;
sbit NRF_MISO = P1^3;
sbit NRF_CSN = P1^2;
sbit NRF_MOSI = P1^1;
sbit NRF_IRQ = P1^0;
sbit BEEP=P3^6;
sbit key=P3^2;
sbit LED2=P1^7;
uchar Rx_buf[32];
/*******函数的声明************/
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData); //指定位置显示一个字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData); //指定位置显示一串字符
void RH_Init(U8 *humi,U8 *temp);
void Init_Timer0(void);
void Delay400Ms(); //
void LCMInit(); //LCM初始化
void Delay5Ms();
/*******变量的定义************/
U8 code rh[] ={" RH: "};
U8 code tmp[] ={" temp: "};
U8 code nrf1[] ={" NRF2401 OK!"};
U8 code nrf2[] ={" NRF2401 Error!"};
/***************************************************************/
/*********************2401所需延时函数***************************/
/*******************************************************************/
void delay_us(uchar num)
{
uchar i;
for(i=0;i>num;i++)
_nop_();
}
void delay_150us()
{
uint i;
for(i=0;i>150;i++);
}
void delay(uint t)
{
uchar k;
while(t--)
for(k=0;k<200;k++);
}
/***************************************************************/
/*写地址,读数据
/*******************************************************************/
uchar SPI_RW(uchar byte)
{
uchar bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // 输出8位
{
NRF_MOSI=(byte&0x80); // MSB TO MOSI
byte=(byte<<1); // shift next bit to MSB
NRF_SCK=1;
byte|=NRF_MISO; // capture current MISO bit
NRF_SCK=0;
}
return byte;
}
/*********************************************/
/* 函数功能:给24L01的寄存器写值(一个字节) */
/* 入口参数:reg 要写的寄存器地址 */
/* value 给寄存器写的值 */
/* 出口参数:status 状态值 */
/*********************************************/
uchar NRF24L01_Write_Reg(uchar reg,uchar value)
{
uchar status;
NRF_CSN=0; //CSN=0;
status = SPI_RW(reg); //发送寄存器地址,并读取状态值
SPI_RW(value);
NRF_CSN=1; //CSN=1;
return status;
}
/*************************************************/
/* 函数功能:读24L01的寄存器值 (一个字节) */
/* 入口参数:reg 要读的寄存器地址 */
/* 出口参数:value 读出寄存器的值 */
/*************************************************/
uchar NRF24L01_Read_Reg(uchar reg)
{
uchar value;
NRF_CSN=0; //CSN=0;
SPI_RW(reg); //发送寄存器值(位置),并读取状态值
value = SPI_RW(NOP);
NRF_CSN=1; //CSN=1;
return value;
}
/*********************************************/
/* 函数功能:读24L01的寄存器值(多个字节) */
/* 入口参数:reg 寄存器地址 */
/* *pBuf 读出寄存器值的存放数组 */
/* len 数组字节长度 */
/* 出口参数:status 状态值 */
/*********************************************/
uchar NRF24L01_Read_Buf(uchar reg,uchar *pBuf,uchar len)
{
uchar status,u8_ctr;
NRF_CSN=0; //CSN=0
status=SPI_RW(reg); //发送寄存器地址,并读取状态值
for(u8_ctr=0;u8_ctr<len;u8_ctr++)
pBuf[u8_ctr]=SPI_RW(0XFF); //读出数据
NRF_CSN=1; //CSN=1
return status; //返回读到的状态值
}
/**********************************************/
/* 函数功能:给24L01的寄存器写值(多个字节) */
/* 入口参数:reg 要写的寄存器地址 */
/* *pBuf 值的存放数组 */
/* len 数组字节长度 */
/**********************************************/
uchar NRF24L01_Write_Buf(uchar reg, uchar *pBuf, uchar len)
{
uchar status,u8_ctr;
NRF_CSN=0;
status = SPI_RW(reg); //发送寄存器值(位置),并读取状态值
for(u8_ctr=0; u8_ctr<len; u8_ctr++)
SPI_RW(*pBuf++); //写入数据
NRF_CSN=1;
return status; //返回读到的状态值
}
/*********************************************/
/* 函数功能:24L01接收数据 */
/* 入口参数:rxbuf 接收数据数组 */
/* 返回值: 0 成功收到数据 */
/* 1 没有收到数据 */
/*********************************************/
uchar NRF24L01_RxPacket(uchar *rxbuf)
{
uchar state;
state=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值
NRF24L01_Write_Reg(WRITE_REG+STATUS,state); //清除TX_DS或MAX_RT中断标志
if(state&RX_OK) //接收到数据
{
NRF_CE = 0;
NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
NRF24L01_Write_Reg(FLUSH_RX,0xff); //清除RX FIFO寄存器
NRF_CE = 1;
delay_150us();
return 0;
}
return 1;//没收到任何数据
}
/**********************************************/
/* 函数功能:设置24L01为发送模式 */
/* 入口参数:txbuf 发送数据数组 */
/* 返回值; 0x10 达到最大重发次数,发送失败*/
/* 0x20 成功发送完成 */
/* 0xff 发送失败 */
/**********************************************/
uchar NRF24L01_TxPacket(uchar *txbuf)
{
uchar state;
NRF_CE=0; //CE拉低,使能24L01配置
NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH); //写数据到TX BUF 32个字节
NRF_CE=1; //CE置高,使能发送
while(NRF_IRQ==1); //等待发送完成
state=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值
NRF24L01_Write_Reg(WRITE_REG+STATUS,state); //清除TX_DS或MAX_RT中断标志
if(state&MAX_TX) //达到最大重发次数
{
NRF24L01_Write_Reg(FLUSH_TX,0xff); //清除TX FIFO寄存器
return MAX_TX;
}
if(state&TX_OK) //发送完成
{
return TX_OK;
}
return 0xff; //发送失败
}
/********************************************/
/* 函数功能:检测24L01是否存在 */
/* 返回值; 0 存在 */
/* 1 不存在 */
/********************************************/
uchar NRF24L01_Check(void)
{
uchar check_in_buf[5]={0x11,0x22,0x33,0x44,0x55};
uchar check_out_buf[5]={0x00};
NRF_SCK=0;
NRF_CSN=1;
NRF_CE=0;
NRF24L01_Write_Buf(WRITE_REG+TX_ADDR, check_in_buf, 5);
NRF24L01_Read_Buf(READ_REG+TX_ADDR, check_out_buf, 5);
if((check_out_buf[0] == 0x11)&&\
(check_out_buf[1] == 0x22)&&\
(check_out_buf[2] == 0x33)&&\
(check_out_buf[3] == 0x44)&&\
(check_out_buf[4] == 0x55))return 0;
else return 1;
}
/*********************************************/
/*******函数功能:24L01初始化 ***/
/*********************************************/
void NRF24L01_RT_Init(void)
{
NRF_CE=0;
NRF24L01_Write_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度
NRF24L01_Write_Reg(FLUSH_RX,0xff); //清除RX FIFO寄存器
NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,(uchar*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址
NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,(uchar*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK
NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x01); //使能通道0的自动应答
NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址
NRF24L01_Write_Reg(WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
NRF24L01_Write_Reg(WRITE_REG+RF_CH,0); //设置RF通道为2.400GHz 频率=2.4+0GHz
NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x0F); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启
NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0f); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断
NRF_CE=1; //CE置高,使能发送
}
/*********************************************/
/*******函数功能:发送数据 ***/
/*********************************************/
void SEND_BUF(uchar *buf)
{
NRF_CE=0;
NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0e);
NRF_CE=1;
delay_us(15);
NRF24L01_TxPacket(buf);
NRF_CE=0;
NRF24L01_Write_Reg(WRITE_REG+CONFIG, 0x0f);
NRF_CE=1;
}
/*********************************************/
/******************main函数*************** ***/
/*********************************************/
void main(void)
{
U8 temperature;
U8 humidity;
Init_Timer0();
Delay400Ms(); //启动等待,等LCM讲入工作状态
LCMInit(); //LCM初始化
Delay5Ms(); //延时片刻
while(NRF24L01_Check()) // 等待检测到NRF24L01,程序才会向下执行
{
DisplayListChar(2, 0, nrf2);
Delay400Ms();
}
NRF24L01_RT_Init();
Delay5Ms();
Delay5Ms();
Delay5Ms();
Delay5Ms();
LCMInit(); //LCM初始化
DisplayListChar(2, 0, nrf1);
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
Delay400Ms();
LED2=1;
Delay400Ms();//延时片刻
LCMInit(); //LCM初始化
LED2=0;
DisplayListChar(0, 0, rh);
DisplayListChar(0, 1, tmp);
DisplayOneChar(6, 0, '%');
DisplayOneChar(8, 1, 'C');
while(1)
{
if(NRF_IRQ==0) // 如果无线模块接收到数据
{
if(NRF24L01_RxPacket(Rx_buf)==0)
{
//LCMInit(); //LCM初始化
Delay5Ms(); //延时片刻
DisplayOneChar(4, 0,Rx_buf[1]+0x30);
DisplayOneChar(5, 0,Rx_buf[2]+0x30);
DisplayOneChar(6, 1,Rx_buf[3]+0x30);
DisplayOneChar(7, 1,Rx_buf[4]+0x30);
}
}
// LED2=0;
Delay400Ms();
}
}
/*********************************************************
500us延时函数
晶振:11.0592MHz
*********************************************************/
void delay500(void)
{
uchar i;
for(i=230;i>0;i--);
}
//超温、超湿进入中断
/*
********************************************************************************
** 函数名称 : Init_Timer0(void)
** 函数功能 : 定时器初始化子程序
********************************************************************************
*/
void Init_Timer0(void) //定时器初始化子程序
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0=(65536-46080)/256; //装初值11.0592M晶振定时50ms数为46080
TL0=(65536-46080)%256;
EA=1; //总中断打开
ET0=1; //定时器中断打开
TR0=1; //定时器开关打开
}
/*
********************************************************************************
** 函数名称 : Timer0_isr(void) interrupt 1 using 1
** 函数功能 : 定时器中断程序
********************************************************************************
*/
void Timer0_isr(void) interrupt 1 using 1
{
TH0=(65536-46080)/256; //装初值11.0592M晶振定时50ms数为46080
TL0=(65536-46080)%256;
if(Rx_buf[1]>7||Rx_buf[3]>2)
{
BEEP=0;
delay500();
BEEP=1;
delay500();
}
else BEEP=1;
}
51单片机控制NRF24L01发送和接受数据
最新推荐文章于 2023-03-10 16:59:42 发布