24L01+带数据包的ACK用于双向传输Word下载.docx
- 文档编号:22120266
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:20
- 大小:133.55KB
24L01+带数据包的ACK用于双向传输Word下载.docx
《24L01+带数据包的ACK用于双向传输Word下载.docx》由会员分享,可在线阅读,更多相关《24L01+带数据包的ACK用于双向传输Word下载.docx(20页珍藏版)》请在冰豆网上搜索。
//MasterIn,SlaveOutpin(input)
//sbitMISO=P3^7;
//SerialClockpin,(output)
//sbitIRQ=P3^6;
//MasterOut,SlaveInpin(output)
sbitCE=P0^4;
sbitCSN=P0^3;
sbitSCK=P0^2;
sbitMOSI=P0^1;
sbitMISO=P0^0;
sbitIRQ=P4^6;
//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:
#defineRX_ADDR_P40x0E//数据通道4接收地址,最低字节可设定,高字节部分必须与RX_ADDR_P1[39:
#defineRX_ADDR_P50x0F//数据通道5接收地址,最低字节可设定,高字节部分必须与RX_ADDR_P1[39:
#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<
STC15W.h>
#include"
nrf24l01.h"
intrins.h>
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();
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);
case3:
SPI_Write_Reg(FLUSH_TX,0xff);
SPI_Write_Reg(FLUSH_RX,0xff);
//IRQ收发完成中断开启,16位CRC,主接收
SPI_RW(0x50);
SPI_RW(0x73);
SPI_Write_Reg(WRITE_REG+DYNPD,0x01);
SPI_Write_Reg(WRITE_REG+FEATURE,0x06);
case4:
SPI_Write_Reg(WRITE_REG+CONFIG,0x0e);
//IRQ收发完成中断开启,16位CRC,主发送
SPI_Write_Reg(FLUSH_TX,0xff);
default:
break;
}
CE=1;
}
函数:
delay_ms()
描述:
延迟x毫秒
voidDelay12us()//@18.432MHz
unsignedchari;
_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;
SPI_RW(reg);
//选择寄存器
reg_val=SPI_RW(0);
//然后从该寄存器读数据
return(reg_val);
//返回寄存器数据
SPI_Read_Buf()
从reg寄存器读出bytes个字节,通常用来读取接收通道
数据或接收/发送地址
ucharSPI_Read_Buf(ucharreg,uchar*pBuf,ucharbytes)
ucharstatus,i;
bytes;
i++)
pBuf[i]=SPI_RW(0);
//逐个字节从nRF24L01读出
SPI_Write_Buf()
把pBuf缓存中的数据写入到nRF24L01,通常用来写入发
射通道数据或接收/发送地址
ucharSPI_Write_Buf(ucharreg,uchar*pBuf,ucharbytes)
CSN=0;
status=SPI_RW(reg);
for(i=0;
SPI_RW(pBuf[i]);
//逐个字节写入nRF24L01
return(status);
voidNRF_TX(uchar*pBuf,ucharLen)//发送数据包,用于发送模式2/4
SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);
//装载接收端地址
SPI_Write_Buf(WR_TX_PLOAD,pBuf,Len);
//装载数据
voidNRF_TX_AP(uchar*pBuf,ucharLen)//发送数据包,接收模式2
SPI_Write_Buf(W_ACK_PAYLOAD,pBuf,Len);
//判断寄存器状态是否有接收到数据或者发送完数据
voidRead_24L01_data(void)
//while(IRQ);
sta=SPI_Read(READ_REG+STATUS);
//读状态寄存器
if(RX_DR)//判断是否接受到数据
Length=SPI_Read(READ_REG+R_RX_PL_WID);
if(Length<
33)
SPI_Read_Buf(RD_RX_PLOAD,RX_BUF,Length);
//从RXFIFO读出数据
RX_flag=1;
//将标志位置1,表示接收到数据,好让主函数去处理接收到的数据
else
SPI_Write_Reg(FLUSH_RX,0xff);
//清空缓冲区
if(TX_DS)
;
if(MAX_RT)
if(sta&
0x01)//TXFIFOFULL
SPI_Write_Reg(FLUSH_TX,0xff);
SPI_Write_Reg(WRITE_REG+STATUS,sta);
//清除RX_DS中断标志
以下是主函数,发送与接收模式用一样的.c.h文件,初始化为不同模式就行了
/************************************************************************************/
/***********************************************************************/
发送模式:
voidDelayxms(Wordxms)//@18.432MHz
Wordj;
for(;
xms>
0;
xms--)
for(j=1110;
j>
j--);
Bytea;
voidmain()
{
Dela
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 24 L01 数据包 ACK 用于 双向 传输