This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F149硬件SPI能够驱动nrf24l01+吗?

Other Parts Discussed in Thread: MSP430F149

如题 不知道MSP430F149硬件SPI能不能够驱动nrf24l01+ 搜索到的大多数例程都是GPIO模拟spi驱动

如果能的话 有没有例程   如果不能的话 模拟spi如何提高其传输速度

  • 可以的,没有问题,可以参考下下面的代码。
    www.it610.com/.../1939800.htm
  • msp430的spi可以支持24l01的,只需要简单配置就可以

  • 可以实现的,您可以参考下之前楼上提供的相关程序

    e2echina.ti.com/.../79097
  • 我下载了您的程序 但是里面关于spi模式的启动与ti给的里程不一样啊

    函数名称:Init_Usart
    功    能:串口初始化
    参    数:无
    返回值  :无
    *******************************************************/
    void Init_Usart(void)
    {
        P3SEL |= 0x30;          // 选择P3.4和P3.5做UART通信端口
        ME1 |= UTXE0 + URXE0;   // 使能USART0的发送和接受                                           这里面模式选择是uart并不是spi啊
        UCTL0 |= CHAR;          // 选择8位字符
        UTCTL0 |= SSEL0;        // UCLK = ACLK
        UBR00 = 0x03;           // 波特率9600
        UBR10 = 0x00;           //
        UMCTL0 = 0x4A;          // Modulation
        UCTL0 &= ~SWRST;        // 初始化UART状态机
        IE1 |= URXIE0;          // 使能USART0的接收中断
        _EINT();                //打开全局中断
    }

    帮我解答一下 谢谢 我之前也用的是这类似的程序 但是速度比较慢 想实现80kbsps也就是 一秒传输10000字节的数据 并且将其写入flash中 现在只能达到一秒写入400个字节

  • 这个程序使uart的。你需要找个spi的例程修改下。

    要传输10000字节,波特率至少要115200,考虑到还有写flash,建议选择高一倍以上的波特率。

    还有要注意合理安排程序任务。

  • 只是修改一下是能寄存器的配置就能spi驱动nrf了吗,NRF24L01+的头文件不用改吗

  • 不用修改 NRF24L01+ 中的程序吗?
    //----------------------------------硬件地址配置-----------------------
    #define BIT(x) (1 << (x))
    #define CE 0 //NRF24L01收发切换线
    #define CSN 1 //SPI片选线
    #define SCK 2 //SPI时钟线
    #define MOSI 3 //SPI数据输入线
    #define MISO 4 //SPI数据输出线
    #define IRQ 5 //NRF24L01中断线

    #define NRF24L01_DIR P2DIR
    #define NRF24L01_OUT P2OUT
    #define NRF24L01_IN P2IN
    //写端口
    #define NRF24L01_MOSI_H NRF24L01_OUT|= BIT(MOSI) //MOSI=1
    #define NRF24L01_MOSI_L NRF24L01_OUT&=~BIT(MOSI) //MOSI=0
    #define NRF24L01_SCK_H NRF24L01_OUT|= BIT(SCK) //SCK=1
    #define NRF24L01_SCK_L NRF24L01_OUT&=~BIT(SCK) //SCK=0
    #define NRF24L01_CE_H NRF24L01_OUT|= BIT(CE) //CE=1
    #define NRF24L01_CE_L NRF24L01_OUT&=~BIT(CE) //CE=0
    #define NRF24L01_CSN_H NRF24L01_OUT|= BIT(CSN) //CE=1
    #define NRF24L01_CSN_L NRF24L01_OUT&=~BIT(CSN) //CE=0
    //读端口
    #define NRF24L01_MISO (NRF24L01_IN & BIT(MISO))
    #define NRF24L01_IRQ (NRF24L01_IN & BIT(IRQ))
    //-----------------------------------常数定义-----------------------------------------------
    #define TX_ADR_WIDTH 5 // 5 uints TX address width
    #define RX_ADR_WIDTH 5 // 5 uints RX address width
    #define TX_PLOAD_WIDTH 20 // 20 uints TX payload
    #define RX_PLOAD_WIDTH 20 // 20 uints TX payload
    unsigned char TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址
    unsigned char RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
    //-------------------------------------相关标志定义-----------------------------------------
    #define MAX_TX 0x10 //达到最大发送次数中断
    #define TX_OK 0x20 //TX发送完成中断
    #define RX_OK 0x40 //接收到数据中断
    //-----------------------------------NRF24L01 寄存器指令------------------------------------
    #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 //刷新发送 FIFO 指令// Define flush TX register command
    #define FLUSH_RX 0xE2 //刷新接收 FIFO 指令// 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) 寄存器地址--------------------------------------
    #define CONFIG 0x00 //配置收发状态,CRC 校验模式以及收发状态响应方式// '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 //频道0 接收数据地址// 'RX address pipe0' register address
    #define RX_ADDR_P1 0x0B //频道1 接收数据地址// 'RX address pipe1' register address
    #define RX_ADDR_P2 0x0C //频道2 接收数据地址 // 'RX address pipe2' register address
    #define RX_ADDR_P3 0x0D //频道3 接收数据地址// 'RX address pipe3' register address
    #define RX_ADDR_P4 0x0E //频道4 接收数据地址// 'RX address pipe4' register address
    #define RX_ADDR_P5 0x0F //频道5 接收数据地址// 'RX address pipe5' register address
    #define TX_ADDR 0x10 //发送地址寄存器// 'TX address' register address
    #define RX_PW_P0 0x11 //接收频道0 接收数据长度// 'RX payload width, pipe0' register address
    #define RX_PW_P1 0x12 //接收频道1 接收数据长度// 'RX payload width, pipe1' register address
    #define RX_PW_P2 0x13 //接收频道2 接收数据长度// 'RX payload width, pipe2' register address
    #define RX_PW_P3 0x14 //接收频道3 接收数据长度// 'RX payload width, pipe3' register address
    #define RX_PW_P4 0x15 //接收频道4 接收数据长度// 'RX payload width, pipe4' register address
    #define RX_PW_P5 0x16 //接收频道5 接收数据长度// 'RX payload width, pipe5' register address
    #define FIFO_STATUS 0x17 //FIFO栈入栈出状态寄存器设置// 'FIFO Status Register' register address
    //----------------------------函数声明----------------------------------------------
    unsigned char SPI_RW(unsigned char byte);
    unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value);
    unsigned char SPI_Read(unsigned char reg);
    unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes);
    unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes);
    void RX_Mode(void);
    void TX_Mode(void);
    unsigned char NRF24L01_Check(void);
    unsigned char NRF24L01_TxPacket(unsigned char *txbuf);
    unsigned char NRF24L01_RxPacket(unsigned char *rxbuf);
    /*********************************************************
    函数名称:init_io
    功 能:初始化I/O口
    参 数:无
    返回值 :无
    *********************************************************/
    void init_io(void)
    {
    NRF24L01_DIR |= BIT(CE);
    NRF24L01_DIR |= BIT(CSN);
    NRF24L01_DIR |= BIT(SCK);
    NRF24L01_DIR |= BIT(MOSI);
    NRF24L01_DIR &= ~BIT(MISO);
    NRF24L01_DIR &= ~BIT(IRQ);

    NRF24L01_CE_L; // 待机
    NRF24L01_CSN_H; // SPI禁止
    NRF24L01_SCK_L; // SPI时钟置低

    }
    /*********************************************************
    函数名称:SPI_RW
    功 能:完成 GPIO模拟 SPI 的功能 这里也写明了时模拟spi,需不需要修改呢, 如果硬件选择了spi模式
    参 数:byte--写入SPI总线上的一个字节数据
    返回值 :读取SPI总线上的一个字节数据
    *********************************************************/
    unsigned char SPI_RW(unsigned char byte)
    {
    unsigned char bit_ctr;
    for(bit_ctr=0;bit_ctr<8;bit_ctr++)
    {
    if(byte & 0x80) NRF24L01_MOSI_H;

    else NRF24L01_MOSI_L;

    byte = (byte << 1);

    NRF24L01_SCK_H;

    if(NRF24L01_MISO) byte |= 1;

    NRF24L01_SCK_L;

    }
    return(byte);
    }
    谢谢解答
  • 剩余的NRF24L01头文件程序如下:
    /*********************************************************
    函数名称:SPI_RW_Reg
    功 能:用来设置 24L01 的寄存器的值
    参 数:reg--要写入数据的寄存器地址
    value--要写入的数据
    返回值 :该地址的原有值
    *********************************************************/
    unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)
    {
    unsigned char status;
    NRF24L01_CSN_L;
    status = SPI_RW(reg);
    SPI_RW(value);
    NRF24L01_CSN_H;
    return(status);
    }
    /*********************************************************
    函数名称:SPI_Read
    功 能:读取 24L01 的寄存器的值
    参 数:reg--要读取数据的寄存器地址
    返回值 :该地址的值
    *********************************************************/
    unsigned char SPI_Read(unsigned char reg)
    {
    unsigned char reg_val;
    NRF24L01_CSN_L;
    SPI_RW(reg);
    reg_val = SPI_RW(0);
    NRF24L01_CSN_H;
    return(reg_val);
    }
    /*********************************************************
    函数名称:SPI_Read_Buf
    功 能:主要用来在接收时读取 FIFO 缓冲区中的值
    参 数:reg--要读取数据的寄存器地址
    *pBuf--数据绶存数组
    bytes--读取数据的长度
    返回值 :该地址的原有值
    *********************************************************/
    unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
    {
    unsigned char status,byte_ctr;

    NRF24L01_CSN_L;
    status = SPI_RW(reg);
    for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
    pBuf[byte_ctr] = SPI_RW(0);
    NRF24L01_CSN_H;
    return(status);
    }
    /*********************************************************
    函数名称:SPI_Write_Buf
    功 能:主要用来把数组里的数放到发射 FIFO缓冲区中
    参 数:reg--要写放数据的寄存器地址
    *pBuf--数据绶存数组
    bytes--写入数据的长度
    返回值 :该地址的原有值
    *********************************************************/
    unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
    {
    unsigned char status,byte_ctr;

    NRF24L01_CSN_L;
    status = SPI_RW(reg);
    for(byte_ctr=0; byte_ctr<bytes; byte_ctr++)
    SPI_RW(*pBuf++);
    NRF24L01_CSN_H;
    return(status);
    }
    /*********************************************************
    函数名称:Mode(多加的一个函数)
    功 能:
    参 数:
    返回值 :
    *********************************************************/
    void Mode(void)
    {
    NRF24L01_CE_L;
    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
    SPI_RW_Reg(WRITE_REG + RF_CH, 40); //设置信道工作为2.4GHZ,收发必须一致
    SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //0x0f //设置发射空中速率为2Mbps,发射功率为最大值0dB
    NRF24L01_CE_H;
    }
    /*********************************************************
    函数名称:RX_Mode
    功 能:
    参 数:
    返回值 :
    *********************************************************/
    void RX_Mode(void)
    {
    NRF24L01_CE_L;
    // 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
    // SPI_RW_Reg(WRITE_REG + RF_CH, 40); //设置信道工作为2.4GHZ,收发必须一致
    // SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //0x0f //设置发射空中速率为2Mbps,发射功率为最大值0dB
    SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); //接收数据通道 0 有效数据宽度-20个字节
    SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // CRC使能 16位CRC 校验 & Prim:TX. MAX_RT & TX_DS enabled..
    NRF24L01_CE_H;

    }
    /*********************************************************
    函数名称:TX_Mode
    功 能:该函数初始化NRF24L01到TX模式
    设置TX地址,写TX数据宽度,设置RX自动应答的地址,填充TX发送数据,选择RF频道,波特率和LNA HCURR
    PWR_UP,CRC使能
    当CE变高后大于10us,则可以启动发送数据了
    参 数:
    返回值 :
    *********************************************************/
    void TX_Mode(void)
    {
    NRF24L01_CE_L;
    SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); //写本地地址
    SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); //自动重发功能设置--延时时间500us + 86us, 从发次数10
    SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // CRC使能 16位CRC 校验 & Prim:TX. MAX_RT & TX_DS enabled..
    // 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
    // SPI_RW_Reg(WRITE_REG + RF_CH, 40); //设置信道工作为2.4GHZ,收发必须一致
    // SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射空中速率为2Mbps,发射功率为最大值0dB
    NRF24L01_CE_H; //CE为高,10us后启动发送
    }
    /*********************************************************
    函数名称:NRF24L01_Check
    功 能:检测24L01是否存在
    参 数:无
    返回值 :0,成功;1,失败
    *********************************************************/
    unsigned char NRF24L01_Check(void)
    {
    unsigned char buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};
    unsigned char i;
    SPI_Write_Buf(WRITE_REG+TX_ADDR,buf,5);//写入5个字节的地址.
    SPI_Read_Buf(TX_ADDR,buf,5); //读出写入的地址
    for(i=0;i<5;i++)if(buf[i]!=0XA5)break;
    if(i!=5)return 1;//检测24L01错误
    return 0; //检测到24L01
    }
    /*********************************************************
    函数名称:NRF24L01_TxPacket
    功 能:启动NRF24L01发送一次数据
    参 数:txbuf:待发送数据首地址
    返回值 :发送完成状况
    *********************************************************/
    unsigned char NRF24L01_TxPacket(unsigned char *txbuf)
    {
    unsigned char sta;
    NRF24L01_CE_L;
    SPI_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF 32个字节
    NRF24L01_CE_H;//启动发送
    while(NRF24L01_IRQ);//等待发送完成
    sta=SPI_Read(STATUS); //读取状态寄存器的值
    SPI_RW_Reg(WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志
    if(sta&MAX_TX)//达到最大重发次数
    {
    SPI_RW_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器
    return MAX_TX;
    }
    if(sta&TX_OK)//发送完成
    {
    return TX_OK;
    }
    return 0xff;//其他原因发送失败
    }
    /*********************************************************
    函数名称:NRF24L01_Check
    功 能:启动NRF24L01发送一次数据
    参 数:txbuf:待发送数据首地址
    返回值 :0,接收完成;其他,错误代码
    *********************************************************/
    unsigned char NRF24L01_RxPacket(unsigned char *rxbuf)
    {
    unsigned char sta;
    sta=SPI_Read(STATUS); //读取状态寄存器的值
    SPI_RW_Reg(WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志
    if(sta&RX_OK)//接收到数据
    {
    SPI_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
    SPI_RW_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器
    return 0;
    }
    return 1;//没收到任何数据
    }
    多谢解答
  • 如果您有现成的程序 让我看一下也可以,我不他明白 怎么修改
  • 没有现成的程序,因为我不用NRF24L01+,我都用ti的产品。
    NRF24L01+的头文件应该都是对这个器件内部寄存器的定义,你看下具体的手册,应该有通讯时序说明,根据这个调程序就可以。
  • 楼主,请问这个问题你解决了吗,我也遇到同样的问题,可以说明一下解决方法吗,谢谢

  • 我就是在楼上的大神的程序包里的程序修改的 但是效果不理想