besyao 发表于 2012-9-29 07:22:39

[求助] C8051F340驱动nRF24L01出点问题,请前辈们指教

C8051F340驱动nRF24L01,模拟SPI,未使用中断,通过读取状态寄存器来判断数据接收状况(在子函数

nRF24L01_RxPacket中实现),但是RX_DR的值始终为0??屏蔽if(RX_DR)这一句后可以收到一两组数据??请用过

的前辈们指教指教,先行谢过!!接收部分的代码如下:


#include <c8051f340.h>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int
//****************************************IO端口定义***************************************
sbit CE =P1^6;                                                // P0^6
sbit CSN=P1^3;                                                // P0^3
sbit SCK=P1^0;                                                // P0^0
sbit MOSI= P1^2;                                                // P0^2
sbit MISO= P1^1;                                                // P0^1
sbit IRQ = P1^7;                                                // P0^7
//***********************************LED灯**************************************************
sbit led1 = P2^2;                      // Green LED D4                               
sbit 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_WIDTH16        // 20 uints TX payload
#define RX_PLOAD_WIDTH16        // 20 uints TX payload
uint const TX_ADDRESS= {0x34,0x43,0x10,0x10,0x01};        //本地地址
uint const RX_ADDRESS= {0x34,0x43,0x10,0x10,0x01};        //接收地址
char rx_buf;
//***************************************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 Crossbar 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 crossbar 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 <BAUDRATE> 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<s; i++);
        for(i=0; i<s; i++);
}

void ddelay(uint k)
{
   uint i, j;
   for(i=0;i<k;i++)
       for(j=0;j<6000;j++);
}
//******************************************************************************************
uint         bdata sta;   //状态标志
sbit        RX_DR        =sta^6;
sbit        TX_DS        =sta^5;
sbit        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<uchars;uchar_ctr++)
                pBuf = 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<uchars; 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;
        PCA0MD &= ~0x40;                  // WDTE = 0 (clear watchdog timer enable)
        SYSCLK_Init ();                     // Initialize Oscillator
        PORT_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]
查看完整版本: [求助] C8051F340驱动nRF24L01出点问题,请前辈们指教