?? nrf24l01
字號:
#ifndef __NRF24L01_H__
#define __NRF24L01_H__
#define uchar unsigned char
#define uint unsigned int
sbit CE = P0^5; // Chip Enable pin signal (output)
sbit CSN = P0^4; // Slave Select pin, (output to CSN, nRF24L01)
sbit IRQ = P0^0; // Interrupt signal, from nRF24L01 (input)
sbit MISO = P0^1; // Master In, Slave Out pin (input)
sbit MOSI = P0^2; // Serial Clock pin, (output)
sbit SCK = P0^3; // Master Out, Slave In pin (output)
uchar TxBuf[20]={"1234567890abcdefghij"};
#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
uchar TX_ADDRESS[TX_ADR_WIDTH]= {0xE7,0xE7,0xE7,0xE7,0xE7}; //本地地址
uchar RX_ADDRESS[RX_ADR_WIDTH]= {0xE7,0xE7,0xE7,0xE7,0xE7}; //接收地址
///***************************************NRF24L01寄存器指令*******************************************************
#define READ_REG 0x00 // 讀寄存器指令
#define WRITE_REG 0x20 // 寫寄存器指令
#define RD_RX_PLOAD 0x61 // 讀取接收數據指令
#define WR_TX_PLOAD 0xA0 // 寫待發(fā)數據指令
#define FLUSH_TX 0xE1 // 沖洗發(fā)送 FIFO指令
#define FLUSH_RX 0xE2 // 沖洗接收 FIFO指令
#define REUSE_TX_PL 0xE3 // 定義重復裝載數據指令
#define NOP 0xFF // 保留
///*************************************SPI(nRF24L01)寄存器地址****************************************************
#define CONFIG 0x00 // 配置收發(fā)狀態(tài),CRC校驗模式以及收發(fā)狀態(tài)響應方式
#define EN_AA 0x01 // 自動應答功能設置
#define EN_RXADDR 0x02 // 可用信道設置
#define SETUP_AW 0x03 // 收發(fā)地址寬度設置
#define SETUP_RETR 0x04 // 自動重發(fā)功能設置
#define RF_CH 0x05 // 工作頻率設置
#define RF_SETUP 0x06 // 發(fā)射速率、功耗功能設置
#define NRFRegSTATUS 0x07 // 狀態(tài)寄存器
#define OBSERVE_TX 0x08 // 發(fā)送監(jiān)測功能
#define CD 0x09 // 地址檢測
#define RX_ADDR_P0 0x0A // 頻道0接收數據地址
#define RX_ADDR_P1 0x0B // 頻道1接收數據地址
#define RX_ADDR_P2 0x0C // 頻道2接收數據地址
#define RX_ADDR_P3 0x0D // 頻道3接收數據地址
#define RX_ADDR_P4 0x0E // 頻道4接收數據地址
#define RX_ADDR_P5 0x0F // 頻道5接收數據地址
#define TX_ADDR 0x10 // 發(fā)送地址寄存器
#define RX_PW_P0 0x11 // 接收頻道0接收數據長度
#define RX_PW_P1 0x12 // 接收頻道1接收數據長度
#define RX_PW_P2 0x13 // 接收頻道2接收數據長度
#define RX_PW_P3 0x14 // 接收頻道3接收數據長度
#define RX_PW_P4 0x15 // 接收頻道4接收數據長度
#define RX_PW_P5 0x16 // 接收頻道5接收數據長度
#define FIFO_STATUS 0x17 // FIFO棧入棧出狀態(tài)寄存器設置
///*****************************子函數集*********************************************************
uchar NRF24SPI_Send_Byte(uchar dat);
uchar SPI_WR_Reg(uchar reg, uchar value);
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar Len);
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar Len);
uchar nRF24L01_RxPacket(unsigned char* rx_buf);
void nRF24L01_TxPacket(unsigned char * tx_buf);
uchar SPI_RD_Reg(uchar reg);
void init_NRF24L01(void);
void TX_Mode(void);
void RX_Mode(void);
void NRF_Send(void);
uchar NRF24L01_Check(void);
///*************************************************************************************
uchar NRF24SPI_Send_Byte(uchar dat)
{
uchar i;
for (i = 0; i < 8; i++) // output 8-bit
{
//發(fā)送1位數據
if (dat & 0x80) // output 'uchar', MSB to MOSI
{
MOSI = 1;
}
else
{
MOSI = 0;
}
dat <<= 1; // shift next bit into MSB..
//讀取1位數據
SCK = 1; // Set SCK high..
if (MISO)
{
dat |= 1;
} // capture current MISO bit
else
{
dat &= 0xFE;
}
SCK = 0; // ..then set SCK low again
}
return(dat); // return read uchar
}
void Delay_n10us(uint n) //延時n個10us
{
for(;n>0;n--)
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=2;a>0;a--);
}
}
///****************************************************************************************
///*NRF24L01檢測是否存在
///***************************************************************************************/
uchar NRF24L01_Check(void)
{
uchar bu[5]={0XA5,0XA5,0XA5,0XA5,0XA5};
uchar bu1[5];
uchar i;
SPI_Write_Buf(WRITE_REG+TX_ADDR,bu,5);//寫入5個字節(jié)的地址.
SPI_Read_Buf(TX_ADDR,bu1,5); //讀出寫入的地址
for(i=0;i<5;i++)if(bu1[i]!=0XA5)break;
if(i!=5)return 1; //NRF24L01不在位
return 0; //NRF24L01在位
}
///****************************************************************************************
///*NRF24L01初始化
///***************************************************************************************/
void init_NRF24L01(void)
{
uchar buf[5]={0};
Delay_n10us(10);
CE = 0; // chip enable
CSN= 0; // Spi disable
SPI_Read_Buf(TX_ADDR, buf, TX_ADR_WIDTH);//debug 測試原來的本地地址:復位值是:0xE7 0xE7 0xE7 0xE7 0xE7
// SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 寫本地地址
// SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 寫接收端地址
//
// SPI_WR_Reg(WRITE_REG + EN_AA, 0x01); // 頻道0自動 ACK應答允許
// SPI_WR_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允許接收地址只有頻道0,如果需要多頻道可以參考Page21
// SPI_WR_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 設置自動重發(fā)時間和次數:500us + 86us, 10 retrans...
// SPI_WR_Reg(WRITE_REG + RF_CH, 22); // 設置信道工作為2.4GHZ,收發(fā)必須一致
// SPI_WR_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //設置接收數據長度,本次設置為32字節(jié)
// SPI_WR_Reg(WRITE_REG + RF_SETUP, 0x07); //設置發(fā)射速率為1MHZ,發(fā)射功率為最大值0dB
//
// SPI_RD_Reg(WRITE_REG + EN_AA);
// SPI_RD_Reg(WRITE_REG + EN_RXADDR);
// SPI_RD_Reg(WRITE_REG + RF_CH);
// SPI_RD_Reg(WRITE_REG + RX_PW_P0);
// SPI_RD_Reg(WRITE_REG + RF_SETUP);
}
///****************************************************************************************************
///*函數:uchar SPI_Read(uchar reg)
///*功能:NRF24L01的SPI時序
///****************************************************************************************************/
uchar SPI_RD_Reg(uchar reg)
{
uchar reg_val;
CSN = 0; // CSN low, initialize SPI communication...
NRF24SPI_Send_Byte(reg); // Select register to read from..
reg_val = NRF24SPI_Send_Byte(0); // ..then read registervalue
CSN = 1; // CSN high, terminate SPI communication
return(reg_val); // return register value
}
//****************************************************************************************************/
//*功能:NRF24L01讀寫寄存器函數
//****************************************************************************************************/
uchar SPI_WR_Reg(uchar reg, uchar value)
{
uchar status;
CSN = 0; // CSN low, init SPI transaction
status = NRF24SPI_Send_Byte(reg);// select register
NRF24SPI_Send_Byte(value); // ..and write value to it..
CSN = 1; // CSN high again
return(status); // return nRF24L01 status uchar
}
///****************************************************************************************************/
//*函數:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar Len)
//*功能: 用于讀數據,reg:為寄存器地址,pBuf:為待讀出數據地址,uchars:讀出數據的個數
//****************************************************************************************************/
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar Len)
{
uint status,i;
CSN = 0; // Set CSN low, init SPI tranaction
status = NRF24SPI_Send_Byte(reg); // Select register to write to and read status uchar
for(i=0;i<Len;i++)
{
pBuf[i] = NRF24SPI_Send_Byte(0);
}
CSN = 1;
return(status); // return nRF24L01 status uchar
}
//*********************************************************************************************************
//*函數:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar Len)
//*功能: 用于寫數據:為寄存器地址,pBuf:為待寫入數據地址,uchars:寫入數據的個數
//*********************************************************************************************************/
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar Len)
{
uint status,i;
CSN = 0; //SPI使能
status = NRF24SPI_Send_Byte(reg);
for(i=0; i<Len; i++) //
{
NRF24SPI_Send_Byte(*pBuf);
pBuf ++;
}
CSN = 1; //關閉SPI
return(status); //
}
//****************************************************************************************************/
//*函數:void SetRX_Mode(void)
//*功能:數據接收配置
//****************************************************************************************************/
void RX_Mode(void)
{
uchar buf[5]={0};
CE = 0;
SPI_Read_Buf(TX_ADDR, buf, TX_ADR_WIDTH);//debug 測試原來的本地地址:復位值是:0xE7 0xE7 0xE7 0xE7 0xE7
//SPI_WR_Reg(WRITE_REG + CONFIG, 0x03);//SPI_WR_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收發(fā)完成中斷響應,16位CRC ,主接收
//SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 寫本地地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 寫接收端地址
SPI_WR_Reg(WRITE_REG + EN_AA, 0);//0x01); // 頻道0自動 ACK應答允許
SPI_WR_Reg(WRITE_REG + EN_RXADDR,0x01); // 允許接收地址只有頻道0,如果需要多頻道可以參考Page21
SPI_WR_Reg(WRITE_REG + SETUP_RETR,0x1a); // 設置自動重發(fā)時間和次數:500us + 86us, 10 retrans...
SPI_WR_Reg(WRITE_REG + RF_CH, 40); // 設置信道工作為2.4GHZ,收發(fā)必須一致
SPI_WR_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //設置接收數據長度,本次設置為32字節(jié)
SPI_WR_Reg(WRITE_REG + RF_SETUP, 0x0F); //設置發(fā)射速率為2MHZ,發(fā)射功率為最大值0dB
SPI_WR_Reg(WRITE_REG + CONFIG, 0x0F);//0x0F);
CE = 1;
Delay_n10us(20); //200us
}
//******************************************************************************************************/
//*函數:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
//*功能:數據讀取后放如rx_buf接收緩沖區(qū)中
//******************************************************************************************************/
uchar nRF24L01_RxPacket(unsigned char* rx_buf)
{
uchar flag=0;
uchar status;
status=SPI_RD_Reg(NRFRegSTATUS); // 讀取狀態(tài)寄存其來判斷數據接收狀況
if(status & 0x40) // 判斷是否接收到數據
{
//CE = 0; //SPI使能
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
flag =1; //讀取數據完成標志
}
SPI_WR_Reg(WRITE_REG+NRFRegSTATUS, status); //接收到數據后RX_DR,TX_DS,MAX_RT都置高為1,通過寫1來清楚中斷標志
return flag;
}
void TX_Mode(void)
{
CE = 0;
//SPI_WR_Reg(WRITE_REG + CONFIG, 0x02); //0x0E // IRQ收發(fā)完成中斷響應,16位CRC,主發(fā)送
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 寫本地地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 寫接收端地址
SPI_WR_Reg(WRITE_REG + EN_AA, 0);//0x01); // 頻道0自動 ACK應答允許
SPI_WR_Reg(WRITE_REG + EN_RXADDR,0);// 0x01); // 允許接收地址只有頻道0,如果需要多頻道可以參考Page21
SPI_WR_Reg(WRITE_REG + SETUP_RETR, 0);//0x1a); // 設置自動重發(fā)時間和次數:500us + 86us, 10 retrans...
SPI_WR_Reg(WRITE_REG + RF_CH, 40); // 設置信道工作為2.4GHZ,收發(fā)必須一致
// SPI_WR_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //設置接收數據長度,本次設置為32字節(jié)
SPI_WR_Reg(WRITE_REG + RF_SETUP, 0x0F); //設置發(fā)射速率為2MHZ,發(fā)射功率為最大值0dB
// SPI_WR_Reg(WRITE_REG + CONFIG, 0x0E);
CE = 1;
}
//***********************************************************************************************************
//*函數:void nRF24L01_TxPacket(unsigned char * tx_buf)
//*功能:發(fā)送 tx_buf中數據
//**********************************************************************************************************/
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
CE = 0; //StandBy I模式
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 裝載接收端地址
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 裝載數據
SPI_WR_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收發(fā)完成中斷響應,16位CRC,主發(fā)送
CE = 1; //置高CE,激發(fā)數據發(fā)送
}
///************************************主函數************************************************************
void NRF_Send(void)
{
//static uint counter=0;
static uchar flag=0;
//TX_Mode();
//IntervalTimems(100);
if(flag==0)
{
flag=1;
//memcpy(TxBuf, "1234567890abcdefghij", 20);
nRF24L01_TxPacket(TxBuf);
}
else
{
flag=0;
//memcpy(TxBuf, "abcdefghij1234567890", 20);
nRF24L01_TxPacket(TxBuf);
}
}
#endif /*__NRF24L01_H__ */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -