Files
ZhaTianRC/Core/Src/nrf24l01.c

247 lines
6.5 KiB
C

/**
* NRF24L01+ 驱动实现
*/
#include "nrf24l01.h"
#include <string.h>
/* 全局状态 */
uint8_t nrf_connected = 0;
uint8_t nrf_bind_phrase[7] = "LOVE";
uint8_t nrf_channel = 40;
uint8_t nrf_tx_addr[NRF_ADDR_WIDTH] = {0xE7, 0xE7, 0xE7, 0xE7, 0xE7};
/* ---- 低层 SPI 操作 ---- */
static void NRF_SPI_CS(uint8_t level) {
if (level) NRF_CSN_H(); else NRF_CSN_L();
}
static uint8_t NRF_SPI_Transfer(uint8_t dat) {
uint8_t rx;
HAL_SPI_TransmitReceive(&hspi1, &dat, &rx, 1, 10);
return rx;
}
uint8_t NRF24L01_ReadReg(uint8_t reg) {
uint8_t val;
NRF_SPI_CS(0);
NRF_SPI_Transfer(NRF_CMD_R_REGISTER | reg);
val = NRF_SPI_Transfer(0xFF);
NRF_SPI_CS(1);
return val;
}
void NRF24L01_WriteReg(uint8_t reg, uint8_t value) {
NRF_SPI_CS(0);
NRF_SPI_Transfer(NRF_CMD_W_REGISTER | reg);
NRF_SPI_Transfer(value);
NRF_SPI_CS(1);
}
void NRF24L01_ReadBuf(uint8_t reg, uint8_t *buf, uint8_t len) {
NRF_SPI_CS(0);
NRF_SPI_Transfer(NRF_CMD_R_REGISTER | reg);
for (uint8_t i = 0; i < len; i++)
buf[i] = NRF_SPI_Transfer(0xFF);
NRF_SPI_CS(1);
}
void NRF24L01_WriteBuf(uint8_t reg, const uint8_t *buf, uint8_t len) {
NRF_SPI_CS(0);
NRF_SPI_Transfer(NRF_CMD_W_REGISTER | reg);
for (uint8_t i = 0; i < len; i++)
NRF_SPI_Transfer(buf[i]);
NRF_SPI_CS(1);
}
/* ---- 初始化 ---- */
void NRF24L01_Init(void) {
NRF_CE_L();
NRF_CSN_H();
/* 上电延时 */
HAL_Delay(100);
/* 配置寄存器 */
NRF24L01_WriteReg(NRF_CONFIG, 0x0E); /* EN_CRC, CRC0, PWR_UP, PTX */
NRF24L01_WriteReg(NRF_EN_AA, 0x01); /* pipe0 auto ACK */
NRF24L01_WriteReg(NRF_EN_RXADDR, 0x01); /* pipe0 enable */
NRF24L01_WriteReg(NRF_SETUP_AW, 0x03); /* 5 bytes address */
NRF24L01_WriteReg(NRF_SETUP_RETR, 0x1A); /* 500us + 15 retries */
NRF24L01_WriteReg(NRF_RF_CH, nrf_channel);
NRF24L01_WriteReg(NRF_RF_SETUP, NRF_RATE_1M | NRF_PA_MAX);
NRF24L01_WriteReg(NRF_RX_PW_P0, 32); /* payload = 32 bytes */
NRF24L01_WriteReg(NRF_FIFO_STATUS, 0x11); /* clear FIFO */
/* 设置地址 */
NRF24L01_SetTXAddr(nrf_tx_addr);
NRF24L01_SetRXAddr(0, nrf_tx_addr);
/* 清空 FIFO */
NRF_SPI_CS(0);
NRF_SPI_Transfer(NRF_CMD_FLUSH_TX);
NRF_SPI_CS(1);
NRF_SPI_CS(0);
NRF_SPI_Transfer(NRF_CMD_FLUSH_RX);
NRF_SPI_CS(1);
/* 清除状态 */
NRF24L01_WriteReg(NRF_STATUS, NRF_STATUS_RX_DR | NRF_STATUS_TX_DS | NRF_STATUS_MAX_RT);
NRF_CE_L();
}
uint8_t NRF24L01_Check(void) {
uint8_t buf[5] = {0xA5, 0xA5, 0xA5, 0xA5, 0xA5};
uint8_t rx[5];
NRF24L01_WriteBuf(NRF_TX_ADDR, buf, 5);
NRF24L01_ReadBuf(NRF_TX_ADDR, rx, 5);
for (uint8_t i = 0; i < 5; i++)
if (rx[i] != 0xA5) return 0;
return 1;
}
/* ---- 配置 ---- */
void NRF24L01_SetChannel(uint8_t ch) {
if (ch > NRF_MAX_CHANNEL) ch = NRF_MAX_CHANNEL;
nrf_channel = ch;
NRF24L01_WriteReg(NRF_RF_CH, ch);
}
void NRF24L01_SetRate(uint8_t rate) {
uint8_t rf = NRF24L01_ReadReg(NRF_RF_SETUP);
rf &= ~0x28;
rf |= (rate & 0x28);
NRF24L01_WriteReg(NRF_RF_SETUP, rf);
}
void NRF24L01_SetPower(uint8_t power) {
uint8_t rf = NRF24L01_ReadReg(NRF_RF_SETUP);
rf &= ~0x06;
rf |= (power & 0x06);
NRF24L01_WriteReg(NRF_RF_SETUP, rf);
}
void NRF24L01_SetTXAddr(const uint8_t *addr) {
memcpy(nrf_tx_addr, addr, NRF_ADDR_WIDTH);
NRF24L01_WriteBuf(NRF_TX_ADDR, addr, NRF_ADDR_WIDTH);
}
void NRF24L01_SetRXAddr(uint8_t pipe, const uint8_t *addr) {
if (pipe > 5) return;
if (pipe < 2) {
NRF24L01_WriteBuf(NRF_RX_ADDR_P0 + pipe, addr, NRF_ADDR_WIDTH);
} else {
NRF24L01_WriteReg(NRF_RX_ADDR_P0 + pipe, addr[0]);
}
}
/* ---- 模式切换 ---- */
void NRF24L01_TXMode(void) {
NRF_CE_L();
uint8_t cfg = NRF24L01_ReadReg(NRF_CONFIG);
cfg &= ~0x01; /* PRIM_RX = 0 -> TX */
NRF24L01_WriteReg(NRF_CONFIG, cfg);
NRF_CE_H();
}
void NRF24L01_RXMode(void) {
NRF_CE_L();
uint8_t cfg = NRF24L01_ReadReg(NRF_CONFIG);
cfg |= 0x01; /* PRIM_RX = 1 -> RX */
NRF24L01_WriteReg(NRF_CONFIG, cfg);
NRF_CE_H();
}
/* ---- 发送/接收 ---- */
uint8_t NRF24L01_TxPacket(const uint8_t *data, uint8_t len) {
uint8_t status;
NRF_CE_L();
/* 清 TX FIFO */
NRF_SPI_CS(0);
NRF_SPI_Transfer(NRF_CMD_FLUSH_TX);
NRF_SPI_CS(1);
/* 写 payload */
NRF_SPI_CS(0);
NRF_SPI_Transfer(NRF_CMD_W_TX_PAYLOAD);
for (uint8_t i = 0; i < len && i < 32; i++)
NRF_SPI_Transfer(data[i]);
NRF_SPI_CS(1);
/* 发射 */
NRF_CE_H();
HAL_Delay(1);
NRF_CE_L();
/* 等待完成 */
uint32_t timeout = 10000;
while (timeout--) {
status = NRF24L01_ReadReg(NRF_STATUS);
if (status & (NRF_STATUS_TX_DS | NRF_STATUS_MAX_RT)) break;
}
/* 清除状态 */
NRF24L01_WriteReg(NRF_STATUS, NRF_STATUS_TX_DS | NRF_STATUS_MAX_RT);
if (status & NRF_STATUS_TX_DS) {
nrf_connected = 1;
return 1; /* 发送成功 */
}
nrf_connected = 0;
return 0; /* 发送失败 */
}
uint8_t NRF24L01_RxPacket(uint8_t *data) {
uint8_t status = NRF24L01_ReadReg(NRF_STATUS);
if (!(status & NRF_STATUS_RX_DR)) return 0;
/* 读 payload */
NRF_SPI_CS(0);
NRF_SPI_Transfer(NRF_CMD_R_RX_PAYLOAD);
for (uint8_t i = 0; i < 32; i++)
data[i] = NRF_SPI_Transfer(0xFF);
NRF_SPI_CS(1);
/* 清除 RX_DR */
NRF24L01_WriteReg(NRF_STATUS, NRF_STATUS_RX_DR);
return 1;
}
uint8_t NRF24L01_IsDataReady(void) {
uint8_t status = NRF24L01_ReadReg(NRF_STATUS);
return (status & NRF_STATUS_RX_DR) ? 1 : 0;
}
/* ---- 对频 ---- */
void NRF24L01_BindMode(void) {
/* 进入接收模式,监听对频请求 */
NRF_CE_L();
NRF24L01_WriteReg(NRF_CONFIG, 0x0F); /* PRX, PWR_UP, CRC */
NRF24L01_WriteReg(NRF_EN_RXADDR, 0x01);
NRF24L01_WriteReg(NRF_RX_PW_P0, 32);
NRF24L01_WriteBuf(NRF_RX_ADDR_P0, nrf_tx_addr, NRF_ADDR_WIDTH);
NRF24L01_WriteReg(NRF_STATUS, 0x70);
NRF_CE_H();
}
uint8_t NRF24L01_BindScan(uint8_t *found_addr) {
/* 扫描所有通道寻找对频设备 */
for (uint8_t ch = 0; ch <= NRF_MAX_CHANNEL; ch++) {
NRF24L01_SetChannel(ch);
HAL_Delay(2);
if (NRF24L01_RxPacket(found_addr)) {
/* 验证对频短语 */
if (memcmp(found_addr, nrf_bind_phrase, strlen((char*)nrf_bind_phrase)) == 0) {
/* 对频成功,记录地址 */
memcpy(nrf_tx_addr, found_addr + 6, NRF_ADDR_WIDTH);
nrf_connected = 1;
return 1;
}
}
}
return 0;
}