使用飞思卡尔,连接无线模块NRF24L01,程序怎么编写?直接用SPI端口实现?还是虚拟SPI?

使用飞思卡尔,连接无线模块NRF24L01,程序怎么编写?直接用SPI端口实现?还是虚拟SPI?,第1张

nRF24L01是需要单片机通过SPI总线写入数据并拉低CE脚才能发送的。接收端也必须要单片机读取数据。如果你只想通过按键就可以发送,可以使用315M/433M发送模块加上PT2262、PT2272组成的遥控模块,这种只需要按下按钮就能发送。发送时可以附带4位数据,总共16总状态。只要在接收端加一块单片机就可以很容易的实现16路的抢答器了。

在固定长度数据包模式下,接收端在未接收到指定长度的数据包之前是不会进行CRC校验和改变IRQ引脚状态的。

在Enhanced ShockBurst™协议中,前导码、同步字、地址位和CRC校验位全部由nRF24L01完成。使用者仅需在TX_FIFO中写入需要传输的数据即可,在发送时nRF24L01会自动将其它字段附加在发送的信号序列中。

所以32Byte的数据是指可以传送的用户数据长度,前导码、同步字、地址位和CRC校验位不会占用该长度。

nRF24L01是需要单片机通过SPI总线写入数据并拉低CE脚才能发送的。
接收端也必须要单片机读取数据。
如果你只想通过按键就可以发送,可以使用315M/433M发送模块加上PT2262、PT2272组成的遥控模块,这种只需要按下按钮就能发送。
发送时可以附带4位数据,总共16总状态。只要在接收端加一块单片机就可以很容易的实现16路的抢答器了。

是SPI接口吧,就是将相应接口连接起来就行,这是发送的,如果想加按键,可在主函数接收前指定一个I/O口用于按键设置,
#include <reg52h>
#include <intrinsh>
#include <apih>
//
#define uchar unsigned char
#define TX_ADR_WIDTH 5 // 5字节宽度的发送/接收地址
#define TX_PLOAD_WIDTH 4 // 数据通道有效数据宽度
uchar code TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01}; // 定义一个静态发送地址
//uchar code RX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x02};
uchar RX_BUF[TX_PLOAD_WIDTH];
uchar TX_BUF[TX_PLOAD_WIDTH] = {0x22,0x34,0x56,0x78};
uchar flag;
uchar DATA = 0x01;
uchar bdata sta;
sbit RX_DR = sta^6;
sbit TX_DS = sta^5;
sbit MAX_RT = sta^4;
//
/
函数: init_io()
描述:初始化IO
//
void init_io(void)
{
CE = 0; // 待机
CSN = 1; // SPI禁止
SCK = 0; // SPI时钟置低
IRQ = 1; // 中断复位
}
//
/
函数:delay_ms()
描述:延迟x毫秒
//
void delay_ms(uchar x)
{
uchar i, j;
i = 0;
for(i=0; i<x; i++)
{
j = 250;
while(--j);
j = 250;
while(--j);
}
}
//
/
函数:SPI_RW()
描述:根据SPI协议,写一字节数据到nRF24L01,同时从nRF24L01读出一字节
//
uchar SPI_RW(uchar byte)
{
uchar i;
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寄存器
//
uchar SPI_RW_Reg(uchar reg, uchar value)
{
uchar status;
CSN = 0; // CSN置低,开始传输数据
status = SPI_RW(reg); // 选择寄存器,同时返回状态字
SPI_RW(value); // 然后写数据到该寄存器
CSN = 1; // CSN拉高,结束数据传输
return(status); // 返回状态寄存器
}
//
/
函数:SPI_Write_Buf()
描述:把pBuf缓存中的数据写入到nRF24L01,通常用来写入发射通道数据或接收/发送地址
//
uchar SPI_Write_Buf(uchar reg, uchar pBuf, uchar bytes)
{
uchar status, i;
CSN = 0; // CSN置低,开始传输数据
status = SPI_RW(reg); // 选择寄存器,同时返回状态字
for(i=0; i<bytes; i++)
SPI_RW(pBuf[i]); // 逐个字节写入nRF24L01
CSN = 1; // CSN拉高,结束数据传输
return(status); // 返回状态寄存器
}
//
/
函数:TX_Mode()
描述:这个函数设置nRF24L01为发送模式,(CE=1持续至少10us),130us后启动发射,数据发送结束后,发送模块自动转入接收模式等待应答信号。
//
void TX_Mode(uchar BUF)
{
CE = 0;
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写入发送地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 为了应答接收设备,接收通道0地址和发送地址相同
SPI_Write_Buf(WR_TX_PLOAD, BUF, TX_PLOAD_WIDTH); // 写数据包到TX FIFO
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 使能接收通道0自动应答
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 使能接收通道0
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0); // 自动重发延时等待250us+86us,自动重发10次
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // 选择射频通道0x40
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x01); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // CRC使能,16位CRC校验,上电
CE = 1;
}
//
/
函数:Check_ACK()
描述:检查接收设备有无接收到数据包,设定没有收到应答信号是否重发
//
uchar Check_ACK(bit clear)
{
while(IRQ);
sta = SPI_RW(NOP); // 返回状态寄存器
if(MAX_RT)
if(clear) // 是否清除TX FIFO,没有清除在复位MAX_RT中断标志后重发
SPI_RW(FLUSH_TX);
SPI_RW_Reg(WRITE_REG + STATUS, sta); // 清除TX_DS或MAX_RT中断标志
IRQ = 1;
if(TX_DS)
return(0x00);
else
return(0xff);
}
//
/
函数:main()
描述:主函数
//
void main(void)
{
init_io();
while(1)
{
TX_Mode(TX_BUF);
Check_ACK(1);
delay_ms(1000);
}
}
//

nRF24L01的封装及引脚排列如图1、2所示。各引脚功能如下:
CE:使能发射或接收;
CSN,SCK,MOSI,MISO:SPI引脚端,微处理器可通过此引脚配置nRF24L01:
IRQ:中断标志位;
VDD:电源输入端;
VSS:电源地:
XC2,XC1:晶体振荡器引脚;
VDD_PA:为功率放大器供电,输出为18 V;
ANT1,ANT2:天线接口;
IREF:参考电流输入。 引脚 名称 引脚功能 描述 1 CE 数字输入 RX或TX模式选择 2 CSN 数字输入 SPI片选信号 3 SCK 数字输入 SPI时钟 4 MOSI 数字输入 从SPI数据输入脚 5 MISO 数字输出 从SPI数据输出脚 6 IRQ 数字输出 可屏蔽中断脚 7 VDD 电源 电源(+3V) 8 VSS 电源 接地(0V) 9 XC2 模拟输出 晶体振荡器2脚 10 XC1 模拟输入 晶体振荡器1脚/外部时钟输入脚 11 VDD-PA 电源输出 给RF的功率放大器提供的+18V电源 12 ANT1 天线 天线接口1 13 ANT2 天线 天线接口2 14 VSS 电源 接地(0V) 15 VDD 电源 电源(+3V) 16 IREP 模拟输入 参考电流 17 VSS 电源 接地(0V) 18 VDD 电源 电源(+3V) 19 DVDD 电源输出 去耦电路电源正极端 20 VSS 电源 接地(0V)

RF-CH共包括六位,这六位决定了不同的工作方式频率,nRF24L01无线通信模块中工作通道频率由RF-CH寄存器的内容确定,可由以下公式计算得出:Fo=(2400+RF-CH)MHz
扩展:射频频道的频率决定射频收/发所使用频道的中心频率,在速率为250Kbps或1Mbps时,频道占用的带宽小于1M,而在速率为2Mbps时,所占宽带小于2M,射频收发器工作的频率范围从2400-2525GHz,无线频道设置的频率分辨率为1MHz。
由于在2Mbps通信速率时,占用宽带为超过频道分辨率,为了确保在2Mbps速率下不出现重叠,频道间隔必须设定为2M或更宽一些,250Kbps或1Mbps速率下占用宽带等于或低于频道分辨率。
无线频率由RF-CH寄存器的内容确定,可由以下公式计算得出:Fo=(2400+RF-CH)MHz
为确保相互通信,发射器和接收器须编程为同一个频率

通过配置寄存器可将nRF241L01配置为发射、接收、空闲及掉电四种工作模式,如表1所示。 模式 PWR_UP PRIM_RX CE FIFO寄存器状态 接收模式 1 1 1 - 发射模式 1 0 1 数据在TX FIFO 寄存器中 发射模式 1 0 1→0 停留在发送模式,直至数据发送完 待机模式2 1 0 1 TX FIFO 为空 待机模式1 1 - 0 无数据传输 掉电 0 - - - 表 (1)
待机模式1主要用于降低电流损耗,在该模式下晶体振荡器仍然是工作的;
待机模式2则是在当FIFO寄存器为空且CE=1时进入此模式;
待机模式下,所有配置字仍然保留。
在掉电模式下电流损耗最小,同时nRF24L01也不工作,但其所有配置寄存器的值仍然保留。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12625237.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存