高级会员
主题
帖子
积分750
阅读权限30
注册时间2013-10-25
最后登录1970-1-1
在线时间 小时
|
最近没事研究了一下网上说的很多的NRF24L01模块,在淘宝上买了几个,三块钱一个,这几天弄的可烦人了,数据丢包很严重,发送三个数据包,距离很近,接收模块最多能收到俩数据包, 发送接收距离放远了6m左右,发10个,收到1个就不错话不多说 上程序,我怀疑是我买的模块不行,还是这种模块就是这么个德行,真心感觉太烂了
主函数意思就是,上电复位 发送三个数据包后,就进入接收模式,我就是这么测试模块收发的
#include "rf2401.h"
#include "spi_init.h"
#include "STM32f10x.h"
#include"uart_init.h"
#include "delay.h"
u8 TX_ADDRESS[5]={0xe7,0xe7,0xe7,0xe7,0xe7};
//u8 RX_ADDRESS[5]={0xc2,0xc2,0xc2,0xc2,0xc2};
u8 tx_buf[10]={0,1,2,3,4,5,6,7,8,9};
u8 reciece_data[10]={0};
void rf2401_io_init()
{
//**配置spi1 引脚为复用输出*////
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9; //选择
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //速度配置为2M
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
Clr_CE;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10; //选择
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //速度配置为2M
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void rf2401_wr_reg(u8 addr,u8 data)
{
addr=addr|RF_WRITE_REG;
Clr_CS;
// delay_ms(80);
SPIx_ReadWriteByte(addr);
SPIx_ReadWriteByte(data);
Set_CS;
// delay_ms(80);
}
u8 rf2401_re_reg(u8 addr)
{ u8 data;
addr=addr|RF_READ_REG;
Clr_CS;
SPIx_ReadWriteByte(addr);
data=SPIx_ReadWriteByte(0);
Set_CS;
return data;
}
void rf2401_wr_buf(u8 reg, u8 *pBuf, u8 bytes )
{
u8 byte_ctr;
Clr_CS; // Set CSN low, init SPI tranaction
SPIx_ReadWriteByte(reg); // Select register to write to and read status byte
Delay(10);
for(byte_ctr=0; byte_ctr<bytes; byte_ctr++) // then write all byte in buffer(*pBuf)
SPIx_ReadWriteByte(*(pBuf++));
Set_CS; // Set CSN high again
}
/**************************************************
函数:SPI_Read_Buf()
描述:从reg寄存器读出bytes个字节,通常用来读取接收通道
数据或接收/发送地址
*************************************************/
u8 rf2401_read_buf(u8 reg, u8 * pBuf, u8 bytes)
{
u8 status, i;
Clr_CS; // CSN置低,开始传输数据
status = SPIx_ReadWriteByte(reg); // 选择寄存器,同时返回状态字
for(i=0; i<bytes; i++)
pBuf[i] = SPIx_ReadWriteByte(0); // 逐个字节从nRF24L01读出
Set_CS; // CSN拉高,结束数据传输
return(status); // 返回状态寄存器
}
/**************************************************
函数:Check_ACK()
描述:
检查接收设备有无接收到数据包,设定没有收到应答信
号是否重发
***************************************************/
u8 check_rx(void)
{ u8 reg_staus;
reg_staus= rf2401_re_reg(STATUS);
if (reg_staus&0x40==0)
return 0;
else
return 1;
}
void rf2401_init(void)
{
rf2401_io_init();
spi1_init();
delay_ms(5);
rf2401_wr_reg( EN_AA, 0x00); // 使能自动应答
rf2401_wr_reg( SETUP_AW, 0x02); //地址宽度设置为5个字节
rf2401_wr_reg( SETUP_RETR, 0x10); //重发延时 500us + 86us, 重发10次
rf2401_wr_reg( RF_CH, 100); // Select RF channel 40
rf2401_wr_reg( RF_SETUP, 0x03); // TX_PWR:0dBm, Datarate:2Mbps,LNA:HCURR
}
///**************************************************
//函数:RX_Mode()
//描述:这个函数设置nRF24L01为接收模式,等待接收发送设备的数据包
//*************************************************/
void RX_Mode(void)
{
//Clr_CE;
rf2401_wr_buf(RF_WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); //设置发送地址和宽度
rf2401_wr_buf(RF_WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); //设置接收地址和宽度
//rf2401_wr_buf(RF_WRITE_REG + RX_ADDR_P1, TX_ADDRESS, TX_ADR_WIDTH); //设置接收地址和宽度
rf2401_wr_reg( EN_RXADDR, 0x01); //使能接收通道0
rf2401_wr_reg( RX_PW_P0, TX_PLOAD_WIDTH); //设置有效数据宽度
//rf2401_wr_reg( RX_PW_P1, TX_PLOAD_WIDTH); //设置有效数据宽度
rf2401_wr_reg( CONFIG, 0x0b); // irq引脚显示中断信息 crc使能 ,上电接收模式
Set_CE; // Set CE pin high to enable RX device
delay_ms(15);
}
// /**************************************************
//函数:TX_Mode()
//描述:
// 这个函数设置nRF24L01为发送模式,(CE=1持续至少10us),
// 130us后启动发射,数据发送结束后,发送模块自动转入接收
// 模式等待应答信号。
//*************************************************/
void TX_Mode(void)
{
u8 rf_status;
rf2401_wr_buf(RF_WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); //设置发送地址和宽度
rf2401_wr_buf(RF_WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); //设置接收地址和宽度
rf2401_wr_reg( FLUSH_TX , NOP); // irq引脚显示中断信息 crc使能 ,上电接收模式
rf2401_wr_buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); //设置发送换出去有效字节数目
rf2401_wr_reg( CONFIG, 0x0a); //关闭 crc 打开上电发送
Set_CE; // Set CE pin high to enable RX device
delay_ms(15);
Clr_CE;
//rf2401_wr_reg( STATUS, rf2401_re_reg(0x07)); //地址宽度设置为5个字节
rf_status= rf2401_re_reg(STATUS);
uart2_hex_to_16asiic(rf_status);
put_String2("\n");
if (rf_status&0x10)
{
rf2401_wr_reg( STATUS, rf_status); //关闭 crc 打开上电发送
}
}
void rf2401_send_databag(void)
{
TX_Mode();
}
void rf2401_recieve_dis(void)
{
u8 i,rf_status;
RX_Mode();
rf_status= rf2401_re_reg(0x07);
//uart2_hex_to_16asiic(rf_status);
//put_String2("\n");
if (rf_status&0x40)
{
rf2401_read_buf(RD_RX_PLOAD,reciece_data,TX_PLOAD_WIDTH);
for (i=0;i<10;i++)
{
uart2_hex_to_16asiic(reciece_data[i]); }
rf2401_wr_reg( FLUSH_RX, NOP); // irq引脚显示中断信息 crc使能 ,上电接收模式
rf2401_wr_reg( STATUS, rf_status); //地址宽度设置为5个字节
}
}
int main(void)
{ u8 t;
clk_init();
uart2_init ();
put_String2("串口2接收正常\n");
rf2401_init();
for(t=0;t<3;t++)
rf2401_send_databag ();
while (1)
{
rf2401_recieve_dis();
}
}
|
|