天线|RF射频
直播中

韩香茹

7年用户 182经验值
私信 关注
[问答]

C8051F340驱动nRF24L01失败

C8051F340驱动nRF24L01,模拟SPI,未使用中断,通过读取状态寄存器来判断数据接收状况(在子函数nRF24L01_RxPacket中实现),但是RX_DR的值始终为0??屏蔽if(RX_DR)这一句后可以收到一两组数据??请用过的前辈们指教指教,先行谢过!!



#include

#include


#define uchar unsigned char

#define uint unsigned int

//****************************************IO端口定义***************************************

***it CE =  P1^6;      // P0^6

***it CSN=  P1^3;      // P0^3

***it SCK=  P1^0;      // P0^0

***it MOSI= P1^2;      // P0^2

***it MISO= P1^1;      // P0^1

***it IRQ = P1^7;      // P0^7

//***********************************LED灯**************************************************

***it led1 = P2^2;                      // Green LED D4   

***it led2 = P2^3;                      // Green LED D3

//*********************************************NRF24L01*************************************

#define SYSCLK      12000000           // SYSCLK frequency in Hz

#define BAUDRATE        9600           // Baud rate of UART in bps

#define SPI_CLOCK          250000      // Maximum SPI clock

                                       // The SPI clock is a maximum of 250 kHz

                                       // when this example is used with

                                       // the SPI0_Slave code example.


#define TX_ADR_WIDTH    5    // 5 uints TX address width

#define RX_ADR_WIDTH    5    // 5 uints RX address width

#define TX_PLOAD_WIDTH  16   // 20 uints TX payload

#define RX_PLOAD_WIDTH  16   // 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}; //接收地址

char rx_buf[TX_PLOAD_WIDTH];

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


//----------------------------------------------------------------------------------------

uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);

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

uint SPI_RW_Reg(uchar reg, uchar value);


// PORT_Init

//-----------------------------------------------------------------------------

//

// Return Value : None

// Parameters   : None

//

// Configure the Cros***ar and GPIO ports.

//

// P0.4   digital   push-pull    UART TX

// P0.5   digital   open-drain   UART RX

//

//-----------------------------------------------------------------------------


void PORT_Init (void)

{

   P1MDOUT |= 0x5d;

   P2MDOUT = 0x0c;                     // Make the LED push-pull

  

   P0MDOUT |= 0x10;                    // Enable UTX as push-pull output

   XBR0     = 0x01;                    // Enable UART on P0.4(TX) and P0.5(RX)

   XBR1     = 0x40;                    // Enable cros***ar and weak pull-ups

}


//-----------------------------------------------------------------------------

// SYSCLK_Init

//-----------------------------------------------------------------------------

//

// Return Value : None

// Parameters   : None

//

// This routine initializes the system clock to use the internal oscillator

// at its maximum frequency.

// Also enables the Missing Clock Detector.

//-----------------------------------------------------------------------------


void SYSCLK_Init (void)

{

   OSCICN |= (0x03);                     // Configure internal oscillator for

                                       // its maximum frequency

   RSTSRC  = 0x04;                     // Enable missing clock detector

}


//-----------------------------------------------------------------------------

// UART0_Init

//-----------------------------------------------------------------------------

//

// Return Value : None

// Parameters   : None

//

// Configure the UART0 using Timer1, for and 8-N-1.

//-----------------------------------------------------------------------------


void UART0_Init (void)

{

   SCON0 = 0x10;                       // SCON0: 8-bit variable bit rate

                                       //        level of STOP bit is ignored

                                       //        RX enabled(接收允许)

                                       //        ninth bits are zeros

                                       //        clear RI0 and TI0 bits(软件清0)

   if (SYSCLK/BAUDRATE/2/256 < 1)     

   {

      TH1 = -(SYSCLK/BAUDRATE/2);    //625

      CKCON &= ~0x0B;                  // T1M = 1; SCA1:0 = xx(不分频)

      CKCON |=  0x08;

   }

   else if (SYSCLK/BAUDRATE/2/256 < 4)

   {

      TH1 = -(SYSCLK/BAUDRATE/2/4);

      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 01(4分频)

      CKCON |=  0x01;

   }

   else if (SYSCLK/BAUDRATE/2/256 < 12)

   {

      TH1 = -(SYSCLK/BAUDRATE/2/12);

      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 00(12分频)

   }

   else

   {

      TH1 = -(SYSCLK/BAUDRATE/2/48);

      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 10(48分频)

      CKCON |=  0x02;

   }


   TL1 = TH1;                          // init Timer1

   TMOD &= ~0xf0;                      // TMOD: timer 1 in 8-bit autoreload

   TMOD |=  0x20;

   TR1 = 1;                            // START Timer1

   IP |= 0x10;                         // Make UART high priority

   ES0 = 1;                            // Enable UART0 interrupts


}




//*****************************************长延时*****************************************

void Delay(uint s)

{

unsigned int i;

for(i=0; i
for(i=0; i
}


void ddelay(uint k)

{

   uint i, j;

   for(i=0;i
   for(j=0;j<6000;j++);

}

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

uint  bdata sta;   //状态标志

***it RX_DR =sta^6;

***it TX_DS =sta^5;

***it MAX_RT =sta^4;

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

/*延时函数

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

void inerDelay_us(uchar 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

CE=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,如果需要多频道可以参考Page21  

SPI_RW_Reg(WRITE_REG + RF_CH, 0);        // Select RF channel 40,收发必须一致

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

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

SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);     // IRQ收发完成中断响应,16位CRC ,主接收

}

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

/*函数:uint SPI_RW(uint uchar)

/*功能:NRF24L01的SPI写时序

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

uint SPI_RW(uint byte)

{

uint bit_ctr;

    for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit

    {

  MOSI = (byte & 0x80);         // output 'uchar', MSB to MOSI

  byte = (byte << 1);           // shift next bit into MSB..

  SCK = 1;                      // Set SCK high..

  byte |= MISO;           // capture current MISO bit

  SCK = 0;                // ..then set SCK low again

    }

    return(byte);               // return read uchar

}

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

/*函数:uchar SPI_Read(uchar reg)

/*功能:NRF24L01的SPI时序

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

uchar SPI_Read(uchar reg)

{

uchar reg_val;



CSN = 0;                // CSN low, initialize SPI communication...

SPI_RW(reg);            // Select register to read from..

reg_val = SPI_RW(0);    // ..then read registervalue

CSN = 1;                // CSN high, terminate SPI communication



return(reg_val);        // return register value

}

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

/*功能:NRF24L01读写寄存器函数

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

uint SPI_RW_Reg(uchar reg, uchar value)

{

uint status;



CSN = 0;                   // CSN low, init SPI transaction

status = SPI_RW(reg);      // select register

SPI_RW(value);             // ..and write value to it..

CSN = 1;                   // CSN high again



return(status);            // return nRF24L01 status uchar

}

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

/*函数: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;                      // Set CSN low, init SPI tranaction

status = SPI_RW(reg);         // Select register to write to and read status uchar



for(uchar_ctr=0;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
  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接收缓冲区中

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

uchar nRF24L01_RxPacket(char* rx_buf)  

{

    uchar revale=0;

sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况

if(RX_DR)    // 判断是否接收到数据 RX_DR

// while(RX_DR==0);

{   

     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来清楚中断标志

SPI_RW_Reg(WRITE_REG+STATUS,0xf0);   //接收到数据后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);

}


//************************************通过串口将接收到数据发送给PC端**************************************

void R_S_Byte(uchar R_Byte)

{

  SBUF0 = R_Byte;

    while( TI0 == 0 );    //查询法

    TI0 = 0;   

}

//************************************主函数************************************************************

void main(void)

{

char i,num;

CA0MD &= ~0x40;                    // WDTE = 0 (clear watchdog timer enable)

SYSCLK_Init ();                     // Initialize Oscillator

ORT_Init();                        // Initialize Port I/O  



UART0_Init ();

init_NRF24L01() ;

led1=0;led2=0;

Delay(6000);  


EA=1;


while(1)

  {

      led1=1;

   ddelay(200);   


   SetRX_Mode();        

      if(nRF24L01_RxPacket(rx_buf))   

   {

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

    {

    //R_S_Byte(RxBuf);

     num=rx_buf;

        R_S_Byte(num);

    }

       led2=1;

             ddelay(200);

   }  

   led1=0;led2=0;

   ddelay(200);

}   

}


/***************************************END OF FILE*******************************/

回帖(1)

赵娜

2019-6-24 06:40:25
有一发一收在同时工作吧?

举报

更多回帖

发帖
×
20
完善资料,
赚取积分