#include "NRF24L01.h"
/*测试代码
传统函数调用:
if(NRF24L01_RxPacket(Rx_BUF) == 0)
if(NRF24L01_TxPacket(Tx_BUF) == TX_OK)
while(1)
{
NRF24L01_CE_L(); NRF24L01_CSN_L();
delay_ms(1000);
NRF24L01_CE_H(); NRF24L01_CSN_H3e();
delay_ms(1000);
} */
u8 TX_ADDRESS[TX_ADR_WIDTH]= {0xAA,0xBB,0xCC,0xDD,0xEE}; //{0xE1,0xE2,0xE3,0xE4,0xE5}; //本地地址
u8 RX_ADDRESS[RX_ADR_WIDTH]= {0xAA,0xBB,0xCC,0xDD,0xEE}; //{0xE1,0xE2,0xE3,0xE4,0xE5}; //接收地址
//初始化24L01的IO口
void NRF24L01_Init(void)
{
NRF24L01_CE_L(); //初始化相关引脚的初始电平
NRF24L01_CSN_H();
SPI3_Init();
//EXTI_NRF_Init();//接收中断配置 (IRQ -- PD4)
}
//参考资料:STM32不完全手册_库函数版本_V3.1.pdf pdf -- 175
void EXTI_NRF_Init(void)
{
EXTI_InitTypeDef EXTI_InitStructure; //配置NRF接收中断
EXTI_ClearITPendingBit(EXTI_Line4); //配置外部中断线4连接到PD4
GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource4); //端口与中断线映射
EXTI_InitStructure.EXTI_Line = EXTI_Line4;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
//检测24L01是否存在
u8 NRF24L01_Check(void)
{
u8 i,buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};
//SPI3_SetSpeed(SPI_BaudRatePrescaler_8); //spi 速度为 9Mhz !!!!!
NRF24L01_Write_Buf(WRITE_REG_NRF+TX_ADDR,buf,5);//写入5个字节的地址.
NRF24L01_Read_Buf(TX_ADDR,buf,5); //读出写入的地址
for(i=0;i<5;i++)if(buf[i]!=0XA5)break;
if(i!=5)return 0;//检测24L01错误
return 1; //检测到24L01
}
//SPI写寄存器
u8 NRF24L01_Write_Reg(uint8_t reg,uint8_t value)
{
u8 status;
NRF24L01_CSN_L(); //使能SPI传输
status =SPI3_ReadWriteByte(reg);//发送寄存器号
SPI3_ReadWriteByte(value); //写入寄存器的值
NRF24L01_CSN_H(); //禁止SPI传输
return(status); //返回状态值
}
//读取SPI寄存器值
u8 NRF24L01_Read_Reg(u8 reg)
{
u8 reg_val;
NRF24L01_CSN_L();; //使能SPI传输
SPI3_ReadWriteByte(reg); //发送寄存器号
reg_val=SPI3_ReadWriteByte(0XFF);//读取寄存器内容
NRF24L01_CSN_H();; //禁止SPI传输
return(reg_val); //返回状态值
}
//在指定位置读出指定长度的数据
u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len)
{
u8 status,u8_ctr;
NRF24L01_CSN_L(); //使能SPI传输
status=SPI3_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值
for(u8_ctr=0;u8_ctr<len;u8_ctr++)pBuf[u8_ctr]=SPI3_ReadWriteByte(0XFF);//读出数据
NRF24L01_CSN_H(); //关闭SPI传输
return status; //返回读到的状态值
}
//在指定位置写指定长度的数据
u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len)
{
u8 status,u8_ctr;
NRF24L01_CSN_L(); //使能SPI传输
status = SPI3_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值
for(u8_ctr=0; u8_ctr<len; u8_ctr++)SPI3_ReadWriteByte(*pBuf++); //写入数据
NRF24L01_CSN_H(); //关闭SPI传输
return status; //返回读到的状态值
}
//启动NRF24L01发送一次数据
u8 NRF24L01_TxPacket(u8 *txbuf)
{
SPI3_SetSpeed(SPI_BaudRatePrescaler_16);//spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)
NRF24L01_CE_L(); //StandBy I模式
NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF 32个字节
NRF24L01_CE_H(); //置高CE,激发数据发送
#if Single_Com == 1
u8 sta;
while(NRF24L01_IRQ!=0);//等待发送完成
sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值;
NRF24L01_Write_Reg(WRITE_REG_NRF+STATUS,sta); //清除TX_DS或MAX_RT中断标志
if(sta&MAX_TX)//达到最大重发次数
{
NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器
return MAX_TX;
}
if(sta&TX_OK)//发送完成
{
return TX_OK;
}
return 0xff;//其他原因发送失败
#else
return 0;
#endif
}
void NRF24L01_TxPacket_AP(u8 *txbuf)
{
SPI3_SetSpeed(SPI_BaudRatePrescaler_16);//spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)
NRF24L01_CE_L(); //StandBy I模式
NRF24L01_Write_Buf(0xA8,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF 32个字节
NRF24L01_CE_H(); //置高CE,激发数据发送
}
//启动NRF24L01接收一次数据
u8 NRF24L01_RxPacket(u8 *rxbuf)
{
#if Single_Com == 1
u8 sta;
SPI3_SetSpeed(SPI_BaudRatePrescaler_32); //spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)
sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值
NRF24L01_Write_Reg(WRITE_REG_NRF+STATUS,sta); //清除TX_DS或MAX_RT中断标志
if(sta&RX_OK)//接收到数据
{
NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器
GPIO_SetBits(GPIOE, GPIO_Pin_15 );
return 0;
}
return 1;//没收到任何数据
#else
return 0;
#endif
}
//设置2401工作模式
void NRF24L01_Mode(u8 model)
{
NRF24L01_CE_L();
NRF24L01_Write_Buf(WRITE_REG_NRF+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址
NRF24L01_Write_Buf(WRITE_REG_NRF+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK
NRF24L01_Write_Reg(WRITE_REG_NRF+EN_AA,0x01); //使能通道0的自动应答 00表示不应答
NRF24L01_Write_Reg(WRITE_REG_NRF+EN_RXADDR,0x01); //使能通道0的接收地址 为0,不接收
NRF24L01_Write_Reg(WRITE_REG_NRF+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次 不重发
NRF24L01_Write_Reg(WRITE_REG_NRF+RF_CH,50); //0x73 设置RF通道为40设置信道工作为2.5GHZ,收发必须一致
NRF24L01_Write_Reg(WRITE_REG_NRF+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启
if(model==1) //RX
{
NRF24L01_Write_Reg(WRITE_REG_NRF+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度
NRF24L01_Write_Reg(WRITE_REG_NRF + CONFIG, 0x0f); // IRQ收发完成中断开启,16位CRC,主接收
}
else if(model==2) //TX
{
NRF24L01_Write_Reg(WRITE_REG_NRF+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度
NRF24L01_Write_Reg(WRITE_REG_NRF + CONFIG, 0x0e); // IRQ收发完成中断开启,16位CRC,主发送
}
else if(model==3) //RX2
{
NRF24L01_Write_Reg(FLUSH_TX,0xff);
NRF24L01_Write_Reg(FLUSH_RX,0xff);
NRF24L01_Write_Reg(WRITE_REG_NRF + CONFIG, 0x3f); //0f // IRQ收发完成中断开启,16位CRC,主接收0x0f
//高位为3表示屏蔽发送中断
SPI3_ReadWriteByte(0x50);
SPI3_ReadWriteByte(0x73);
NRF24L01_Write_Reg(WRITE_REG_NRF+0x1c,0x01);
NRF24L01_Write_Reg(WRITE_REG_NRF+0x1d,0x07); //06
}
else //TX2
{
NRF24L01_Write_Reg(WRITE_REG_NRF + CONFIG, 0x2e); //0e // IRQ收发完成中断开启,16位CRC,主发送0x0e
NRF24L01_Write_Reg(FLUSH_TX,0xff); //高位bit4MAX_RT bit5 为1屏蔽TX_DS bit6 RX_DS
NRF24L01_Write_Reg(FLUSH_RX,0xff); //对于飞控,发送模式2e才是好用的
SPI3_ReadWriteByte(0x50);
SPI3_ReadWriteByte(0x73);
NRF24L01_Write_Reg(WRITE_REG_NRF+0x1c,0x01);
NRF24L01_Write_Reg(WRITE_REG_NRF+0x1d,0x07); //06
}
NRF24L01_CE_H();
}
//启动NRF24L01发送一帧数据
u8 tempbuf[64];
u8 NRF24L01_Txframes(u8 *txbuf,u8 packlen)
{
u8 txresult;
//开始发送处理后的帧
txresult=NRF24L01_TxPacket(txbuf);
if(packlen>32)
txresult=NRF24L01_TxPacket(&txbuf[32]);
if(packlen>64)
txresult=NRF24L01_TxPacket(&txbuf[64]);
if(packlen>96)txresult=!TX_OK;//数据长度大于96暂且认为是错误帧
if(txresult==TX_OK)//发送完成
{
return 1;
}
return 0;//其他原因发送失败
}
void NRF24L01_Check_Event(void)
{
u8 sta;
SPI3_SetSpeed(SPI_BaudRatePrescaler_32);
sta = NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值;
if(sta & RX_OK) //接收到数据
{
u8 Rx_Len = NRF24L01_Read_Reg(R_RX_PL_WID);
if(Rx_Len<33)
{
NRF24L01_Read_Buf(RD_RX_PLOAD,Rx_BUF,RX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
//处理数据
}else NRF24L01_Write_Reg(FLUSH_RX,0xff);//清空缓冲区
}
if(sta & TX_OK)
{
}
if(sta & MAX_TX)
{
if(sta & 0x01) //TX FIFO FULL
NRF24L01_Write_Reg(FLUSH_TX,0xff);
}
NRF24L01_Write_Reg(WRITE
没有合适的资源?快使用搜索试试~ 我知道了~
NRF24L01+ 伪双工通信
共2个文件
h:1个
c:1个
2星 需积分: 49 36 下载量 118 浏览量
2017-12-23
12:19:27
上传
评论 1
收藏 5KB ZIP 举报
温馨提示
NRF24L01+ 伪双工通信代码,实测可用 可应用与无人机通信,免去收发切换的时间 需要带+号的模块
资源推荐
资源详情
资源评论
收起资源包目录
NRF24L01.zip (2个子文件)
NRF24L01
nrf24l01.h 5KB
nrf24l01.c 8KB
共 2 条
- 1
资源评论
- MiruiMiracle2022-01-09与描述不符
- 沐雨余生2021-03-18老哥怎么联系。我下载到你这个了。.c文件最开始有个测试代码,第11行有个NRF24L01_CSN_H3e();函数,这个函数在.c中没有找到。
- qq_294432092019-12-14经过测试, 真他妈的是 骗人的 !! 别下载...可惜我的VIPDcDAV2019-12-28你这种人适合别人嚼烂了再喂到你嘴里,适合复制粘贴。半点基本能力都没有,张口喷饭,你能搞出来这个才怪
- chiqingjiao75032019-08-23http://www.openedv.com/forum.php?mod=viewthread&tid=91958
- Kelly97582044-A2018-12-26骗人的, 只有一个nrf24l01.h和一个nrf24l01.c的文件, 里面就是标准的普通的烂大街的24L01的代码DcDAV2019-08-11只能说你不会用就不要留言误导其他人,先仔细读读手册再瞎喷,分享文件里收发有多个模式其中34是用于伪双工。NRF24L01+只能通过这种方式实现双工通信,说什么全双工都是瞎扯,只能伪双工方式,将回传数据添加在ACK包中一块传回,实现伪双工。
DcDAV
- 粉丝: 3
- 资源: 12
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功