分享

51单片机应用之无线通讯模块NRF24L01+

 共同成长888 2022-03-12

本教程关于NRF24L01+的内容十分详细,对于大家的学习和调试及其有帮助

图片1.png

内含详细教程:
0.png0.png0.png0.png0.jpg 



单片机源程序如下:

接下来我们写发送程序:

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

//   NRF24L01+模块发射程序

//      用8个LED调试

//   Txz001 2012.05.16

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

#include

typedef unsigned char uchar; //将无符号字节类型重定义为uchar

typedef unsigned int uint;  //将无符号整数类型重定义为Uint

//*********************NRF24L01函数定义****************************

void delayms(uint t);//毫秒延时

void init_NRF24L01(void);   //模块初始化函数

uchar SPI_RW(uchar reg);    //基本SPI读写时序

uchar SPI_Read(uchar reg);  //从寄存器reg读一个字节

void SetRX_Mode(void);      //设置接收模式

uchar SPI_RW_Reg(uchar reg, uchar value);  //向寄存器写一个字节

uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars); // 从缓冲器读出uchars字节的数据

uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars); //向缓冲器写进uchars字节的数据

void nRF24L01_TxPacket(uchar * tx_buf); //启动一次发送

uchar nRF24L01_RxPacket(uchar * rx_buf);//读取接收的数据,放入rx_buf数组

//***********NRF24L01模块IO端口定义******************

sbit CE=P1^0;

sbit CSN =P1^1;

sbit SCK =P1^2;

sbit MOSI =P1^3;

sbit MISO =P1^4;

sbit IRQ =P1^5;

//*****************NRF24L01常量**********************

#define TX_ADR_WIDTH    5    //发送地址宽度 5字节

#define RX_ADR_WIDTH    5    //接收地址宽度 5字节

#define TX_PLOAD_WIDTH  32   // 发送数据宽度 32字节

#define RX_PLOAD_WIDTH  32   //接收数据的宽度 32字节

uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x01,0x02,0x03,0x04,0x05}; //本地地址

uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x01,0x02,0x03,0x04,0x05}; //接收地址

//*****************NRF24L01寄存器指令*******************

#define READ_REG        0x00   // 读寄存器指令

#define WRITE_REG       0x20  // 写寄存器指令

#define RD_RX_PLOAD     0x61   // 读取接收数据指令

#define WR_TX_PLOAD     0xA0   // 写待发数据指令

#define FLUSH_TX        0xE1   //清空发送缓冲区

//**************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栈入栈出状态寄存器设置

/*****毫秒延时子程序*****/

void delayms(uint t)     //约延时t毫秒

{

  uint i;

  while(t--)

    {

     for(i=0;i<125;i++);

    }        

}

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

/*函数:uint SPI_RW(uint uchar)

/*功能:NRF24L01的SPI写时序

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

uchar SPI_RW(uchar uuchar)

{

uchar bit_ctr;

    for(bit_ctr=0;bit_ctr<8;bit_ctr++) // 输出8个位

    {

  MOSI = (uuchar & 0x80);     //输出uuhar的最高位

  uuchar = (uuchar << 1);     //左移一位

  SCK = 1;                    // 将时钟线置'1’

  uuchar |= MISO;             //同时读取STATUS

  SCK = 0;                //然后再将时钟线置'0’

    }

    return(uuchar);               //返回读取的值

}

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

/*函数:uchar SPI_Read(uchar reg)

/*功能:NRF24L01的SPI读取一个字节时序

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

uchar SPI_Read(uchar reg)

{

uchar reg_val;

CSN = 0;             //CSN置'0',允许指令操作

SPI_RW(reg);            //写一条reg指令

reg_val = SPI_RW(0);    //读取reg的值到reg_val

CSN = 1;                //CSN置'1',禁示操作

return(reg_val);        //返回读取的值

}

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

/*功能:NRF24L01写一个字节到寄存器函数

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

uchar SPI_RW_Reg(uchar reg, uchar value)

{

uchar status;

  

CSN = 0;                   // CSN置'0',允许操作

status = SPI_RW(reg);      //这指令,并读STATUS

SPI_RW(value);             //写数据值到reg

CSN = 1;                   // CSN置'1',禁止操作

return(status);            // return nRF24L01 status uchar

}

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

/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)

/*功能: 用于写数据:reg:为寄存器地址,

/*                  pBuf:为待写入数据地址,

/*                  uchars:写入数据的个数

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

uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)

{

uchar status,uchar_ctr;

CSN = 0;            //SPI使能        

status = SPI_RW(reg);   

for(uchar_ctr=0; uchar_ctr  SPI_RW(*pBuf++);

CSN = 1;           //关闭SPI

return(status);    //  

}

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

/*NRF24L01初始化

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

void init_NRF24L01(void)

{

  delayms(1);

  CE=0;    //  射频停止工作

  CSN=1;   // 停止寄存器读写

  SCK=0;   //时种信号停止读写

  IRQ=1;//中断复位

  SPI_RW_Reg(WRITE_REG + EN_AA, 0x00);      //  频道0自动 ACK应答禁止  

  SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00);      //禁止自动发送

  SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  //  允许接收地址只有频道0,   

  SPI_RW_Reg(WRITE_REG + RF_CH, 1);        //   设置信道工作为2.4GHZ,收发必须一致

  SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节

  SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);     //设置发射速率为2MHZ,发射功率为最大值0dB  

}

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

/*函数: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 + 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 + CONFIG, 0x0e);      // IRQ收发完成中断响应,16位CRC,主发送

CE=1;   //置高CE,激发数据发送

delayms(1);

}

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

//              主函数

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

void main()

{

  uchar  TxBuf[32];

  uchar status;  //定义一个变量用来装读取到的STATUS数值

  init_NRF24L01();//NRF24L01初始化

  SPI_RW_Reg(WRITE_REG+STATUS,0XFF);   //清状态寄存器

  status=SPI_Read(STATUS); //读取状态

  P0=~status;//P0口显示读取的状态

  delayms(4000);//显示延时4秒,以便从容看清楚

  P0=0xff;//清除显示

  delayms(600);

  TxBuf[0]=1;  //我们设置个初值1在想要发送的数组的第1个里变量里。

  while(1)

   { TxBuf[0]=~TxBuf[0];   //这句把要发送的第1个变量的值取反,如果原来是1,现再就为0

     nRF24L01_TxPacket(TxBuf);//装载数据并进行一次发送操作

     status=SPI_Read(STATUS); //发送完后再读取状态

     P0=~status;  //显示发送完后的状态

     delayms(500);  //显示发送后的信息停留1秒

     P0=0xFF;   //清除显示

     delayms(500);

   }  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多