求助!帮我看看无线通信模块代码哪里错了

2019-03-24 18:46发布

要实现的功能:
主机按一个键P3^4,发送一次数据从机对比数据是不是需要的数据,是的话从机蜂鸣器响
出现的问题是:
1、按下键,主机一直在发数据,从机始终没有接收到,从机不做任何反应
2、另外可能是程序不稳定,还会出现一个问题:没有把24L01拔下,Tx_DR和MAX_RT不置高,始终没有发送数据;把24L01模块拔下,Tx_DR和MAX_RT置高(就是主机程序会进入if(Tx_DR)和if(MAX_RT)),从机也一样,把模块拔下,再上电,蜂鸣器会响

主机发送:
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
//****************************************IO端口定义***************************************
sbit  CSN=P3^3;
sbit MOSI=P1^5;
sbit  IRQ=P1^3;
sbit   CE=P1^4;
sbit  SCK=P1^6;
sbit MISO=P1^7;
sbit  LED=P1^2;
sbit  LED1=P1^0;
sbit BEEP=P2^3;
sbit  KEY=P3^4;
//******************************************************************************************
uchar bdata sta        ;
sbit RX_DR=        sta^6;
sbit TX_DR=sta^5;
sbit MAX_RT=sta^4;
//*********************************************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  2   // 32 uints TX payload
#define RX_PLOAD_WIDTH  2   // 32 uints TX payload
uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址
uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
uchar code Tx_Buf_1[TX_PLOAD_WIDTH]={0x01,0x02};//发送数据
uchar  Tx_Buf[TX_PLOAD_WIDTH]={0};
//***************************************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栈入栈出状态寄存器设置
/******************************************延时函数********************************************************/

//长延时
void Delay(unsigned int s)
{
unsigned int i,j;
for(i=0;i<1000;i++)for(j=0;j<s;j++);
}
//短延时
void delay1us()
{; ;}

void inerDelay_us(unsigned char n)
{
        for(;n>0;n--)
        //_nop_();
        delay1us();
}

/************************************IO 口模拟SPI总线 代码************************************************/
uchar SPI_RW(uchar byte)
{
uchar i;
for(i=0;i<8;i++)
  {
   MOSI=(byte&0x80);
   
   byte=(byte<<1);
   SCK=1;
   byte|=MISO;
   SCK=0;
  }
  return(byte) ;
}
uchar SPI_RW_Reg  (uchar  reg,uchar value) // 向寄存器REG写一个字节,同时返回状态字节
{
    uchar status;
  CSN=0;
  status=SPI_RW(reg);
    SPI_RW(value);
  CSN=1;
  return(status);
}
uchar SPI_Read (uchar  reg )
{
    uchar reg_val;
  CSN=0;
  SPI_RW(reg);
   reg_val=SPI_RW(0);
  CSN=1;
  return(reg_val);
}

uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
        uchar status,byte_ctr;
       
        CSN = 0;                                    // Set CSN low, init SPI tranaction
        status = SPI_RW(reg);                       // Select register to write to and read status byte
       
        for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
                pBuf[byte_ctr] = SPI_RW(0);    //
       
        CSN = 1;                           
       
        return(status);                    // return nRF24L01 status byte
}

uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
uchar status,byte_ctr;
   CSN = 0;                   // Set CSN low, init SPI tranaction
   status = SPI_RW(reg);    // Select register to write to and read status byte
   for(byte_ctr=0; byte_ctr<bytes; byte_ctr++) // then write all byte in buffer(*pBuf)
    SPI_RW(*pBuf++);
   CSN = 1;                 // Set CSN high again
   return(status);          // return nRF24L01 status byte
}

void SetRX_Mode(void)
{
        CE=0;
        SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // Use the same address on the RX device as the TX device
       
        SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      //
        SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  //
        SPI_RW_Reg(WRITE_REG + RF_CH, 0);        //
        SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH);
        SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   
        SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);     
       
        CE = 1;
        inerDelay_us(130);

}

/*******************************发*****送*****模*****式*****代*****码*************************************/
void TX_MODE(uchar *tx_buf)
{
CE=0;
CSN=1;
SCK=0;
//SPI_RW_Reg(FLUSH_TX,0x00);
SPI_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);
SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,RX_ADDRESS,TX_ADR_WIDTH);
  SPI_Write_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH);
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_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, 0x1a);
SPI_RW_Reg(WRITE_REG+RF_CH, 0);
SPI_RW_Reg(WRITE_REG+RF_SETUP, 0x07);
SPI_RW_Reg(WRITE_REG + CONFIG,0x0e);
CE=1;
inerDelay_us(100);
}

//************************************主程序*********************************************************
main()
{
CSN=1;
SCK=0;
CE=0;
  while(!KEY)
   {
        Delay(2);
        while(!KEY)
         {
         SetRX_Mode();
         Tx_Buf[0]=0x01;
         Tx_Buf[1]=0x02;
     TX_MODE(Tx_Buf);
      Delay(50);
      sta=SPI_Read(READ_REG+STATUS);
     if(TX_DR)
      {
             LED=0;
        Delay(50);
            LED=1;
            SPI_RW_Reg(WRITE_REG+STATUS,sta);
      }
     if(MAX_RT)
      {
             LED1=0;
            Delay(20);
            LED1=1;
            SPI_RW_Reg(WRITE_REG+STATUS,sta);
       }
          }
         }
          while(!KEY);
  }

从机接收:
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
//****************************************IO端口定义***************************************
sbit BEEP=P1^2;
sbit  CSN=P3^6;
sbit MOSI=P3^4;
sbit  IRQ=P3^2;
sbit   CE=P3^7;
sbit  SCK=P3^3;
sbit MISO=P3^5;
sbit DIOLA =P1^5;
//******************************************************************************************
uchar bdata sta        ;
sbit RX_DR=        sta^6;
sbit TX_DR=sta^5;
sbit MAX_RT=sta^4;
//*********************************************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  2   // 32 uints TX payload
#define RX_PLOAD_WIDTH  2   // 32 uints TX payload
uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址
uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
uchar code Tx_Buf_1[TX_PLOAD_WIDTH]={0x01,0x02};//发送数据
//uchar Rx_Buf[RX_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栈入栈出状态寄存器设置
/******************************************延时函数********************************************************/
//长延时
void Delay(unsigned int s)
{
unsigned int i,j;
for(i=0;i<1000;i++)for(j=0;j<s;j++);
}
void delay1us()
{; ;}
//短延时
void inerDelay_us(unsigned char n)
{
        for(;n>0;n--)
        //_nop_();
        delay1us();
}
/************************************IO 口模拟SPI总线 代码************************************************/
uchar SPI_RW(uchar byte)
{
uchar i;
for(i=0;i<8;i++)
  {
   MOSI=(byte&0x80);
   
   byte=(byte<<1);
   SCK=1;
   byte|=MISO;
   SCK=0;
  }
  return(byte) ;
}
uchar SPI_RW_Reg  (uchar  reg,uchar value) // 向寄存器REG写一个字节,同时返回状态字节
{
    uchar status;
  CSN=0;
  status=SPI_RW(reg);
    SPI_RW(value);
  CSN=1;
  return(status);
}
uchar SPI_Read (uchar  reg )
{
    uchar reg_val;
  CSN=0;
  SPI_RW(reg);
   reg_val=SPI_RW(0);
  CSN=1;
  return(reg_val);
}
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
uchar status,byte_ctr;
   CSN = 0;                   // Set CSN low, init SPI tranaction
   status = SPI_RW(reg);    // Select register to write to and read status byte
   for(byte_ctr=0; byte_ctr<bytes; byte_ctr++) // then write all byte in buffer(*pBuf)
    SPI_RW(*pBuf++);
   CSN = 1;                 // Set CSN high again
   return(status);          // return nRF24L01 status byte
}


/*******************************接*****收*****模*****式*****代*****码*************************************/
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uchar 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<uchars;uchar_ctr++)
  pBuf[uchar_ctr] = SPI_RW(0);    //

CSN = 1;      
return(status);                    // return nRF24L01 status uchar
}
/******************************************************************************************************/
/*函数: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,RX_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来清楚中断标志
CE=1;
return revale;
}
/****************************************************************************************************/
/*函数:void RX_Mode(void)
/*功能:数据接收配置
/****************************************************************************************************/
void RX_Mode(void)
{
CE=0;
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack
  SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      // Enable Auto.Ack:Pipe0
   SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // Enable Pipe0
   //SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...1a
   SPI_RW_Reg(WRITE_REG + RF_CH, 0);        // Select RF channel 40
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为2字节
   SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   // TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);
CE=1;
inerDelay_us(130);
}

//************************************主程序*********************************************************
main()
{
uchar i=0,k;
uchar Rx_Buf[]={0};
CSN=1;
SCK=0;
CE=0;
DIOLA =1;
while(1)
  {
   RX_Mode();
   if(nRF24L01_RxPacket(Rx_Buf))
    {
         for(i=0;i<2;i++)
          {
          if(Rx_Buf==Tx_Buf_1) k++;
         }
         if(k==2)
           {
                    BEEP=0;
                 Delay(50);
                 BEEP=1;
                 Delay(50);
                 BEEP=0;
                 Delay(50);
                 BEEP=1;
          }
   }
  }
} 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。