打印

C8051f411+nRF24L01无线模块

[复制链接]
1188|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
阿比安吉|  楼主 | 2014-12-23 16:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 阿比安吉 于 2014-12-23 16:15 编辑

小弟使用C8051f411nRF24L01+搭建一个无线通信的模块,一个发射模块和一个接收模块。这两天正在调试发射模块,现在遇到的问题是调用一次数据发送函数nRF24L01_TxPacket之后读取STATUS寄存器的值,这时候读到的是0x1F。但是按照寄存器说明表中,应该读取到0x2E才对请教各位大神这个是什么问题。是否与我在设定TX_MODE时,对寄存器EN_AAEN_RXADDRSETUP_RETR的配置有关?附上程序如下(程序中包含了串口程序,请无视):
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------

#include <C8051F410.h>                 // SFR declarations
#include <stdio.h>

//-----------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------

typedef unsigned char uchar;
typedef unsigned char uint;

#define SYSCLK             24500000    // Internal oscillator frequency in Hz

#define SPI_CLOCK          500000      // Maximum SPI clock
                                       // TheSPI clock is a maximum of 500 kHz
                                       // witha SYSCLK of 24.5 MHz when this
                                       //example is used with the SPI0_Slave
                                       // codeexample.

//-----------------------------------------------------------------------------
// nRF24L01+ 相关宏设置
//-----------------------------------------------------------------------------

// SPI(nRF24L01) commands
#define READ_REG    0x00 // Define read command to register
#define WRITE_REG   0x20 // Define write command to register
#define RD_RX_PLOAD 0x61  // Define RX payload register address
#define WR_TX_PLOAD 0xA0  // Define TX payload register address
#define FLUSH_TX    0xE1 // Define flush TX register command
#define FLUSH_RX    0xE2 // Define flush RX register command
#define REUSE_TX_PL 0xE3  // Define reuse TX payload register command
#define NOP         0xFF // Define No Operation, might be used to read status register

// SPI(nRF24L01) registers(addresses)
#define CONFIG      0x00 // 'Config' register address
#define EN_AA       0x01 // 'Enable Auto Acknowledgment' register address
#define EN_RXADDR   0x02 // 'Enabled RX addresses' register address
#define SETUP_AW    0x03 // 'Setup address width' register address
#define SETUP_RETR  0x04 // 'Setup Auto. Retrans' register address
#define RF_CH       0x05 // 'RF channel' register address
#define RF_SETUP    0x06 // 'RF setup' register address
#define STATUS      0x07 // 'Status' register address
#define OBSERVE_TX  0x08 // 'Observe TX' register address
#define CD          0x09 // 'Carrier Detect' register address
#define RX_ADDR_P0  0x0A // 'RX address pipe0' register address
#define RX_ADDR_P1  0x0B // 'RX address pipe1' register address
#define RX_ADDR_P2  0x0C // 'RX address pipe2' register address
#define RX_ADDR_P3  0x0D // 'RX address pipe3' register address
#define RX_ADDR_P4  0x0E // 'RX address pipe4' register address
#define RX_ADDR_P5  0x0F // 'RX address pipe5' register address
#define TX_ADDR     0x10 // 'TX address' register address
#define RX_PW_P0    0x11 // 'RX payload width, pipe0' register address
#define RX_PW_P1    0x12 // 'RX payload width, pipe1' register address
#define RX_PW_P2    0x13 // 'RX payload width, pipe2' register address
#define RX_PW_P3    0x14 // 'RX payload width, pipe3' register address
#define RX_PW_P4    0x15 // 'RX payload width, pipe4' register address
#define RX_PW_P5    0x16 // 'RX payload width, pipe5' register address
#define FIFO_STATUS 0x17  // 'FIFO Status Register' register address

//-----------------------------------------------------------------------------
// Function Prototypes
//-----------------------------------------------------------------------------

#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         //1 uints TX payload,每次发送MSB+LSB
#define RX_PLOAD_WIDTH  2        // 1uints TX payload,每次接收MSB+LSB
uint const TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};    //本地地址
uint const RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};   //接收地址
uint          bdatasta;   //状态标志
sbit  RX_DR      =sta^6;
sbit  TX_DS       =sta^5;
sbit  MAX_RT  =sta^4;
sbit CE =  P2^1;                     
sbit IRQ =  P2^0;

void SYSCLK_Init (void);
void UART0_Init (void);
void PORT_Init (void);

void SPI0_Init(void);
uchar SPI_RW(uchar val);
uchar SPI_RW_Reg(uchar reg, uchar value);
uchar SPI_Read(uchar reg);
uchar SPI_Read_Buf(uchar reg, uchar * pBuf,uchar bytes);
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes);
unsigned char nRF24L01_RxPacket(unsignedchar* rx_buf);
void nRF24L01_TxPacket(unsigned char *tx_buf);
void RX_Mode(void);
void TX_Mode(void);

//-----------------------------------------------------------------------------
// main() Routine
//-----------------------------------------------------------------------------
void main (void)
{
  unsigned char i=0x00;
  unsigned char TxBuf[2]={0};      
  unsigned char RxBuf[2]={0};
  PCA0MD &= ~0x40;                   // Disable Watchdog timer

  SYSCLK_Init ();
  UART0_Init ();
  PORT_Init ();
  SPI0_Init();
  TX_Mode();        
  RxBuf[0]     = 0xEB;
  RxBuf[1]     = 0x9D;              

  nRF24L01_TxPacket(TxBuf);
   i= SPI_Read(READ_REG+STATUS);                     

  while (1)
   {
         ;
   }        
}

// 辅助函数

void SYSCLK_Init (void)
{
  OSCICN = 0x87;                     // configure internal oscillator for
                                       // 24.5MHz
  RSTSRC = 0x04;                     // enable missing clock detector
}

void PORT_Init (void)
{
   P0MDOUT   = 0x1D;                //P0.0 P0.2 P0.3 P0.4SCK MOSI NSS TX0置于Push-Pull
   P2MDOUT   = 0x03;                //P2.0 P2.1置于Push-Pull
   XBR0      = 0x03;                    //启用UART0 SPI0
   XBR1      = 0x40;                    //Enable Crossbar
}

void SPI0_Init()
{
  SPI0CFG   = 0x43;                   // Enable the SPI as aMaster

  SPI0CN    = 0x0D;                   // 4-wire Single Master, SPIenabled

   //SPI clock frequency equation from the datasheet
  SPI0CKR   =(SYSCLK/(2*SPI_CLOCK))-1;
}

//-----------------------------------------------------------------------------
// Support Routines
//-----------------------------------------------------------------------------               

uchar SPI_RW(uchar val)
{
   SPIF=0;
   SPI0DAT=val;
    while(SPIF==0);
    returnSPI0DAT;
}

uchar SPI_RW_Reg(uchar reg, uchar value)
{
       uchar status;
       NSSMD0 = 0;                   // CSN置低,开始传输数据
       status = SPI_RW(reg);      // 选择寄存器,同时返回状态字
       SPI_RW(value);             // 然后写数据到该寄存器
       NSSMD0 = 1;                   // CSN拉高,结束数据传输
       return(status);            // 返回状态寄存器
}

uchar SPI_Read(uchar reg)
{
       uchar reg_val;
       NSSMD0 = 0;                    // CSN置低,开始传输数据
       SPI_RW(reg);                // 选择寄存器
       reg_val = SPI_RW(0);        // 然后从该寄存器读数据
       NSSMD0 = 1;                    // CSN拉高,结束数据传输
       return(reg_val);            // 返回寄存器数据
}

uchar SPI_Read_Buf(uchar reg, uchar * pBuf,uchar bytes)
{
       uchar status, i;
       NSSMD0 = 0;                    // CSN置低,开始传输数据
       status = SPI_RW(reg);       // 选择寄存器,同时返回状态字
       for(i=0; i<bytes; i++)
             pBuf = SPI_RW(0);    // 逐个字节从nRF24L01读出
       NSSMD0 = 1;                    // CSN拉高,结束数据传输
       return(status);             // 返回状态寄存器
}

uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
       uchar status, i;
       NSSMD0 = 0;                    // CSN置低,开始传输数据
       status = SPI_RW(reg);       // 选择寄存器,同时返回状态字
       for(i=0; i<bytes; i++)
             SPI_RW(pBuf);        // 逐个字节写入nRF24L01
       NSSMD0 = 1;                    // CSN拉高,结束数据传输
       return(status);             // 返回状态寄存器
}

void RX_Mode(void)
{
         CE= 0;
       SPI_Write_Buf(WRITE_REG + RX_ADDR_P0,TX_ADDRESS, TX_ADR_WIDTH);  // 接收设备接收通道0使用和发送设备相同的发送地址
       SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);               // 使能接收通道0自动应答
       SPI_RW_Reg(WRITE_REG + EN_RXADDR,0x01);           // 使能接收通道0
       SPI_RW_Reg(WRITE_REG + RF_CH, 40);                 // 选择射频通道0x40
       SPI_RW_Reg(WRITE_REG + RX_PW_P0,TX_PLOAD_WIDTH);  // 接收通道0选择和发送通道相同有效数据宽度
       SPI_RW_Reg(WRITE_REG + RF_SETUP,0x07);            // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益
       SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);              // CRC使能,16CRC校验,上电,接收模式
       CE = 1;                                            // 拉高CE启动接收设备
         delay(130);
}

void TX_Mode(void)
{
         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);  // 为了应答接收设备,接收通道0地址和发送地址相同
       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);  // 自动重发延时等待250us+86us,自动重发10
       SPI_RW_Reg(WRITE_REG + RF_CH, 40);         // 选择射频通道0x40
       SPI_RW_Reg(WRITE_REG + RF_SETUP,0x07);    // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益
       SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);      // CRC使能,16CRC校验,上电
         CE= 1;
         delay(130);
}

unsigned char nRF24L01_RxPacket(unsignedchar* rx_buf)
{
   unsigned char revale=0;
         sta=SPI_Read(STATUS);   // 读取状态寄存其来判断数据接收状况
         if(RX_DR)                             // 判断是否接收到数据
         {
             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来清楚中断标志
         returnrevale;
}

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收发完成中断响应,16CRC,主发送
         CE=1;                  //置高CE,激发数据发送                      .
         delay(10);
}



相关帖子

沙发
xujuanliang| | 2014-12-23 21:28 | 只看该作者
拿分路过 这么复杂!

使用特权

评论回复
板凳
温雨无明| | 2016-3-22 15:11 | 只看该作者
你好楼主,这个实现无线通信使用到两个单片机板子吗?一个接受,一个发送。能不能拍一张图片给我看看?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

21

帖子

0

粉丝