NRF24L01实现msp430单片机通信(SPI)

2018-07-11 20:57:36编辑:什么鱼 关键字:NRF24L01  msp430  单片机通信  SPI

24l01.h

#ifndef _24L01_H_

#define _24L01_H_




/***************************************************/
typedef unsigned char     BYTE;


#define uchar unsigned char


//24L01发送接收数据宽度定义
#define TX_ADR_WIDTH    5   //5字节的地址宽度
#define RX_ADR_WIDTH    5   //5字节的地址宽度
#define TX_PLOAD_WIDTH  7  //20字节的用户数据宽度
#define RX_PLOAD_WIDTH  7  //20字节的用户数据宽度




#define nRF_TX_Mode 0x00
#define nRF_RX_Mode 0x01
///****************************************************************//
// 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
//========================
//STATUS REG ?μ?÷
#define MAX_RT   0x10  //′?μ?×?′ó·¢?í′?êy?D??
#define TX_OK   0x20  //TX·¢?ííê3é?D??
#define RX_OK   0x40  //?óê?μ?êy?Y?D??
/**************************************************/
#define nRF24L01_CE_1         P4OUT |=  BIT4              //CE = 1
#define nRF24L01_CE_0         P4OUT &=~ BIT4            //CE = 0
#define nRF24L01_CSN_1       P4OUT |=  BIT5             //CSN = 1
#define nRF24L01_CSN_0       P4OUT &=~ BIT5            //CSN = 0
#define nRF24L01_SCK_1       P5OUT |=  BIT3              //SCK = 1
#define nRF24L01_SCK_0       P5OUT &=~ BIT3            //SCK = 0
#define nRF24L01_MOSI_1   P5OUT |=  BIT2         //MOSI = 1
#define nRF24L01_MOSI_0   P5OUT &=~ BIT2       //MOSI = 0
#define nRF24L01_MISO_IN     ((P5IN>>1)  & 0x01)    //读入MISO,P5.1//((P5IN >> 1) & 0x04) 
/**************************************************/
/**************************************************/
///===============REG setting data===============
//===0x00 CONFIG===============
#define MASK_RX_DR 0x40
#define MASK_TX_DS 0x20
#define MASK_MAX_RT 0x10
#define EN_CRC 0x08
#define CRCO 0x04// 0---1byte,1---2byte
#define PWR_UP 0x02// 1---power up,0---power down
#define PRIM_RX 0x01// 1---RX mode,0---TX mode
//===0x01 EN_AA================
//使能自响应通道,默认5通道全开
#define ENAA_P5 0x20
#define ENAA_P4 0x10
#define ENAA_P3 0x08
#define ENAA_P2 0x04
#define ENAA_P1 0x02
#define ENAA_P0 0x01
#define ENAA_DisableALL 0x00
//===0x02 EN_RXADDR============
#define ERX_P5 0x20
#define ERX_P4 0x10
#define ERX_P3 0x08
#define ERX_P2 0x04
#define ERX_P1 0x02
#define ERX_P0 0x01
#define ERX_None 0x00
//===0x03 SETUP_AW=============
#define AW_3Bytes 0x01
#define AW_4Bytes 0x02
#define AW_5Bytes 0x03
//===0x04 SETUP_RETR============
#define AutoReTxDalay_250uS 0x00//default
#define AutoReTxDalay_500uS 0x10
#define AutoReTxDalay_750uS 0x20
#define AutoReTxDalay_1000uS 0x30
#define AutoReTxDalay_1250uS 0x40
#define AutoReTxDalay_1500uS 0x50
#define AutoReTxDalay_1750uS 0x60
#define AutoReTxDalay_2000uS 0x70
#define AutoReTxDalay_2250uS 0x80
#define AutoReTxDalay_2500uS 0x90
#define AutoReTxDalay_2750uS 0xA0
#define AutoReTxDalay_3000uS 0xB0
#define AutoReTxDalay_3250uS 0xC0
#define AutoReTxDalay_3500uS 0xD0
#define AutoReTxDalay_3750uS 0xE0
#define AutoReTxDalay_4000uS 0xF0
#define AutoReTx_Disable 0x00
#define AutoReTxTimes_1 0x01
#define AutoReTxTimes_2 0x02
#define AutoReTxTimes_3 0x03//default
#define AutoReTxTimes_4 0x04
#define AutoReTxTimes_5 0x05
#define AutoReTxTimes_6 0x06
#define AutoReTxTimes_7 0x07
#define AutoReTxTimes_8 0x08
#define AutoReTxTimes_9 0x09
#define AutoReTxTimes_10 0x0A
#define AutoReTxTimes_11 0x0B
#define AutoReTxTimes_12 0x0C
#define AutoReTxTimes_13 0x0D
#define AutoReTxTimes_14 0x0E
#define AutoReTxTimes_15 0x0F
//===0x06 RF_SETUP============
#define RF_DR_1Mbps 0x00
#define RF_DR_2Mbps 0x08
//#define RF_PWR_




uchar SPI_RW(uchar byte);
uchar SPI_RW_Reg(BYTE reg, BYTE value);
BYTE SPI_Read(BYTE reg);
uchar SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes);
uchar SPI_Write_Buf(BYTE reg, BYTE const *pBuf, BYTE bytes);
void RX_Mode(void);
void TX_Mode(void);
void nRF24L01_Init(unsigned char Mode);
void nRF24L01_Send(void);
void nRF24L01_Revceive(void);
uchar NRF_Check(void);
void nRF24L01_IO_set(void);


#endif


24l01.c


#include  <msp430x14x.h>
#include "24l01.h"


unsigned char TestBuf=0;




uchar  const TX_ADDRESS[TX_ADR_WIDTH]  = {0x6d,0x61,0x67,0x69,0x63}; // Define a static TX address
uchar rx_buf[RX_PLOAD_WIDTH];        
uchar tx_buf[TX_PLOAD_WIDTH]={0xB3,0x73,0x6b,0x79,0x00,0x00,0x00};//,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02};
uchar flag,q;


//******************************************************************************************
//延时函数
//******************************************************************************************


void delay_50us(unsigned int i)
{
//for(unsigned char i=0; i<77; i++);
unsigned long j;
for(;i>0;i--)
{
for(j=0;j<33;j++);//50.4us
}
}


void delay_100ms(unsigned int i)
{
unsigned long j;
for(;i>0;i--)
{
for(j=0;j<144200;j++);
}
}


void msDelay(unsigned int ms)
{
    unsigned int i,j;

    for(i=0;i    {
       j=1329;;
       while(j--);
    }
}
void delay_1ms(unsigned int i)
{
unsigned long j;
for(;i>0;i--)
{
//for(j=0;j<640;j++);//8M--->880us
for(j=0;j<730;j++);//8M--->1ms
//for(j=0;j<80;j++);//1M
//for(j=0;j<200;j++);//1M 1ms延时是对的,但345数据在12ms就准备完成了,这影响后面计数
}
}
void inerDelay_us(int n)
{
for(;n>0;n--);
}


//***********************************************************************************
void CE_Pin(BYTE state)
{
    if(state)
    nRF24L01_CE_1;
  else
    nRF24L01_CE_0;
}


//***********************************************************************************
//***********************************************************************************
void CSN_Pin(BYTE state)                                // Set/reset CSN pin
{
    if(state)
    nRF24L01_CSN_1;
  else
    nRF24L01_CSN_0;
}
//***********************************************************************************
//***********************************************************************************
void SCK_Pin(BYTE state)                                // Set/reset SCK pin
{
  if(state)
    nRF24L01_SCK_1;
  else
    nRF24L01_SCK_0;
}
//***********************************************************************************
//***********************************************************************************
void MOSI_Pin(BYTE state)                               // Set/reset MOSI pin
{
  if(state)
    nRF24L01_MOSI_1;
  else
    nRF24L01_MOSI_0;
}
//***********************************************************************************
//***********************************************************************************


BYTE MISO_Pin(void)                                     // Read MISO pin
{
  return nRF24L01_MISO_IN;
}
//**************************************************
//Function: SPI_RW();


//escription:
 // Writes one byte to nRF24L01, and return the byte read
 // from nRF24L01 during write, according to SPI protocol
//**************************************************/
uchar SPI_RW(uchar byte)
{
uchar bit_ctr;
    for(bit_ctr=0;bit_ctr<8;bit_ctr++)   // output 8-bit
    {
    MOSI_Pin(byte&0x80);         // output 'byte', MSB to MOSI
    byte = (byte << 1);           // shift next bit into MSB..
    SCK_Pin(1);// Set SCK high..
    byte|=MISO_Pin();        // capture current MISO bit
    SCK_Pin(0);              // ..then set SCK low again
    }
    return(byte);            // return read byte
}
/**************************************************/


//**************************************************
//Function: SPI_RW_Reg();


//Description:
 // Writes value 'value' to register 'reg'
//**************************************************/
uchar SPI_RW_Reg(BYTE reg, BYTE value)
{
        uchar status;
  CSN_Pin(0);                   // CSN low, init SPI transaction
  status = SPI_RW(reg);      // select register
  SPI_RW(value);             // ..and write value to it..
  CSN_Pin(1);                   // CSN high again


  return(status);            // return nRF24L01 status byte
        
}
/**************************************************/


/**************************************************
Function: SPI_Read();


Description:
  Read one byte from nRF24L01 register, 'reg'
**************************************************/
BYTE SPI_Read(BYTE reg)
{
BYTE reg_val;


  CSN_Pin(0);                // CSN low, initialize SPI communication...
  SPI_RW(reg);            // Select register to read from..
  reg_val = SPI_RW(0);    // ..then read registervalue
  CSN_Pin(1);                // CSN high, terminate SPI communication


  return(reg_val);        // return register value
}
/**************************************************/


/**************************************************
Function: SPI_Read_Buf();


Description:
  Reads 'bytes' #of bytes from register 'reg'
  Typically used to read RX payload, Rx/Tx address
**************************************************/
uchar SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
uchar status,byte_ctr;


  CSN_Pin(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    pBuf[byte_ctr] = SPI_RW(0);    // Perform SPI_RW to read byte from nRF24L01


  CSN_Pin(1);                           // Set CSN high again


  return(status);                    // return nRF24L01 status byte
}
/**************************************************/


/**************************************************
Function: SPI_Write_Buf();


Description:
  Writes contents of buffer '*pBuf' to nRF24L01
  Typically used to write TX payload, Rx/Tx address
**************************************************/
uchar SPI_Write_Buf(BYTE reg, BYTE const *pBuf, BYTE bytes)
{
uchar status,byte_ctr;


  CSN_Pin(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    SPI_RW(*pBuf++);
  CSN_Pin(1);                 // Set CSN high again
  return(status);          // return nRF24L01 status byte
}
/**************************************************/


//***********************************************************************************
/**************************************************
Function: RX_Mode();


Description:
  This function initializes one nRF24L01 device to
  RX Mode, set RX address, writes RX payload width,
  select RF channel, datarate & LNA HCURR.
  After init, CE is toggled high, which means that
  this device is now ready to receive a datapacket.
**************************************************/
void RX_Mode(void)
{
        CE_Pin(0);
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // D′±?μ?μ??· 
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, RX_ADR_WIDTH); // D′?óê???μ??·
SPI_RW_Reg(WRITE_REG + EN_AA, ENAA_DisableALL);  //???1×??ˉó|′e
SPI_RW_Reg(WRITE_REG + SETUP_RETR,AutoReTx_Disable);//???1×??ˉ??·¢
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  //  ?êDí?óê?μ??·??óD?μμà0
SPI_RW_Reg(WRITE_REG + RF_CH, 0);        //   éè??D?μà1¤×÷?a2.4GHZ£?ê?·¢±?D?ò???
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //éè???óê?êy?Y3¤?è
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x27);   //éè??·¢é??ù?ê?a250kHZ£?·¢é?1|?ê?a×?′ó?μ0dB
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);   // IRQê?·¢íê3é?D???ìó|£?16??CRC £?·¢?í
        CE_Pin(1);
}
/**************************************************/


/**************************************************
Function: TX_Mode();


Description:
  This function initializes one nRF24L01 device to
  TX mode, set TX address, set RX address for auto.ack,
  fill TX payload, select RF channel, datarate & TX pwr.
  PWR_UP is set, CRC(2 bytes) is enabled, & PRIM:TX.


  ToDo: One high pulse(>10us) on CE will now send this
  packet and expext an acknowledgment from the RX device.
**************************************************/
void TX_Mode(void)
{
CE_Pin(0);

  SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // D′±?μ?μ??· 
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, RX_ADR_WIDTH); // D′?óê???μ??·
SPI_RW_Reg(WRITE_REG + EN_AA, ENAA_DisableALL);  //???1×??ˉó|′e
SPI_RW_Reg(WRITE_REG + SETUP_RETR,AutoReTx_Disable);//???1×??ˉ??·¢
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  //  ?êDí?óê?μ??·??óD?μμà0
SPI_RW_Reg(WRITE_REG + RF_CH, 0);        //   éè??D?μà1¤×÷?a2.4GHZ£?ê?·¢±?D?ò???
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //éè???óê?êy?Y3¤?è
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x27);   //éè??·¢é??ù?ê?a250kHZ£?·¢é?1|?ê?a×?′ó?μ0dB
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);   // IRQê?·¢íê3é?D???ìó|£?16??CRC £?·¢?í
CE_Pin(1);


}




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


void nRF24L01_Init(unsigned char Mode)
{
TestBuf = SPI_Read(RX_ADDR_P4);//return is 0xC5,if connection is ok


if(Mode == nRF_TX_Mode)
TX_Mode();
else RX_Mode();
delay_1ms(2);//24L01 掉电模式到待机模式需要1.5ms
}




void nRF24L01_Send(void)
{
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // Writes data to TX payload
}


void nRF24L01_Revceive(void)
{
TestBuf = SPI_Read(STATUS);
SPI_RW_Reg(WRITE_REG+STATUS,TestBuf);
if(TestBuf&RX_OK)
{
SPI_Read_Buf(RD_RX_PLOAD, rx_buf, RX_PLOAD_WIDTH);
SPI_RW_Reg(FLUSH_RX, 0xff);
//Cycle_Cnt = (rx_buf[4]<<8)|rx_buf[5];
}

}
/*
 * 函数名:NRF_Check
 * 描述  :主要用于NRF与MCU是否正常连接
 * 输入  :无 
 * 输出  :SUCCESS/ERROR 连接正常/连接失败
 * 调用  :外部调用
 */
uchar NRF_Check(void)
{
uchar buf[5]={0xC2,0xC2,0xC2,0xC2,0xC2};
uchar buf1[5];
uchar i; 
 
/*写入5个字节的地址.  */  
SPI_Write_Buf(WRITE_REG+TX_ADDR,buf,5);


/*读出写入的地址 */
SPI_Read_Buf(TX_ADDR,buf1,5); 
 
/*比较*/               
for(i=0;i<5;i++)
{       
if(buf1[i]!=0xC2)
break;            

      
if(i==5)
return 1 ;        //MCU与NRF成功连接 
else
return 0 ;        //MCU与NRF不正常连接
              
}


void nRF24L01_IO_set(void)
{
      P4DIR |= BIT4;         //ce
      //P4OUT = BIT4;         //ce
      P4DIR |= BIT5;         //csn
      P5DIR |= BIT3;         //sck
      P5DIR |= BIT2;         //mosi out
      P5DIR &=~BIT1;         //MISO IN 
      P1DIR &=~BIT4;         //IRQ
      
      SCK_Pin(0);
      CE_Pin(0);
}


main.c

[1] [2]

关键字:NRF24L01  msp430  单片机通信  SPI

来源: eefocus 引用地址:http://www.eeworld.com.cn/mcu/2018/ic-news071140253.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:MSP430单片机USART串口发送字符和字符串
下一篇:LCD1602动态显示--基于MSP430F149单片机

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

nRF24L01单片机通信的总结

1周时间,我从一个没用过STC单片机,不知道什么叫SPI接口的“文盲”,把nRF24L01的整个通信过程弄到完全没有bug.。兴奋之余来小屁一下。给那些正在奋斗着这个牛逼的芯片的小牛们小炫一下。希望有所帮助。屁话少说。正题:基本的东西我理解了,那就是:1.用5根线的SPI接口向2401发送数据或指令。2.芯片在每次上电的时候都需要进行一番配置。这些配置数据,就是所谓的指令了。3.配置完成后知道芯片处在哪个模式。并且知道它将要转向哪个模式。4.通讯协议。5.观察现象。好了,小牛们一定急切想知道自己的程序问题出在哪里了,再小白一点的一定想急切的知道如何配置才能让它工作。更小白一点的一定想知道这个芯片的各个模式之间是怎么联系的。又是
发表于 2018-07-14 21:26:07

基于ATmega16单片机 NRF24L01无线收发驱动程序源代码

//NRF2401发送驱动程序#include <avr/io.h>#define  uint unsigned  int#define  uchar unsigned  char//------------------------------------------------------------------------------//--------------------------------NRF24L01接口定义
发表于 2018-06-21 20:10:25

NRF24L01无线模块接收-AVR程序代码

=0; uchar_ctr        SPI_RW(*pBuf++);    CSN = 1;           //关闭SPI    return(status);    // }     void init_NRF24L01(void
发表于 2017-11-23 20:50:00

NRF24L01无线模块发送-AVR程序代码

(*pBuf++);    CSN = 1;           //关闭SPI    return(status);    // }    void init_NRF24L01(void){delay_ms(1);CE=0; //射频停止工作CSN=1;SCK=0;IRQ=1;//中断复位SPI_RW_Reg
发表于 2017-11-23 20:49:16

AVR单片机nRF24L01发送接收驱动程序

//--------------------------------NRF24L01接口定义--------------------------------//------------------------------------------------------------------------------//#define NRF24L01_MISO PB6 //输入0#define Hign_24L01_MISO PORTB|=(1 << PB6)#define Low_24L01_MISO PORTB &= ~(1 << PB6)#define 
发表于 2017-11-18 10:43:08

MSP430G2553电子时钟实验

用msp430g2553控制1602液晶显示时间,并可以通过按键设置时间,我做了正计时和倒计时两种模式/*********************************************************************msp430g2553与1602引脚连接情况* PIN1 --> 地* PIN2 --> VCC(一定要接+5V)* PIN3 -->仿真时悬空,实际电路 2K电阻-->地 (电阻可以是500-2k的,改变电阻可以改变字符显示的亮度,电阻接不好会导致什么都不显示)* PIN4 --> RS --> P1.6* PIN5 --> R/W -->
发表于 2018-07-14 20:42:53

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2018 EEWORLD.com.cn, Inc. All rights reserved