NRF24L01收发测试程序


调试好了NRF24L01的程序,前几天一直接收不到,今天发现是寄存器设置错误,更新最新调试好的程序:


接收:

#include "include.h"

unsigned char sta;  // 状态变量     
unsigned char rx_dr_flag;//接收成功标志位

#define RX_DR (sta & 0x40)  // 接收成功中断标志
#define TX_DS (sta & 0x20)  // 发射成功中断标志
#define MAX_RT (sta & 0x10) // 重发溢出中断标志

sbit IRQ = P0^0;
sbit MISO = P0^1;
sbit MOSI = P0^2;
sbit SCK = P0^3;
sbit CSN = P0^4;
sbit CE = P0^5;

unsigned char const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};	//接收地址
unsigned char const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};	//本地地址

/*
********************************************************************************
* 函数名称:void Init_io(void)
*
* 功    能:初始化io口
*
* 调用清单:无
*
* 参    数:1)无
*
* 返 回 值:无
*
* 注    意:1) 
*           2) 
********************************************************************************
*/
void Init_NRF24L01(void)
{
	CE  = 0;        // 待机
	CSN = 1;        // SPI禁止
	SCK = 0;        // SPI时钟置低
	IRQ = 1;        // 中断复位
}
					
/*
********************************************************************************
* 函数名称:unsigned char SPI_RW(unsigned char byte)    
*
* 功    能:写时序
*
* 调用清单:无
*
* 参    数:1)byte: 写入的数据
*
* 返 回 值:byte
*
* 注    意:1) 
*           2) 
********************************************************************************
*/
unsigned char SPI_RW(unsigned char byte)
{
    unsigned char bit_ctr;

	for(bit_ctr = 0; bit_ctr < 8; bit_ctr++)
    {
	    MOSI = (0x80 & byte);
        byte <<= 1;
        SCK = 1;
		byte |= MISO;
		SCK = 0;      
	}	

	return (byte);
}

/*
********************************************************************************
* 函数名称:unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)    
*
* 功    能:设置寄存器的值
*
* 调用清单:1)unsigned char SPI_RW(unsigned char byte)
*
* 参    数:1)reg  : 待设置寄存器地址
            2)value: 设置寄存器的值
*
* 返 回 值:status
*
* 注    意:1) 
*           2) 
********************************************************************************
*/
unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)
{
    unsigned char status;

    CSN = 0;
    status = SPI_RW(reg);
    SPI_RW(value);
    CSN = 1;

    return (status);
}

/*
********************************************************************************
* 函数名称:unsigned char SPI_Read(unsigned char reg)
*
* 功    能:读取寄存器中的值
*
* 调用清单:1)unsigned char SPI_RW(unsigned char byte)
*
* 参    数:1)reg: 待读取寄存器的地址
*
* 返 回 值:1)reg_val: 读取的值
*
* 注    意:1) 
*           2) 
********************************************************************************
*/
unsigned char SPI_Read(unsigned char reg)
{
    unsigned char reg_val;

    CSN = 0;
    SPI_RW(reg);
    reg_val = SPI_RW(0);
    CSN = 1;

    return (reg_val);
}

/*
********************************************************************************
* 函数名称:unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
*
* 功    能:在接收时读取FIFO缓冲区中的值
*
* 调用清单:1)unsigned char SPI_RW(unsigned char byte)
*
* 参    数:1)reg  : 寄存器地址
            2)pBuf : 待读取的数据地址
            3)bytes: 读出数据的个数
*
* 返 回 值:status: 寄存器状态
*
* 注    意:1) 
*           2) 
********************************************************************************
*/
unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
{
    unsigned char status;
    unsigned char byte_ctr;

    CSN = 0;
    status = SPI_RW(reg);
    for(byte_ctr = 0; byte_ctr < bytes; byte_ctr++)
    {
        pBuf[byte_ctr] = SPI_RW(0);
    }
    CSN = 1;

    return (status);
}


/*
********************************************************************************
* 函数名称:unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
*
* 功    能: 把数组里的数放到发射FIFO缓冲区中去
*
* 调用清单:1)unsigned char SPI_RW(unsigned char byte)
*
* 参    数:1)reg  : 寄存器地址
            2)pBuf : 待写入数据地址
            3)bytes: 读出字节的个数
*
* 返 回 值:status: 寄存器状态
*
* 注    意:1) 
*           2) 
********************************************************************************
*/
unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
{
    unsigned char status;
    unsigned char byte_ctr;

    CSN = 0;
    status = SPI_RW(reg);
    Delay_Us(10);
    for(byte_ctr = 0; byte_ctr < bytes; byte_ctr++)
    {
        SPI_RW(*pBuf++);
    }
    CSN = 1;

    return (status);
}

/*
********************************************************************************
* 函数名称:void RX_Mode(void)
*
* 功    能:设置NRF24L01为接收方式
*
* 调用清单:1)unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
*			2)unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)
* 参    数:无
*
* 返 回 值:无
*
* 注    意:1) 							 
*           2) 
********************************************************************************
*/
#if 1
void RX_Mode(void)
{
    CE = 0;
    SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
    SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);
    SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);
    SPI_RW_Reg(WRITE_REG + RF_CH, 40);
    SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);
    SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);
    SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);
    CE = 1;
    Delay_Us(130);
}
#endif

/*
********************************************************************************
* 函数名称:void TX_Mode(void)
*
* 功    能:设置NRF24L01为发射方式
*
* 调用清单:1)unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
*			2)unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)
* 参    数:无
*
* 返 回 值:无
*
* 注    意:1) 							 
*           2) 
********************************************************************************
*/
//void TX_Mode(unsigned char *tx_data)
//{
//    CE = 0;    //待机
//    SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);       //写寄存器指令 + 接收节电地址 + 地址宽度
//    SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);    //为了接收设备应答信号,接收通道0地址与发送地址相同
//    SPI_Write_Buf(TX_PLOAD_WIDTH, tx_data, TX_ADR_WIDTH);      //写有效数据地址 + 有效数据 + 有效数据宽度
//
//  	SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);       // 使能接收通道0自动应答
//  	SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);   // 使能接收通道0
//  	SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x0a);  // 自动重发延时等待250us+86us,自动重发10次
//  	SPI_RW_Reg(WRITE_REG + RF_CH, 40);         // 选择射频通道0x40 (2.4G HZ)
//  	SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);    // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益
//  	SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);      // CRC使能,16位CRC校验,上电
//    CE = 1;         //启动发射
//    Delay_Ms(1);    //CE高电平持续事件最少10us以上
//}

//unsigned char Check_ACK(void)
//{
//	while(IRQ);
//	sta = SPI_RW(NOP);                    // 返回状态寄存器
//	if(MAX_RT || TX_DS)
//    {
//	    SPI_RW_Reg(WRITE_REG + STATUS, sta);  // 清除TX_DS或MAX_RT中断标志
//        CSN = 0;
//        SPI_RW(FLUSH_TX);
//        CSN = 1;
//
//        return 0x00;
//    }
//
//    return 0xff;
//}

/******************************************************************************************************/
/*函数: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)				// 判断是否接收到数据
	{
	    rx_dr_flag = 1;     //成功接受数据置1
        CE = 0; 			//SPI使能
		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;
}

#include "include.h"

extern unsigned char rx_dr_flag;
/*
********************************************************************************
* 主函数
********************************************************************************
*/
void main()
{
    unsigned char i;
    unsigned char RX_Buf[20] = {0};

    Init_NRF24L01();
    i = 0;
    while(1)
    {
        RX_Mode();
        nRF24L01_RxPacket(&RX_Buf[i]);
        Delay_Ms(2);
        if(rx_dr_flag)//接收一次数据,为P1赋值一次
        {
            P1 = RX_Buf[i];
            i++;
            if(8 == i)
            {
                i = 0;
            }
            rx_dr_flag = 0;   //赋值之后清空标志位
        }
    }   
}


发送:

#include "include.h"

unsigned char giv_status;  // 状态变量

#define RX_DR (giv_status & 0x40)  // 接收成功中断标志
#define TX_DS (giv_status & 0x20)  // 发射成功中断标志
#define MAX_RT (giv_status & 0x10) // 重发溢出中断标志

sbit IRQ = P0^0;
sbit MISO = P0^1;
sbit MOSI = P0^2;
sbit SCK = P0^3;
sbit CSN = P0^4;
sbit CE = P0^5;

unsigned char const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};	//接收地址
unsigned char const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};	//本地地址

/*
********************************************************************************
* 函数名称:void Init_io(void)
*
* 功    能:初始化io口
*
* 调用清单:无
*
* 参    数:1)无
*
* 返 回 值:无
*
* 注    意:1) 
*           2) 
********************************************************************************
*/
void Init_NRF24L01(void)
{
	CE  = 0;        // 待机
	CSN = 1;        // SPI禁止
	SCK = 0;        // SPI时钟置低
	IRQ = 1;        // 中断复位
}
					
/*
********************************************************************************
* 函数名称:unsigned char SPI_RW(unsigned char byte)    
*
* 功    能:写时序
*
* 调用清单:无
*
* 参    数:1)byte: 写入的数据
*
* 返 回 值:byte
*
* 注    意:1) 
*           2) 
********************************************************************************
*/
unsigned char SPI_RW(unsigned char byte)
{
    unsigned char bit_ctr;

	for(bit_ctr = 0; bit_ctr < 8; bit_ctr++)
    {
	    MOSI = (0x80 & byte);
        byte <<= 1;
        SCK = 1;
		byte |= MISO;
		SCK = 0;      
	}	

	return (byte);
}

/*
********************************************************************************
* 函数名称:unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)    
*
* 功    能:设置寄存器的值
*
* 调用清单:1)unsigned char SPI_RW(unsigned char byte)
*
* 参    数:1)reg  : 待设置寄存器地址
            2)value: 设置寄存器的值
*
* 返 回 值:status
*
* 注    意:1) 
*           2) 
********************************************************************************
*/
unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)
{
    unsigned char status;

    CSN = 0;
    status = SPI_RW(reg);
    SPI_RW(value);
    CSN = 1;

    return (status);
}

/*
********************************************************************************
* 函数名称:unsigned char SPI_Read(unsigned char reg)
*
* 功    能:读取寄存器中的值
*
* 调用清单:1)unsigned char SPI_RW(unsigned char byte)
*
* 参    数:1)reg: 待读取寄存器的地址
*
* 返 回 值:1)reg_val: 读取的值
*
* 注    意:1) 
*           2) 
********************************************************************************
*/
unsigned char SPI_Read(unsigned char reg)
{
    unsigned char reg_val;

    CSN = 0;
    SPI_RW(reg);
    reg_val = SPI_RW(0);
    CSN = 1;

    return (reg_val);
}

/*
********************************************************************************
* 函数名称:unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
*
* 功    能:在接收时读取FIFO缓冲区中的值
*
* 调用清单:1)unsigned char SPI_RW(unsigned char byte)
*
* 参    数:1)reg  : 寄存器地址
            2)pBuf : 待读取的数据地址
            3)bytes: 读出数据的个数
*
* 返 回 值:status: 寄存器状态
*
* 注    意:1) 
*           2) 
********************************************************************************
*/
//unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
//{
//    unsigned char status;
//    unsigned char byte_ctr;
//
//    CSN = 0;
//    status = SPI_RW(reg);
//    for(byte_ctr = 0; byte_ctr < bytes; byte_ctr++)
//    {
//        pBuf[byte_ctr] = SPI_RW(0);
//    }
//    CSN = 1;
//
//    return (status);
//}


/*
********************************************************************************
* 函数名称:unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
*
* 功    能: 把数组里的数放到发射FIFO缓冲区中去
*
* 调用清单:1)unsigned char SPI_RW(unsigned char byte)
*
* 参    数:1)reg  : 寄存器地址
            2)pBuf : 待写入数据地址
            3)bytes: 读出字节的个数
*
* 返 回 值:status: 寄存器状态
*
* 注    意:1) 
*           2) 
********************************************************************************
*/
unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
{
    unsigned char status;
    unsigned char byte_ctr;

    CSN = 0;
    status = SPI_RW(reg);
    Delay_Us(10);
    for(byte_ctr = 0; byte_ctr < bytes; byte_ctr++)
    {
        SPI_RW(*pBuf++);
    }
    CSN = 1;

    return (status);
}

/*
********************************************************************************
* 函数名称:void RX_Mode(void)
*
* 功    能:设置NRF24L01为接收方式
*
* 调用清单:1)unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
*			2)unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)
* 参    数:无
*
* 返 回 值:无
*
* 注    意:1) 							 
*           2) 
********************************************************************************
*/
#if 0
void RX_Mode(void)
{
    CE = 0;
    SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
    SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);
    SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);
    SPI_RW_Reg(WRITE_REG + RF_CH, 40);
    SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);
    SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);
    SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);
    CE = 1;
}
#endif

/*
********************************************************************************
* 函数名称:void TX_Mode(void)
*
* 功    能:设置NRF24L01为发射方式
*
* 调用清单:1)unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
*			2)unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)
* 参    数:无
*
* 返 回 值:无
*
* 注    意:1) 							 
*           2) 
********************************************************************************
*/
void TX_Mode(unsigned char *tx_data)
{
    CE = 0;    //待机
    SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);       //写寄存器指令 + 接收节电地址 + 地址宽度
    SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);    //为了接收设备应答信号,接收通道0地址与发送地址相同
    SPI_Write_Buf(WR_TX_PLOAD, tx_data, TX_ADR_WIDTH);      //写有效数据地址 + 有效数据 + 有效数据宽度

  	SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);       // 使能接收通道0自动应答
  	SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);   // 使能接收通道0
  	SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x0a);  // 自动重发延时等待250us+86us,自动重发10次
  	SPI_RW_Reg(WRITE_REG + RF_CH, 40);         // 选择射频通道0x40 (2.4G HZ)
  	SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);    // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益
  	SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);      // CRC使能,16位CRC校验,上电
    CE = 1;         //启动发射
    Delay_Ms(1);    //CE高电平持续事件最少10us以上
}

//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,激发数据发送
//    Delay_Us(10);
//}

unsigned char Check_ACK(void)
{
	while(IRQ);
	giv_status = SPI_RW(NOP);                    // 返回状态寄存器

	if(MAX_RT || TX_DS)
    {
	    SPI_RW_Reg(WRITE_REG + STATUS, giv_status);  // 清除TX_DS或MAX_RT中断标志
        CSN = 0;
        SPI_RW(FLUSH_TX);
        CSN = 1;
        IRQ = 1;
        return 0x00;
    }
    IRQ = 1;
    return 0xff;
}

#include "include.h"

sbit led = P1^0;

/*
********************************************************************************
* 主函数
********************************************************************************
*/
void main()
{
    unsigned char i;
    unsigned char TX_Buf[8] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};
                                     //1111 1110, 1111 1101, 1111 1011, 1111 0111, 
                                     //1110 1111, 1101 1111, 1011 1111, 0111 1111
    Init_NRF24L01();

    while(1)
    {
        for(i = 0; i < 8; i++)
        {
            TX_Mode(&TX_Buf[i]);
            while(Check_ACK());
            led = ~led;
            Delay_S(1);
        }
        i = 0;
    }   
}


智能推荐

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告