24L01+带大数据包地ACK用于双向传输.docx

上传人:b****8 文档编号:9345634 上传时间:2023-02-04 格式:DOCX 页数:19 大小:54.98KB
下载 相关 举报
24L01+带大数据包地ACK用于双向传输.docx_第1页
第1页 / 共19页
24L01+带大数据包地ACK用于双向传输.docx_第2页
第2页 / 共19页
24L01+带大数据包地ACK用于双向传输.docx_第3页
第3页 / 共19页
24L01+带大数据包地ACK用于双向传输.docx_第4页
第4页 / 共19页
24L01+带大数据包地ACK用于双向传输.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

24L01+带大数据包地ACK用于双向传输.docx

《24L01+带大数据包地ACK用于双向传输.docx》由会员分享,可在线阅读,更多相关《24L01+带大数据包地ACK用于双向传输.docx(19页珍藏版)》请在冰豆网上搜索。

24L01+带大数据包地ACK用于双向传输.docx

24L01+带大数据包地ACK用于双向传输

发现网上关于24L01带数据包的ACK介绍的比较少,自己之前做四轴的时候想说用24L01做双向通讯,但是对于频繁切换发送、接收模式很是麻烦,时间调的不好很容易造成通讯失败,后来想到24L01的带数据包的ACK做双向通讯,在网上找了资料,但是就只做了简单介绍,没有介绍用的时候是怎么实现,下面我就对我使用的过程做一个总结,在附上测试程序(C51),本人热衷于使用STC单片机做东西,四轴也是用STC单片机来做的控制板,飞的也还行。

对于初学者来讲,STC单片机的程序看起来也比较容易看得懂,对于双向传输,我看过STM32的程序,想要移植到51上,但是对于发送接收部分没有详细的注释,所以刚开始也是一头雾水,找半天都找不到什么时候吧带数据的ACK包送入缓存,所以也就放弃了,但是我觉得初始化部分写的比较好,所以也就移植了部分程序,好了不多说,下面开始将原理:

带数据包的ACK应答传输,有的人说只能用在24L01+上,没有+的用不了,然而我刚好只有带+的,没带+的用不用的了这个我就不知道了,但是我看过没带+的芯片手册,并没有看到有关带数据包的ACK的介绍,然后又看了带+的芯片手册,在带+的手册上发现有相关带数据包的ACK的介绍,所以我也认为ACK要能带数据包,只能用在有+的芯片上。

利用这个ACK做数据传输,首先要配置正确,对于配置,你们网上找找,也能找到,我也在这里直接复制粘贴别人的说法:

1,需要设置成为可变长度的接收与发送

2,需要将接收数据的ACK使能

3,由于ACK带有数据因此自动重发的时间要改成500μS

4,将数据写入等待发送使用的是W_ACK_PAYLOAD命令

作为接收模式,若要让ACK带上数据包,那就得在接收到数据之前,把数据包送到ACK发送缓存,将数据写入W_ACK_PAYLOAD这个地址里面,详细介绍如下

从这里可以看出,W_ACK_PAYLOAD的地址为0xA8-0xAD,用哪个地址由你喜欢,缓存字节数为32字节。

所以,初始化为接收模式之后,就先装载ACK包,然后在进入接收循环,每当接收到发送端发送过来的数据,读取数据完毕,马上把ACK数据包再写进去,不写的话发送端就接收不到带数据包的ACK。

作为发送端,在发送完数据之后立马就读取到ACK数据包了,我刚开始用的时候也是犯傻,怎么把ACK里面的数据提取出来,想了半天,后来也是灵光一现,想着,手册上说,通道0是接收应答信号的,那收到的ACK数据包读取方式应该跟一般接收到的数据读取方式是一样的,所以我就尝试了一下,果然成了,能接收到数据了,废话不多说,我文采不好,不想打这么多字了,下面直接附上程序:

 

以下是.h文件

/*****************************************************************************************************************************************************/

#ifndef__NRF24L01_H_

#define__NRF24L01_H_

#defineucharunsignedchar

#defineuintunsignedint

/*

1:

GND;2:

Vcc;3:

CE;4CSN;5:

SCK;6:

MOSI;7:

MISO;8:

IRQ

*/

//sbitCE=P7^3;//ChipEnablepinsignal(output)

//sbitCSN=P7^2;//SlaveSelectpin,(outputtoCSN,nRF24L01)

//sbitSCK=P7^1;//Interruptsignal,fromnRF24L01(input)

//sbitMOSI=P7^0;//MasterIn,SlaveOutpin(input)

//sbitMISO=P3^7;//SerialClockpin,(output)

//sbitIRQ=P3^6;//MasterOut,SlaveInpin(output)

 

sbitCE=P0^4;//ChipEnablepinsignal(output)

sbitCSN=P0^3;//SlaveSelectpin,(outputtoCSN,nRF24L01)

sbitSCK=P0^2;//Interruptsignal,fromnRF24L01(input)

sbitMOSI=P0^1;//MasterIn,SlaveOutpin(input)

sbitMISO=P0^0;//SerialClockpin,(output)

sbitIRQ=P4^6;//MasterOut,SlaveInpin(output)

//SPI(nRF24L01)commands

#defineREAD_REG0x00//读寄存器指令

#defineWRITE_REG0x20//写寄存器指令

#defineR_RX_PL_WID0x60//读接收到的数据长度

#defineRD_RX_PLOAD0x61//读接收数据指令

#defineWR_TX_PLOAD0xA0//写待发送数据指令

#defineW_ACK_PAYLOAD0xA8//写ACK数据指令,用于接收模式

#defineFLUSH_TX0xE1//冲洗发送FIFO指令

#defineFLUSH_RX0xE2//冲洗接收FIFO指令

#defineREUSE_TX_PL0xE3//重复装载数据指令

#defineNOP0xFF//空指令,用于读出状态字

//寄存器地址

#defineCONFIG0x00//配置寄存器

#defineEN_AA0x01//自动应答,禁止自动应答后可以与2401通讯

#defineEN_RXADDR0x02//接收地址允许

#defineSETUP_AW0x03//设置地址宽度

#defineSETUP_RETR0x04//自动重发

#defineRF_CH0x05//射频通道

#defineRF_SETUP0x06//射频寄存器

#defineSTATUS0x07//状态寄存器

#defineOBSERVE_TX0x08//发送检测寄存器

#defineCD0x09//地址检查

#defineRX_ADDR_P00x0A//数据通道0接收地址,最大长度5个字节,先写低字节,所有字节数量由SETUP_AW设定

#defineRX_ADDR_P10x0B//数据通道1接收地址,最大长度5个字节,先写低字节,所有字节数量由SETUP_AW设定

#defineRX_ADDR_P20x0C//数据通道2接收地址,最低字节可设定,高字节部分必须与RX_ADDR_P1[39:

8]相等

#defineRX_ADDR_P30x0D//数据通道3接收地址,最低字节可设定,高字节部分必须与RX_ADDR_P1[39:

8]相等

#defineRX_ADDR_P40x0E//数据通道4接收地址,最低字节可设定,高字节部分必须与RX_ADDR_P1[39:

8]相等

#defineRX_ADDR_P50x0F//数据通道5接收地址,最低字节可设定,高字节部分必须与RX_ADDR_P1[39:

8]相等

#defineTX_ADDR0x10//发送地址

#defineRX_PW_P00x11//通道0接收数据长度

#defineRX_PW_P10x12//通道1接收数据长度

#defineRX_PW_P20x13//通道2接收数据长度

#defineRX_PW_P30x14//通道3接收数据长度

#defineRX_PW_P40x15//通道4接收数据长度

#defineRX_PW_P50x16//通道5接收数据长度

#defineFIFO_STATUS0x17//FIFO状态寄存器

#defineDYNPD0x1C

#defineFEATURE0x1D

#defineMode_RX11//普通接收模式

#defineMode_TX12//普通发送模式

#defineMode_RX23//双向传输接收模式

#defineMode_TX24//双向传输发送模式

#defineTX_ADR_WIDTH5//5字节宽度的发送地址

#defineRX_ADR_WIDTH5//5字节宽度的接收地址

#defineTX_PLOAD_WIDTH32//数据通道有效数据宽度

#defineRX_PLOAD_WIDTH32//数据通道有效数据宽度

 

externucharcodeTX_ADDRESS[TX_ADR_WIDTH];

externucharcodeRX_ADDRESS[RX_ADR_WIDTH];

externucharRX_BUF[TX_PLOAD_WIDTH];//接收缓存

externucharTX_BUF[TX_PLOAD_WIDTH];//发送缓存

externucharRX_flag;//接收标志

externucharLength;//数据长度

voidInit_24L01(ByteModeDat,Bytech);//初始化24L01

voidDelay12us();

ucharSPI_RW(ucharbyte);//SPI读写函数

ucharSPI_Write_Reg(ucharreg,ucharvalue);

ucharSPI_Read(ucharreg);

ucharSPI_Read_Buf(ucharreg,uchar*pBuf,ucharbytes);

ucharSPI_Write_Buf(ucharreg,uchar*pBuf,ucharbytes);

voidNRF_TX(uchar*pBuf,ucharLen);//发送数据包,用于发送模式2/4

voidNRF_TX_AP(uchar*pBuf,ucharLen);//发送数据包,接收模式2

ucharCheck_ACK(bitclear);

voidRead_24L01_data(void);

#endif

/********************************************************************************************************************************************************/

以下是.c文件

#include

#include"nrf24l01.h"

#include

#include"uart1.h"

ucharbdatasta;

sbitRX_DR=sta^6;

sbitTX_DS=sta^5;

sbitMAX_RT=sta^4;

ucharcodeTX_ADDRESS[TX_ADR_WIDTH]={0x13,0x14,0x52,0x05,0x20};//定义一个静态发送地址

ucharcodeRX_ADDRESS[RX_ADR_WIDTH]={0x13,0x14,0x52,0x05,0x20};//定义一个静态发送地址

 

ucharRX_BUF[TX_PLOAD_WIDTH];//接收缓存

ucharTX_BUF[TX_PLOAD_WIDTH];//发送缓存

ucharRX_flag;//接收标志

ucharLength;//数据长度

/**************************************************/

/**************************************************

函数:

init_io()

描述:

初始化IO

/**************************************************/

voidInit_24L01(ByteModeDat,Bytech)

{

CE=0;//待机

CSN=1;//SPI禁止

SCK=0;//SPI时钟置低

IRQ=1;//中断复位

Delay12us();

CE=0;

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);//为了应答接收设备,接收通道0地址和发送地址相同

SPI_Write_Reg(WRITE_REG+EN_AA,0x01);//使能接收通道0自动应答

SPI_Write_Reg(WRITE_REG+EN_RXADDR,0x01);//使能接收通道0

SPI_Write_Reg(WRITE_REG+SETUP_RETR,0x1a);//自动重发延时等待500us,自动重发10次

SPI_Write_Reg(WRITE_REG+RF_CH,ch);//选择射频通道ch

SPI_Write_Reg(WRITE_REG+RF_SETUP,0x0f);//数据传输率1Mbps,发射功率0dBm,低噪声放大器增益

switch(ModeDat)

{

case1:

SPI_Write_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//接收通道0选择和发送通道相同有效数据宽度

SPI_Write_Reg(WRITE_REG+CONFIG,0x0f);

break;

case2:

SPI_Write_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);

SPI_Write_Reg(WRITE_REG+CONFIG,0x0e);

break;

case3:

SPI_Write_Reg(FLUSH_TX,0xff);

SPI_Write_Reg(FLUSH_RX,0xff);

SPI_Write_Reg(WRITE_REG+CONFIG,0x0f);//IRQ收发完成中断开启,16位CRC,主接收

SPI_RW(0x50);

SPI_RW(0x73);

SPI_Write_Reg(WRITE_REG+DYNPD,0x01);

SPI_Write_Reg(WRITE_REG+FEATURE,0x06);

break;

case4:

SPI_Write_Reg(WRITE_REG+CONFIG,0x0e);//IRQ收发完成中断开启,16位CRC,主发送

SPI_Write_Reg(FLUSH_TX,0xff);

SPI_Write_Reg(FLUSH_RX,0xff);

SPI_RW(0x50);

SPI_RW(0x73);

SPI_Write_Reg(WRITE_REG+DYNPD,0x01);

SPI_Write_Reg(WRITE_REG+FEATURE,0x06);

break;

default:

break;

}

CE=1;

}

/**************************************************/

/**************************************************

函数:

delay_ms()

描述:

延迟x毫秒

/**************************************************/

voidDelay12us()//@18.432MHz

{

unsignedchari;

_nop_();

_nop_();

_nop_();

i=52;

while(--i);

}

/**************************************************/

/**************************************************

函数:

SPI_RW()

描述:

根据SPI协议,写一字节数据到nRF24L01,同时从nRF24L01

读出一字节

/**************************************************/

ucharSPI_RW(ucharbyte)

{

uchari;

for(i=0;i<8;i++)//循环8次

{

MOSI=(byte&0x80);//byte最高位输出到MOSI

byte<<=1;//低一位移位到最高位

SCK=1;//拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据

byte|=MISO;//读MISO到byte最低位

SCK=0;//SCK置低

}

return(byte);//返回读出的一字节

}

/**************************************************/

/**************************************************

函数:

SPI_RW_Reg()

描述:

写数据value到reg寄存器

/**************************************************/

ucharSPI_Write_Reg(ucharreg,ucharvalue)

{

ucharstatus;

CSN=0;//CSN置低,开始传输数据

status=SPI_RW(reg);//选择寄存器,同时返回状态字

SPI_RW(value);//然后写数据到该寄存器

CSN=1;//CSN拉高,结束数据传输

return(status);//返回状态寄存器

}

/**************************************************/

/**************************************************

函数:

SPI_Read()

描述:

从reg寄存器读一字节

/**************************************************/

ucharSPI_Read(ucharreg)

{

ucharreg_val;

CSN=0;//CSN置低,开始传输数据

SPI_RW(reg);//选择寄存器

reg_val=SPI_RW(0);//然后从该寄存器读数据

CSN=1;//CSN拉高,结束数据传输

return(reg_val);//返回寄存器数据

}

/**************************************************/

/**************************************************

函数:

SPI_Read_Buf()

描述:

从reg寄存器读出bytes个字节,通常用来读取接收通道

数据或接收/发送地址

/**************************************************/

ucharSPI_Read_Buf(ucharreg,uchar*pBuf,ucharbytes)

{

ucharstatus,i;

CSN=0;//CSN置低,开始传输数据

status=SPI_RW(reg);//选择寄存器,同时返回状态字

for(i=0;i

pBuf[i]=SPI_RW(0);//逐个字节从nRF24L01读出

CSN=1;//CSN拉高,结束数据传输

return(status);//返回状态寄存器

}

/**************************************************/

/**************************************************

函数:

SPI_Write_Buf()

描述:

把pBuf缓存中的数据写入到nRF24L01,通常用来写入发

射通道数据或接收/发送地址

/**************************************************/

ucharSPI_Write_Buf(ucharreg,uchar*pBuf,ucharbytes)

{

ucharstatus,i;

CSN=0;//CSN置低,开始传输数据

status=SPI_RW(reg);//选择寄存器,同时返回状态字

for(i=0;i

SPI_RW(pBuf[i]);//逐个字节写入nRF24L01

CSN=1;//CSN拉高,结束数据传输

return(status);//返回状态寄存器

}

/**************************************************/

 

voidNRF_TX(uchar*pBuf,ucharLen)//发送数据包,用于发送模式2/4

{

CE=0;

SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);//装载接收端地址

SPI_Write_Buf(WR_TX_PLOAD,pBuf,Len);//装载数据

CE=1;

Delay12us();

}

voidNRF_TX_AP(uchar*pBuf,ucharLen)//发送数据包,接收模式2

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1