?? nrf24l01.c
字號:
#define NRF_GLOBALS
#include "..\App\includes.h"
#include "NRF24L01.h"
#include "demo.h"
/***************************************************/
//#define uchar unsigned char
//#define TX_ADR_WIDTH 5 // 5 bytes TX(RX) address width
//#define TX_PLOAD_WIDTH 20 // 20 bytes TX payload
//uchar TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01}; // Define a static TX address
//uchar rx_buf[TX_PLOAD_WIDTH];
//uchar tx_buf[TX_PLOAD_WIDTH]={"1234567890abcdefghij"};
//uchar flag;
//uchar rx_com_buffer[10];
//uchar tx_com_buffer[10];
GPIO_InitTypeDef GPIO_InitStructure;
/**************************************************/
void SPI_CS(uchar a){
if(a==1) GPIO_SetBits(GPIOB, GPIO_Pin_12); /*開*/
else GPIO_ResetBits(GPIOB, GPIO_Pin_12); /*關*/
}
void SPI_DOUT(uchar a){
if(a==1) GPIO_SetBits(GPIOB, GPIO_Pin_15); /*開*/
else GPIO_ResetBits(GPIOB, GPIO_Pin_15); /*關*/
}
void SPI_CLK(uchar a){
if(a==1) GPIO_SetBits(GPIOB, GPIO_Pin_13); /*開*/
else GPIO_ResetBits(GPIOB, GPIO_Pin_13); /*關*/
}
void MODE_CE(uchar a){ /*NRF24L01 模式控制引腳CE*/
if(a==1) GPIO_SetBits(GPIOC, GPIO_Pin_6); /*開*/
else GPIO_ResetBits(GPIOC, GPIO_Pin_6); /*關*/
}
void SPI2_NRF24L01_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* 使能SPI2,GPIOB時鐘 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2 ,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/* 配置SPI2接口: SCK=PB13,MISO=PB14,MOSI=PB15 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;/*復用推挽輸出*/
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* 配置PB12推挽輸出模式, 有于片選 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;/*推挽輸出*/
GPIO_Init(GPIOB, &GPIO_InitStructure);
/*配置NRF24L01模式引腳CE=PC6 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;/*推挽輸出*/
GPIO_Init(GPIOC, &GPIO_InitStructure);
/*配置NRF24L01 中斷控制引腳IRQ=PB8 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;/*輸入下拉*/
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB, GPIO_Pin_8); /*開*/
NotSelect_SDR();
/* SPI2接口參數配置 */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);
/* 使能SPI2接口 */
SPI_Cmd(SPI2, ENABLE);
}
uchar SPI2_NRF_SendByte(u8 byte)
{
/* 當DR寄存器不為空時循環 */
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
//NotSelect_Flash(); while(1);
/* 通過SPI2外設發送數據 */
SPI_I2S_SendData(SPI2, byte);
/* 等待接收數據 */
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
/* 返回從SPI總線讀取的數據 */
return SPI_I2S_ReceiveData(SPI2);
}
uchar SPI_RW_Reg(unsigned char data1,unsigned char data2)
{
unsigned int Data = 0,a;
Select_SDR();
Data=SPI2_NRF_SendByte(data1);
SPI2_NRF_SendByte(data2);
NotSelect_SDR();
return(Data);
}
uchar SPI_Write_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
uchar status,byte_ctr;
Select_SDR(); /* CSN置低, 初始化SPI傳輸*/
status=SPI2_NRF_SendByte(reg);
for(byte_ctr=0; byte_ctr<bytes; byte_ctr++) /* 將所有字節寫入緩沖*/
{
/*發送字節*/
SPI2_NRF_SendByte(*pBuf++);
//SPI_I2S_SendData(SPI2,*pBuf++);
}
NotSelect_SDR(); /*CSN置高 */
return(status); /* 返回nRF24L01 狀態*/
}
/*SPI讀*/
unsigned char SPI_Read(BYTE reg)
{
unsigned char Data;
Select_SDR();
SPI2_NRF_SendByte(reg);
Data=SPI2_NRF_SendByte(0);
NotSelect_SDR();
return (Data);
}
u8 SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
uchar status,i;
Select_SDR(); /*CSN置低*/
status=SPI2_NRF_SendByte(reg);
for(i=0; i<bytes; i++) /* 數據寫入緩存 */
{
/* 發送字節*/
pBuf[i]=SPI2_NRF_SendByte(0);
//SPI_I2S_SendData(SPI2,*pBuf++);
}
NotSelect_SDR(); /*CSN置高*/
return(status); /*返回NRF24L01狀態*/
}
void SPI_SDR_SendByte1(unsigned int spi_add,unsigned int spi_data)
{
unsigned char bitcnt,a;
SPI_CS(0);
for(bitcnt=0;bitcnt<16;bitcnt++)
{
if(((spi_add<<bitcnt)&0x8000)>0) SPI_DOUT(1);
else SPI_DOUT(0);
SPI_CLK(0);
SPI_CLK(1);
}
for(bitcnt=0;bitcnt<16;bitcnt++)
{
if(((spi_data<<bitcnt)&0x8000)>0) SPI_DOUT(1);
else SPI_DOUT(0);
SPI_CLK(0);
SPI_CLK(1);
}
SPI_CLK(0);
SPI_CS(1);
}
unsigned int SPI_SDR_ReadByte1(unsigned int spi_add)
{
unsigned int i=0;
unsigned int temp8=0;
SPI_CS(0);
for(i=0;i<16;i++)
{
if(((spi_add<<i)&0x8000)>1)
SPI_DOUT(1);
else
SPI_DOUT(0);
SPI_CLK(0);
SPI_CLK(1);
}
//pPio1->PIO_CODR = SPI_CLK;
for(i=0;i<16;i++)
{
SPI_CLK(1);
SPI_CLK(0);
temp8=temp8<<1;
//if( (pPio1->PIO_PDSR & SPI_IN ) == SPI_IN ) temp8=temp8+1;
}
SPI_CLK(1);
SPI_CLK(0);
//P_CPLD1->spi_fs=0x01;
SPI_CS(1);
return(temp8);
}
/**************************************************
Function: init_io();
Description:
flash led one time,chip enable(ready to TX or RX Mode),
Spi disable,Spi clock line init high
/**************************************************/
void init_io(void)
{
SPI_CS(1); /*片選置1*/
MODE_CE(0); /*CE置0*/
//SPI_CLK(0); // Spi clock line init high
}
/**************************************************/
/*延時函數*/
void delay_ms(unsigned int x)
{
unsigned int i,j;
i=0;
for(i=0;i<x;i++)
{
j=108;
while(j--);
}
}
/**************************************************/
/**************************************************
Function: SPI_RW();
Description:
Writes one byte to nRF24L01, and return the byte read
from nRF24L01 during write, according to SPI protocol
/**************************************************/
/*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
} */
/**************************************************/
/**************************************************
Function: SPI_RW_Reg();
Description:
Writes value 'value' to register 'reg'
/**************************************************/
/**************************************************/
/**************************************************/
/**************************************************
Function: SPI_Read_Buf();
Description:
Reads 'bytes' #of bytes from register 'reg'
Typically used to read RX payload, Rx/Tx address
/**************************************************/
/*uchar SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE 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<bytes;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
} */
/**************************************************/
/**********************************************************************
*函數名: RX_Mode()
*功能描述:初始化NRF24L01到接收模式,設置接收地址,寫有效接收數據寬度
*選擇射頻通道,速率及低噪聲放大器增益,初始化,后CE置高,NRF24L01
*接收數據包準備就緒.
**********************************************************************/
void RX_Mode(void)
{ it_msg=0;
init_io();
/*TX地址*/
TX_ADDRESS[0]=0x34;
TX_ADDRESS[1]=0x43;
TX_ADDRESS[2]=0x10;
TX_ADDRESS[3]=0x10;
TX_ADDRESS[4]=0x01;
MODE_CE(0);
/*收發使用相同的地址*/
SPI_Write_Buf(WRITE_REG1 + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
/*使能自動應答通道0*/
SPI_RW_Reg(WRITE_REG1 + EN_AA, 0x01);
SPI_RW_Reg(WRITE_REG1 + EN_RXADDR, 0x01);
/*選擇射頻通道40*/
SPI_RW_Reg(WRITE_REG1 + RF_CH, 40);
/*接收/發送有效負載數據長度相等*/
SPI_RW_Reg(WRITE_REG1 + RX_PW_P0, TX_PLOAD_WIDTH);
/*發射功率:0dBm, 數據速率:2Mbps, 低噪聲放大增益:HCURR */
if(nrf_baud==0) SPI_RW_Reg(WRITE_REG1 + RF_SETUP, 0x0f);
else SPI_RW_Reg(WRITE_REG1 + RF_SETUP, 0x07);
/*設置PWR_UP位, 使能CRC(2 bytes)校驗,PRIM_RX位,RX_DR位*/
SPI_RW_Reg(WRITE_REG1 + CONFIG, 0x0f);
MODE_CE(1);/*CE置1,使能接收模式*/
// 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.
}
/**********************************************************************
*函數名: TX_Mode()
*功能描述:初始化NRF24L01到發送模式,設置發送地址,設置接收自動應答功能
*選擇射頻通道,速率及發射功率,使能PWR_UP,PRIM_TX,CRC校驗=2字節初始化,
*CE置高并維持10us,NRF24L01準備發送數據包并接收應答信號.
**********************************************************************/
void TX_Mode(void)
{
/*模式引腳CE=0*/
MODE_CE(0);
/*寫發送地址TX_ADDR到nRF24L01*/
SPI_Write_Buf(WRITE_REG1 + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);
/*使能自動應答功能時發送/接收地址須相等*/
SPI_Write_Buf(WRITE_REG1 + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
//SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // Writes data to TX payload
/*使能通道0自動應答*/
SPI_RW_Reg(WRITE_REG1 + EN_AA, 0x01);
/*使能通道0*/
SPI_RW_Reg(WRITE_REG1 + EN_RXADDR, 0x01);
/*500us + 86us, 10次重發*/
SPI_RW_Reg(WRITE_REG1 + SETUP_RETR, 0x1a);
/*選擇射頻通道40*/
SPI_RW_Reg(WRITE_REG1 + RF_CH, 40);
/*設置發射功率:0dBm, 數據速率:2Mbps, 低噪聲放大增益:HCURR*/
if(nrf_baud==0) SPI_RW_Reg(WRITE_REG1 + RF_SETUP, 0x0f);
else SPI_RW_Reg(WRITE_REG1 + RF_SETUP, 0x07);
/* 設置PWR_UP位,使能CRC校驗=2字節,PRIM_TX,MAX_RT,TX_DS寄存器位使能*/
SPI_RW_Reg(WRITE_REG1 + CONFIG, 0x0e);
//SPI_RW_Reg(WRITE_REG1+ CONFIG, 0x02);//0x0E);
MODE_CE(1);
}
void NRF24L01_TX(unsigned char * tx_buf)
{
MODE_CE(0);
/*自動應答時收發地址相等*/
SPI_Write_Buf(WRITE_REG1 + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
/*寫數據到TX_PLD*/
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH);
MODE_CE(1);
}
/**********************************************************************
*函數名: NRF24L01_TXBUF()
*功能描述:發送數據緩沖內容="1234567890abcdefghij ,
*配置發送地址,I/O配置等
**********************************************************************/
void NRF24L01_TXBUF(void)
{
uchar a,i=0;
TX_ADDRESS[0]=0x34;
TX_ADDRESS[1]=0x43;
TX_ADDRESS[2]=0x10;
TX_ADDRESS[3]=0x10;
TX_ADDRESS[4]=0x01;
//TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01};
init_io();
//LED1=1;
it_msg=0;
SPI_RW_Reg(WRITE_REG1+STATUS,0xff);
SPI_RW_Reg(0xe1,0);
SPI_RW_Reg(0xe2,0);
TX_Mode(); /* 發送模式* /
delay_ms(100);
NRF24L01_TX(tx_buf);
while(i==0)
{
if(it_msg!=0){
it_msg=0;
a=SPI_Read(READ_REG1+STATUS);
/*發送達到最大重發次數*/
if((a&0x10)>0){
/*清除發送緩沖區*/
SPI_RW_Reg(0xe1,0);
/*清除07寄存器中斷標志*/
SPI_RW_Reg(WRITE_REG1+STATUS,0xff);
//if(led_flash==1) GPIO_SetBits(GPIOB, GPIO_Pin_5);
//else Led_OFF();
memcpy(status_buf, "Object NO ACK! ", 20);
i=1;
}
else if((a&0x20)>0){/*發射后收到應答*/
/*清除發送緩沖區*/
SPI_RW_Reg(0xe1,0);
/*清除07寄存器中斷標志*/
SPI_RW_Reg(WRITE_REG1+STATUS,0xff);
//if(led_flash==1) GPIO_SetBits(GPIOB, GPIO_Pin_5);
//else Led_OFF();
memcpy(status_buf, "Send OK! ", 20);
i=1;
}
}
u8 NRF24L01_RxPacket()
{u8 flag=0;
u8 status;
if(it_msg!=0){
it_msg=0;
/*讀取狀態寄存其來判斷數據接收狀況*/
status=SPI_Read(READ_REG1+STATUS);
if(status & 0x40) /*判斷是否接收到數據*/
{
/*從接收緩沖區讀有效數據*/
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);
flag =1; /*讀取數據完成標志*/
//if(led_flash==1){ Led_ON(); }
//else if(led_flash==0){ Led_OFF();}
memcpy(status_buf, "Recive OK! ", 20);
/*接收到數據后RX_DR,TX_DS,MAX_RT都置高為1,通過寫1來清楚中斷標志*/
SPI_RW_Reg(WRITE_REG1+STATUS, status);
}
}
return flag;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -