如题 不知道MSP430F149硬件SPI能不能够驱动nrf24l01+ 搜索到的大多数例程都是GPIO模拟spi驱动
如果能的话 有没有例程 如果不能的话 模拟spi如何提高其传输速度
xyz549040622:
可以的,没有问题,可以参考下下面的代码。
www.it610.com/…/1939800.htm
灰小子:
msp430的spi可以支持24l01的,只需要简单配置就可以
Susan Yang:
可以实现的,您可以参考下之前楼上提供的相关程序
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 CE0//NRF24L01收发切换线
#define CSN1//SPI片选线
#define SCK2//SPI时钟线
#define MOSI3//SPI数据输入线
#define MISO4//SPI数据输出线
#define IRQ5//NRF24L01中断线#define NRF24L01_DIRP2DIR
#define NRF24L01_OUTP2OUT
#define NRF24L01_INP2IN
//写端口
#define NRF24L01_MOSI_HNRF24L01_OUT|= BIT(MOSI)//MOSI=1
#define NRF24L01_MOSI_LNRF24L01_OUT&=~BIT(MOSI)//MOSI=0
#define NRF24L01_SCK_HNRF24L01_OUT|= BIT(SCK)//SCK=1
#define NRF24L01_SCK_LNRF24L01_OUT&=~BIT(SCK)//SCK=0
#define NRF24L01_CE_HNRF24L01_OUT|= BIT(CE)//CE=1
#define NRF24L01_CE_LNRF24L01_OUT&=~BIT(CE)//CE=0
#define NRF24L01_CSN_HNRF24L01_OUT|= BIT(CSN)//CE=1
#define NRF24L01_CSN_LNRF24L01_OUT&=~BIT(CSN)//CE=0
//读端口
#define NRF24L01_MISO(NRF24L01_IN & BIT(MISO))
#define NRF24L01_IRQ(NRF24L01_IN & BIT(IRQ))
//———————————–常数定义———————————————–
#define TX_ADR_WIDTH5// 5 uints TX address width
#define RX_ADR_WIDTH5// 5 uints RX address width
#define TX_PLOAD_WIDTH20// 20 uints TX payload
#define RX_PLOAD_WIDTH20// 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_TX0x10//达到最大发送次数中断
#define TX_OK0x20//TX发送完成中断
#define RX_OK0x40//接收到数据中断
//———————————–NRF24L01 寄存器指令————————————
#define READ_REG0x00//读寄存器指令// Define read command to register
#define WRITE_REG0x20//写寄存器指令// Define write command to register
#define RD_RX_PLOAD0x61//读取接收数据指令// Define RX payload register address
#define WR_TX_PLOAD0xA0//写待发数据指令// Define TX payload register address
#define FLUSH_TX0xE1//刷新发送 FIFO 指令// Define flush TX register command
#define FLUSH_RX0xE2//刷新接收 FIFO 指令// Define flush RX register command
#define REUSE_TX_PL0xE3//定义重复装载数据指令// Define reuse TX payload register command
#define NOP0xFF//保留// Define No Operation, might be used to read status register
//———————————-SPI(nRF24L01) 寄存器地址————————————–
#define CONFIG0x00//配置收发状态,CRC 校验模式以及收发状态响应方式// 'Config' register address
#define EN_AA0x01//自动应答功能设置// 'Enable Auto Acknowledgment' register address
#define EN_RXADDR0x02//可用信道设置// 'Enabled RX addresses' register address
#define SETUP_AW0x03//收发地址宽度设置// 'Setup address width' register address
#define SETUP_RETR0x04//自动重发功能设置// 'Setup Auto. Retrans' register address
#define RF_CH0x05//工作频率设置// 'RF channel' register address
#define RF_SETUP0x06//发射速率、功耗功能设置// 'RF setup' register address
#define STATUS0x07//状态寄存器// 'Status' register address
#define OBSERVE_TX0x08//发送监测功能// 'Observe TX' register address
#define CD0x09//地址检测 // 'Carrier Detect' register address
#define RX_ADDR_P00x0A//频道0 接收数据地址// 'RX address pipe0' register address
#define RX_ADDR_P10x0B//频道1 接收数据地址// 'RX address pipe1' register address
#define RX_ADDR_P20x0C//频道2 接收数据地址 // 'RX address pipe2' register address
#define RX_ADDR_P30x0D//频道3 接收数据地址// 'RX address pipe3' register address
#define RX_ADDR_P40x0E//频道4 接收数据地址// 'RX address pipe4' register address
#define RX_ADDR_P50x0F//频道5 接收数据地址// 'RX address pipe5' register address
#define TX_ADDR0x10//发送地址寄存器// 'TX address' register address
#define RX_PW_P00x11//接收频道0 接收数据长度// 'RX payload width, pipe0' register address
#define RX_PW_P10x12//接收频道1 接收数据长度// 'RX payload width, pipe1' register address
#define RX_PW_P20x13//接收频道2 接收数据长度// 'RX payload width, pipe2' register address
#define RX_PW_P30x14//接收频道3 接收数据长度// 'RX payload width, pipe3' register address
#define RX_PW_P40x15//接收频道4 接收数据长度// 'RX payload width, pipe4' register address
#define RX_PW_P50x16//接收频道5 接收数据长度// 'RX payload width, pipe5' register address
#define FIFO_STATUS0x17//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;elseNRF24L01_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,发射功率为最大值0dBNRF24L01_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 HCURRPWR_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, 从发次数10SPI_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,发射功率为最大值0dBNRF24L01_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 BUF32个字节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+的头文件应该都是对这个器件内部寄存器的定义,你看下具体的手册,应该有通讯时序说明,根据这个调程序就可以。