微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 430控制的NRF24L01程序有点问题、、、

430控制的NRF24L01程序有点问题、、、

时间:10-02 整理:3721RD 点击:
430控制的NRF24L01接收程序有点问题,哪位大神给瞧瞧、、、
#include "msp430x14x.h"
#include "BoardConfig.h"
#define uchar  unsigned  char
#define  uint  unsigned  int

/*******************NRF24L01端口定义************/
#define BIT(x)  (1 << (x))
#define CE      5
#define CSN     4
#define SCLK     3
#define MOSI    2
#define MISO    1
#define IRQ     0
#define PORT    P5OUT
#define PDIR    P5DIR
#define PIN     P5IN
#define   TX_ADR_WIDTH       5  // 5 bytes TX(RX) address width
#define   RX_ADR_WIDTH       5  // 5 bytes TX(RX) address width
#define   TX_PLOAD_WIDTH     32  // 1 bytes TX payload
#define   RX_PLOAD_WIDTH     32  // 1 bytes TX payload
uchar TX_ADDRESS[TX_ADR_WIDTH]= {0xE7,0xE7,0xE7,0xE7,0xE7};//本地地址
uchar RX_ADDRESS[RX_ADR_WIDTH]= {0xE7,0xE7,0xE7,0xE7,0xE7};//接收地址
/*************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 IO_init();
void nrf2401_init();
uchar SPI_RW(uchar byte);
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);
void RX_Mode(void);
uchar nRF24L01_RxPacket(unsigned char* rx_buf);
void  nRF24L01_TxPacket(unsigned char * tx_buf);
void delay(uint t)
{
    uint i;
    for(i=0;i<t;i++);
}

/*******************NRF24L01检测是否存在***************/
uchar NRF24L01_Check(void)
{
        uchar bu[5]={0XA5,0XA5,0XA5,0XA5,0XA5};
        uchar bu1[5];
        uchar i;            
        SPI_Write_Buf(WRITE_REG+TX_ADDR,bu,5);//写入5个字节的地址.       
        SPI_Read_Buf(TX_ADDR,bu1,5);              //读出写入的地址         
        for(i=0;i<5;i++)if(bu1[i]!=0XA5)break;                                          
        if(i!=5)   return 1;                               //NRF24L01不在位       
        return 0;                                                //NRF24L01在位
}
/*********************NRF2401初始化****************************/
void  nrf2401_init()
{
      delay(100);
      PORT &=~BIT(CE);
      PORT |= BIT(CSN);
      PORT &=~BIT(SCLK);
      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);        //   设置信道工作为2.4GHZ,收发必须一致
      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, 0x0e);                    // IRQ收发完成中断响应,16位CRC,主发送
}
/*********************读写操作********************/

uchar SPI_RW(uchar byte)
{
    uchar i;
    PORT &=~(BIT(SCLK));
           for(i=0;i<8;i++) // output 8-bit
           {      
               if(byte & 0x80)
                       PORT |= BIT(MOSI);                  
        else
        {
            PORT &= ~(BIT(MOSI)); // output "byte", MSB to MOSI
        }
                   byte = (byte << 1);  // shift next bit into MSB..
                   PORT |=BIT(SCLK);     // Set clk high..
        if(PIN&(BIT(MISO)))
                       byte |= BIT0;  // capture current MISO bit
        else
        {  
            byte &=~BIT0;
        }
                   PORT &=~BIT(SCLK);   // set  clk low
           }
        PORT &=~(BIT(MOSI));        //PULL DOWN THE MOSI
    return byte;
}
/*******************读写寄存器*********************/

uchar SPI_RW_Reg(uchar reg, uchar value)
{
        uchar status;
          PORT &=~BIT(CSN);          // CSN low, init SPI transaction
          status = SPI_RW(reg);     // select register
          SPI_RW(value);           // ..and write value to it..
          PORT |=BIT(CSN);        // CSN high again
          return status;        // return nRF24L01 status byte
}
/***********************读一个字节从24L01********************/

uchar SPI_Read(uchar reg)
{
        uchar reg_val;
          PORT &=~BIT(CSN);        // CSN low, initialize SPI communication...
          SPI_RW(reg);            // Select register to read from..
          reg_val = SPI_RW(0);   // ..then read registervalue
          PORT |=BIT(CSN);      // CSN high, terminate SPI communication
          return reg_val;      // return register value
}
/**********************read RX payload, Rx/Tx address********************/
/*****************连续读多个寄存器函数******************************/

uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
        uchar status,byte_ctr;
          PORT &=~BIT(CSN);      // 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);  // Perform SPI_RW to read byte from nRF24L01
          PORT |=BIT(CSN);     // Set CSN high again
          return status;     // return nRF24L01 status byte
}
/*****************write TX payload, Rx/Tx address********************/
/*****************连续写多个寄存器函数******************************/

uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
        uchar status,byte_ctr;
          PORT &=~BIT(CSN);      // 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++);
          PORT |=BIT(CSN);     // Set CSN high again
          return status;      // return nRF24L01 status byte
}
/***************数据接收配置函数******************/
void RX_mode()
{
      PORT &=~BIT(CE);
      SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);  
      PORT |= BIT(CE);
      delay(200);
}
/**************数据读取后放如rx_buf接收缓冲区中**************/
uchar nRF24L01_RxPacket(unsigned char* rx_buf)
{
      uchar flag=0;
      uchar status;
       
      status=SPI_Read(STATUS);        // 读取状态寄存器来判断数据接收状况
       
        if(status & 0x40)                                // 判断是否接收到数据
        {
           PORT &= ~BIT(CE); //SPI使能
        SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH); // read receive payload from RX_FIFO buffer
        flag =1;
        }
        SPI_RW_Reg(WRITE_REG+STATUS, status);   //接收到数据后RX_DR,TX_DS,MAX_RT都置高为1,通过写1来清楚中断标志
        return flag;
}
/************************发送数据函数**************************/
/****************--功能:发送 tx_buf中数据--******************/
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
        PORT &=~BIT(CE);                //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,主发送
        PORT |= BIT(CE); //置高CE,激发数据发送       
        delay(50);
}
  /**********选择系统主时钟为8MHz********/
void clock_init()
{
    uchar i;
    BCSCTL1 &= ~XT2OFF;                 // 打开XT2高频晶体振荡器
    do
    {
        IFG1 &= ~OFIFG;                 //清除晶振失败标志
        for (i = 0xFF; i > 0; i--);     //等待8MHz晶体起振
    }
    while ((IFG1 & OFIFG));             // 晶振失效标志仍然存在
    BCSCTL2 |= SELM_2+SELS;             //选择主时钟为高频晶振
}
/**************************IO端口初始化***********************/
void IO_init()
{
    PDIR  |= BIT(CSN) + BIT(CE) + BIT(SCLK) + BIT(MOSI);
    P3OUT |=0xff;
}
void main()
{
  uchar RxBuf[32];
        // Stop watchdog timer to prevent time out reset
        WDTCTL = WDTPW + WDTHOLD;
        BoardConfig(0xba);
        nrf2401_init();
       // clock_init();
        IO_init();
        while(1)
        {
            RX_mode();
           // while(!nRF24L01_RxPacket(RxBuf));
            nRF24L01_RxPacket(RxBuf);
            if(RxBuf[0]==1)
            {            
              P3OUT =0x01;
              delay(1000);
              RxBuf[0]=0;
            }
        }
}

正好在写一样的 坐等            

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top