spi通信基本函数
硬件spi:
/发送数据,同时返回最近收到的数据
u8 SPI1_ReadWriteByte(u8 TxData)
{
u8 retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
{
retry++;
if(retry>200)return 0;
}
SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据
retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)//检查指定的SPI标志位设置与否:接受缓存非空标志位
{
retry++;
if(retry>200)return 0;
}
return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据
}
还得初始化spi,部分代码如下:
SPI_CPOL = SPI_CPOL_Low;
SPI_CPHA = SPI_CPHA_1Edge;
模拟spi:
uchar SPI_RW(uchar byte)
{
uchar bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
{
MOSI = (byte & 0x80); // output 'byte', MSB to MOSI
byte = (byte << 1); // shift next bit into MSB..
SCK = 1; // Set SCK high..
byte |= MISO; // capture current MISO bit
SCK = 0; // ..then set SCK low again
}
return(byte); // return read byte
}
最基本的函数,完成GPIO 模拟SPI 的功能。将输出字节(MOSI)从MSB循环输出,同时将输入字节(MISO)从LSB 循环移入。对NRF器件来说是上升沿读入stm32芯片发来的电平信号,下降沿输出电平信号给stm32芯片。(SCK 被初始化为低电平)
有了上面的基本函数,硬件spi和模拟spi基本一致:
读写寄存器
硬件spi:
//读取SPI寄存器值
//reg:要读的寄存器
u8 NRF24L01_Read_Reg(u8 reg)
{
u8 reg_val;
NRF24L01_CSN = 0; //使能SPI传输
SPI1_ReadWriteByte(reg); //发送寄存器号
reg_val=SPI1_ReadWriteByte(0XFF);//读取寄存器内容
NRF24L01_CSN = 1; //禁止SPI传输
return(reg_val); //返回状态值
}
//SPI写寄存器
//reg:指定寄存器地址
//value:写入的值
u8 NRF24L01_Write_Reg(u8 reg,u8 value)
{
u8 status;
NRF24L01_CSN=0; //使能SPI传输
status =SPI1_ReadWriteByte(reg);//发送寄存器号
SPI1_ReadWriteByte(value); //写入寄存器的值
NRF24L01_CSN=1; //禁止SPI传输
return(status); //返回状态值
}
模拟spi:
上面的截图中有个函数uchar SPI_RW_Reg(uchar reg, uchar value),读写寄存器,实际是写寄存器的功能,uchar SPI_Read(uchar reg)就是读寄存器功能,下面改名为uchar SPI_R_Reg(uchar reg,uchar reg)
寄存器访问函数:用来设置24L01 的寄存器的值。基本思路就是通过WRITE_REG 命令(也就是0x20+寄存器地址)需要注意的是,访问NRF24L01 之前首先要enable 芯片CSN=0;),访问完了以后再disable芯片(CSN=1;)。
把要设定的值写到相应的寄存器地址里面去,并读取返回值。对于函数来说也就是把value 值写到reg 寄存器中。
uchar SPI_W_Reg(uchar reg, uchar value)
{
uchar status;
CSN = 0; // CSN low, init SPI transaction
status = SPI_RW(reg); // select register
SPI_RW(value); // ..and write value to it..
CSN = 1; // CSN high again
return(status); // return nRF24L01 status byte
}
读寄存器功能改为:
uchar SPI_R_Reg(uchar reg)
{
uchar reg_val;
CSN = 0; // CSN low, initialize SPI communication
SPI_RW(reg); // Select register to read from..
reg_val = SPI_RW(0); // ..then read registervalue
CSN = 1; // CSN high, terminate SPI communication
return(reg_val); // return register value
}
其中reg_val=SPI_RW(0XFF); 和reg_val = SPI_RW(0); 好像都行,难道是随便发什么过去,得到返回值就行?
在指定位置读出和写入指定长度的数据
硬件spi:
//在指定位置读出指定长度的数据
//reg:寄存器(位置)
//*pBuf:数据指针
//len:数据长度
//返回值,此次读到的状态寄存器值
先发送寄存器值(位置),并读取状态值用来最后返回,然后循环读出数据,放入数组pBuf[u8_ctr] 缓存。
u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len)
{
u8 status,u8_ctr;
NRF24L01_CSN = 0; //使能SPI传输
status=SPI1_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值
for(u8_ctr=0;u8_ctr
NRF24L01_CSN=1; //关闭SPI传输
return status; //返回读到的状态值
}
//在指定位置写入指定长度的数据
//reg:寄存器(位置)
//*pBuf:数据指针
//len:数据长度
//返回值,此次读到的状态寄存器值
先发送寄存器值(位置),并读取状态值用来最后返回,然后通过 * pBuf++自增循环写入数据。
u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len)
{
u8 status,u8_ctr;
NRF24L01_CSN = 0; //使能SPI传输
status = SPI1_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值
for(u8_ctr=0; u8_ctr
NRF24L01_CSN = 1; //关闭SPI传输
return status; //返回读到的状态值
}
模拟spi:
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
uchar status,byte_ctr;
CSN = 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 = 1; // Set CSN high again
return(status); // return nRF24L01 status byte
}
主要用来在接收时读取FIFO 缓冲区中的值。基本思
路就是通过READ_REG 命令把数据从接收FIFO(RD_RX_PLOAD)中读出并存到数组里面去。
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
uchar status,byte_ctr;
CSN = 0; // Set CSN low, init SPI tranaction
status = SPI_RW(reg); // Select register to write to and read
status byte
Uart_Delay(10);
for(byte_ctr=0; byte_ctr
byte in buffer(*pBuf)
SPI_RW(*pBuf++);
CSN = 1; // Set CSN high again
return(status); // return nRF24L01 status byte
发射缓冲区访问函数:主要用来把数组里的数放到发射FIFO 缓冲区中。基本思路就是通过WRITE_REG 命令把数据存到发射FIFO(WR_TX_PLOAD)中去。
发送,接收模式
硬件spi:
发送模式:
//该函数初始化NRF24L01到TX模式
//设置TX地址,写TX数据宽度,设置RX自动应答的地址,填充TX发送数据,选择RF频道,波特率和LNA HCURR
//PWR_UP,CRC使能
//当CE变高后,即进入RX模式,并可以接收数据了
//CE为高大于10us,则启动发送.
void NRF24L01_TX_Mode(void)
{
NRF24L01_CE=0;
NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址
NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址
NRF24L01_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40); //设置RF通道为40
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启
NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG,0x0e); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断
NRF24L01_CE=1;//CE为高,10us后启动发送
}
接收模式:
//该函数初始化NRF24L01到RX模式
//设置RX地址,写RX数据宽度,选择RF频道,波特率和LNA HCURR
//当CE变高后,即进入RX模式,并可以接收数据了
void NRF24L01_RX_Mode(void)
{
NRF24L01_CE=0;
NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40); //设置RF通信频率
NRF24L01_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启
NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG, 0x0f); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式
NRF24L01_CE = 1; //CE为高,进入接收模式
}
模拟spi:
接收模式:
void RX_Mode(void)
{
CE=0;
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40
SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // Set PWR_UP bit, enable
CRC(2 bytes)
& Prim:RX. RX_DR enabled..
CE = 1; // Set CE pin high to enable RX device
// This device is now ready to receive one packet of 16 bytes
payload from a TX device
sending to address
// '3443101001', with auto acknowledgment, retransmit count of 10,
RF channel 40 and
datarate = 2Mbps.
}
发送模式:
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, TX_ADDRESS, TX_ADR_WIDTH);
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // Writes
data to TX payload
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10
retrans...
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm,
Datarate:2Mbps,
LNA:HCURR
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // Set PWR_UP bit, enable
CRC(2 bytes)
& Prim:TX. MAX_RT & TX_DS enabled..
CE=1;
}
NRF24L01寄存器操作命令,可理解为想对寄存器做什么?是读还是写?等等,也就是how?。
为什么要这样宏定义?
看图:
中文:
举例,第一个宏:
READ_REG 命令(也就是0x00+寄存器地址)
#define NRF_READ_REG 0x00 //读配置寄存器,低5位为寄存器地址,对应二进制0000 0000
对应表格:
000代表想读的寄存器地址,为了理解和操作方便,把它变成基地址+寄存器地址的形式:NRF_READ_REG +寄存器地址,其中NRF_READ_REG代表0000 0000.也就是0x00
第二个宏:
#define NRF_WRITE_REG 0x20 //写配置寄存器,低5位为寄存器地址,对应二进制0010 0000
对应表格:
001代表想写的寄存器地址,为了理解和操作方便,把它变成基地址+寄存器地址的形式:NRF_WRITE_REG+寄存器地址,其中NRF_WRITE_REG代表0010 0000也就是0x20
WRITE_REG 命令(也就是0x20+寄存器地址)
SPI(NRF24L01)寄存器地址想操作的寄存器在哪,也就是where?
寄存器地址来自如下:
总结:寄存器操作命令+寄存器地址就是how+where,去哪个寄存器,怎样操作这个寄存器
spi通信基本函数
硬件spi:
/发送数据,同时返回最近收到的数据
u8 SPI1_ReadWriteByte(u8 TxData)
{
u8 retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
{
retry++;
if(retry>200)return 0;
}
SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据
retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)//检查指定的SPI标志位设置与否:接受缓存非空标志位
{
retry++;
if(retry>200)return 0;
}
return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据
}
还得初始化spi,部分代码如下:
SPI_CPOL = SPI_CPOL_Low;
SPI_CPHA = SPI_CPHA_1Edge;
模拟spi:
uchar SPI_RW(uchar byte)
{
uchar bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
{
MOSI = (byte & 0x80); // output 'byte', MSB to MOSI
byte = (byte << 1); // shift next bit into MSB..
SCK = 1; // Set SCK high..
byte |= MISO; // capture current MISO bit
SCK = 0; // ..then set SCK low again
}
return(byte); // return read byte
}
最基本的函数,完成GPIO 模拟SPI 的功能。将输出字节(MOSI)从MSB循环输出,同时将输入字节(MISO)从LSB 循环移入。对NRF器件来说是上升沿读入stm32芯片发来的电平信号,下降沿输出电平信号给stm32芯片。(SCK 被初始化为低电平)
有了上面的基本函数,硬件spi和模拟spi基本一致:
读写寄存器
硬件spi:
//读取SPI寄存器值
//reg:要读的寄存器
u8 NRF24L01_Read_Reg(u8 reg)
{
u8 reg_val;
NRF24L01_CSN = 0; //使能SPI传输
SPI1_ReadWriteByte(reg); //发送寄存器号
reg_val=SPI1_ReadWriteByte(0XFF);//读取寄存器内容
NRF24L01_CSN = 1; //禁止SPI传输
return(reg_val); //返回状态值
}
//SPI写寄存器
//reg:指定寄存器地址
//value:写入的值
u8 NRF24L01_Write_Reg(u8 reg,u8 value)
{
u8 status;
NRF24L01_CSN=0; //使能SPI传输
status =SPI1_ReadWriteByte(reg);//发送寄存器号
SPI1_ReadWriteByte(value); //写入寄存器的值
NRF24L01_CSN=1; //禁止SPI传输
return(status); //返回状态值
}
模拟spi:
上面的截图中有个函数uchar SPI_RW_Reg(uchar reg, uchar value),读写寄存器,实际是写寄存器的功能,uchar SPI_Read(uchar reg)就是读寄存器功能,下面改名为uchar SPI_R_Reg(uchar reg,uchar reg)
寄存器访问函数:用来设置24L01 的寄存器的值。基本思路就是通过WRITE_REG 命令(也就是0x20+寄存器地址)需要注意的是,访问NRF24L01 之前首先要enable 芯片CSN=0;),访问完了以后再disable芯片(CSN=1;)。
把要设定的值写到相应的寄存器地址里面去,并读取返回值。对于函数来说也就是把value 值写到reg 寄存器中。
uchar SPI_W_Reg(uchar reg, uchar value)
{
uchar status;
CSN = 0; // CSN low, init SPI transaction
status = SPI_RW(reg); // select register
SPI_RW(value); // ..and write value to it..
CSN = 1; // CSN high again
return(status); // return nRF24L01 status byte
}
读寄存器功能改为:
uchar SPI_R_Reg(uchar reg)
{
uchar reg_val;
CSN = 0; // CSN low, initialize SPI communication
SPI_RW(reg); // Select register to read from..
reg_val = SPI_RW(0); // ..then read registervalue
CSN = 1; // CSN high, terminate SPI communication
return(reg_val); // return register value
}
其中reg_val=SPI_RW(0XFF); 和reg_val = SPI_RW(0); 好像都行,难道是随便发什么过去,得到返回值就行?
在指定位置读出和写入指定长度的数据
硬件spi:
//在指定位置读出指定长度的数据
//reg:寄存器(位置)
//*pBuf:数据指针
//len:数据长度
//返回值,此次读到的状态寄存器值
先发送寄存器值(位置),并读取状态值用来最后返回,然后循环读出数据,放入数组pBuf[u8_ctr] 缓存。
u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len)
{
u8 status,u8_ctr;
NRF24L01_CSN = 0; //使能SPI传输
status=SPI1_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值
for(u8_ctr=0;u8_ctr
NRF24L01_CSN=1; //关闭SPI传输
return status; //返回读到的状态值
}
//在指定位置写入指定长度的数据
//reg:寄存器(位置)
//*pBuf:数据指针
//len:数据长度
//返回值,此次读到的状态寄存器值
先发送寄存器值(位置),并读取状态值用来最后返回,然后通过 * pBuf++自增循环写入数据。
u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len)
{
u8 status,u8_ctr;
NRF24L01_CSN = 0; //使能SPI传输
status = SPI1_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值
for(u8_ctr=0; u8_ctr
NRF24L01_CSN = 1; //关闭SPI传输
return status; //返回读到的状态值
}
模拟spi:
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
uchar status,byte_ctr;
CSN = 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 = 1; // Set CSN high again
return(status); // return nRF24L01 status byte
}
主要用来在接收时读取FIFO 缓冲区中的值。基本思
路就是通过READ_REG 命令把数据从接收FIFO(RD_RX_PLOAD)中读出并存到数组里面去。
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
uchar status,byte_ctr;
CSN = 0; // Set CSN low, init SPI tranaction
status = SPI_RW(reg); // Select register to write to and read
status byte
Uart_Delay(10);
for(byte_ctr=0; byte_ctr
byte in buffer(*pBuf)
SPI_RW(*pBuf++);
CSN = 1; // Set CSN high again
return(status); // return nRF24L01 status byte
发射缓冲区访问函数:主要用来把数组里的数放到发射FIFO 缓冲区中。基本思路就是通过WRITE_REG 命令把数据存到发射FIFO(WR_TX_PLOAD)中去。
发送,接收模式
硬件spi:
发送模式:
//该函数初始化NRF24L01到TX模式
//设置TX地址,写TX数据宽度,设置RX自动应答的地址,填充TX发送数据,选择RF频道,波特率和LNA HCURR
//PWR_UP,CRC使能
//当CE变高后,即进入RX模式,并可以接收数据了
//CE为高大于10us,则启动发送.
void NRF24L01_TX_Mode(void)
{
NRF24L01_CE=0;
NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址
NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址
NRF24L01_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40); //设置RF通道为40
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启
NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG,0x0e); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断
NRF24L01_CE=1;//CE为高,10us后启动发送
}
接收模式:
//该函数初始化NRF24L01到RX模式
//设置RX地址,写RX数据宽度,选择RF频道,波特率和LNA HCURR
//当CE变高后,即进入RX模式,并可以接收数据了
void NRF24L01_RX_Mode(void)
{
NRF24L01_CE=0;
NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40); //设置RF通信频率
NRF24L01_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启
NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG, 0x0f); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式
NRF24L01_CE = 1; //CE为高,进入接收模式
}
模拟spi:
接收模式:
void RX_Mode(void)
{
CE=0;
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40
SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // Set PWR_UP bit, enable
CRC(2 bytes)
& Prim:RX. RX_DR enabled..
CE = 1; // Set CE pin high to enable RX device
// This device is now ready to receive one packet of 16 bytes
payload from a TX device
sending to address
// '3443101001', with auto acknowledgment, retransmit count of 10,
RF channel 40 and
datarate = 2Mbps.
}
发送模式:
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, TX_ADDRESS, TX_ADR_WIDTH);
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // Writes
data to TX payload
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10
retrans...
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm,
Datarate:2Mbps,
LNA:HCURR
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // Set PWR_UP bit, enable
CRC(2 bytes)
& Prim:TX. MAX_RT & TX_DS enabled..
CE=1;
}
NRF24L01寄存器操作命令,可理解为想对寄存器做什么?是读还是写?等等,也就是how?。
为什么要这样宏定义?
看图:
中文:
举例,第一个宏:
READ_REG 命令(也就是0x00+寄存器地址)
#define NRF_READ_REG 0x00 //读配置寄存器,低5位为寄存器地址,对应二进制0000 0000
对应表格:
000代表想读的寄存器地址,为了理解和操作方便,把它变成基地址+寄存器地址的形式:NRF_READ_REG +寄存器地址,其中NRF_READ_REG代表0000 0000.也就是0x00
第二个宏:
#define NRF_WRITE_REG 0x20 //写配置寄存器,低5位为寄存器地址,对应二进制0010 0000
对应表格:
001代表想写的寄存器地址,为了理解和操作方便,把它变成基地址+寄存器地址的形式:NRF_WRITE_REG+寄存器地址,其中NRF_WRITE_REG代表0010 0000也就是0x20
WRITE_REG 命令(也就是0x20+寄存器地址)
SPI(NRF24L01)寄存器地址想操作的寄存器在哪,也就是where?
寄存器地址来自如下:
总结:寄存器操作命令+寄存器地址就是how+where,去哪个寄存器,怎样操作这个寄存器
举报