nRF24L01 无线收发控制 Verilog Quartus(2)

名称:nRF24L01 无线收发控制 Verilog Quartus(2)

软件:Quartus

语言:Verilog

功能介绍

这是一个基于 Verilog 和 Quartus 的 nRF24L01 无线收发控制工程,使用 FPGA 通过 SPI 接口完成 nRF24L01 模块的寄存器配置、地址设置、射频参数设置、状态读取及数据载荷收发。工程包含发送、接收和收发切换相关模块,并将 IRQ、CE、CSN、SCLK、MOSI、MISO 等关键控制信号引出,适合用于 2.4GHz 无线通信接口的 FPGA 实现学习。 顶层 nrf24L01_rev 采用分阶段状态控制方式,依次处理 RX_ADDR_P0、TX_ADDR、EN_AA、EN_RXADDR、SETUP_RETR、RF_CH、RF_SETUP、STATUS、RX_PW_P0、FLUSH_RX、CONFIG 和 R_RX_PAYLOAD 等寄存器操作,支持地址及有效载荷的多字节传输。配套的 LCD 和定时模块可用于显示通信状态或测试数据,工程还提供发送方向 nrf24L01_tran 及相关测试文件,便于构建完整的收发实验。

运行环境

开发语言:Verilog;开发软件:Intel Quartus。工程提供 nrf24l01_rev.qpf、nrf24l01_rev.qsf、nrf24l01_tran.qpf 和 nrf24l01_tran.qsf 项目文件,可在 Quartus 中分别打开接收与发送工程进行编译、管脚分配和配置文件生成。

设计思路

设计以 nRF24L01 的 SPI 寄存器控制流程为核心,将发送、接收、状态读取和数据载荷处理拆分为独立 Verilog 模块。nrf24L01_rev 负责接收方向的寄存器初始化与 SPI 时序调度,通过 spi_rwqq 状态推进不同配置阶段,并根据 byte_num、byte_tran 和 byte_qq 组织多字节地址及控制数据。spi_mode 负责产生 CSN、SCLK、MOSI 等串行信号,nedge_mode 对 IRQ 边沿进行处理,形成完整的无线收发控制链路。 工程同时提供 nrf24L01_tx_core、nrf24L01_rx_core 和 rf24_turn_node 等通用模块,用于搭建发送端、接收端及收发切换节点;timer_lcd、timer_spi、cnt5、cnt10 等模块提供时基和计数支持,lcd_24l01test0 用于配合显示测试结果。通过 rev 与 tran 两套工程,可以分别组织接收和发送方向的验证流程,便于学习 nRF24L01 寄存器配置、自动应答、射频参数设置、FIFO 操作以及 SPI 状态机设计。

模块结构

工程主要由以下层次组成:nrf24L01_rev 与 nrf24L01_tran 分别承担接收和发送方向的顶层控制;nrf24L01_tx_core、nrf24L01_rx_core 和 rf24_turn_node 用于封装无线收发及收发切换逻辑;spi_mode 负责 SPI 串行时序,nedge_mode 处理 IRQ 边沿检测;timer_spi、timer_lcd、cnt5、cnt10 提供计时和计数;lcd_24l01test0 负责测试信息显示。rev、tran 目录分别配有独立 Quartus 工程、管脚约束和测试模块。

开发板验证

工程提供 rev 与 tran 两套 Quartus 项目及对应 QSF 管脚约束文件,包含 nRF24L01 SPI 接口、状态信号、数据输入输出和显示相关端口的分配信息,并带有可直接用于编译配置的工程文件。用户可按约束文件连接 nRF24L01 模块和外围显示电路,完成下载验证。

仿真图/仿真说明/设计文档图片

工程包含 test_24l01rev.v、test_24l01tran.v 等测试文件,可用于搭建 nRF24L01 接收和发送方向的功能验证环境。

部分代码

以下展示顶层模块 nrf24L01_rev 的部分代码,完整源码请下载压缩包查看。

module nrf24L01_rev(clk,rst,irq,miso,csn,sclk,mosi,ce,data_rev,rev_lock,en_1ms,en_1s,stage_dq);
input clk,rst,irq,miso;
output [15:0]data_rev;
output csn,sclk,mosi,ce,rev_lock,en_1ms,en_1s;
output [3:0]stage_dq;


reg [5:0]byte_num,byte_qq;
reg [7:0] byte_tran;
reg [3:0]spi_rwqq;
reg [15:0]data_rev;

wire irq_en,rwb_spi,spi_sta,en_100us,en_1ms,en_1s,byte_en_tran,byte_en_rev,spi_busy,spi_end;
wire [7:0]byte_rev;


assign ce=spi_rwqq[3] & spi_rwqq[1] & spi_rwqq[0] & ~spi_busy;
assign rev_lock=spi_rwqq[3] & spi_rwqq[1] & spi_rwqq[0] & spi_end;
assign stage_dq=spi_rwqq;
assign rwb_spi= spi_rwqq[3] & spi_rwqq[1] & spi_rwqq[0];
//assign data_rev=data_rev_reg;
assign spi_sta=(spi_rwqq[3] & spi_rwqq[1] & spi_rwqq[0])? irq_en : en_100us;


spi_mode U0(clk,rst,rwb_spi,spi_sta,byte_num,byte_tran,byte_en_tran,byte_rev,byte_en_rev,spi_busy,csn,sclk,mosi,miso,en_100us,en_1ms,en_1s,spi_end);
nedge_mode U1(clk,rst,1'b1,irq,irq_en);


always@(posedge clk or negedge rst)
if(~rst)
   spi_rwqq<=4'b0000;
else if(spi_end)
  begin
     if(spi_rwqq[3] & spi_rwqq[1] & spi_rwqq[0])
         spi_rwqq<=4'b0111;
     else
         spi_rwqq<=spi_rwqq + 1'b1;
  end



always@(posedge clk or negedge rst)
if(~rst)
   byte_qq<=6'b000000;
else if(~spi_busy & spi_sta | spi_busy & spi_end)
   byte_qq<=6'b000000;
else if(byte_en_tran)
   byte_qq<=byte_qq + 1'b1;

always@(spi_rwqq)
 case(spi_rwqq)
  4'b0000:byte_num=6'b000101;
  4'b0001:byte_num=6'b000101;
  4'b0010:byte_num=6'b000001;
  4'b0011:byte_num=6'b000001;
  4'b0100:byte_num=6'b000001;
  4'b0101:byte_num=6'b000001;
  4'b0110:byte_num=6'b000001;
  4'b0111:byte_num=6'b000001;
  4'b1000:byte_num=6'b000001;
  4'b1001:byte_num=6'b000000;
  4'b1010:byte_num=6'b000001;
  4'b1011:byte_num=6'b000010;  
  default:byte_num=6'b000000;
 endcase


always@(posedge clk or negedge rst)
if(~rst)
   byte_tran<=8'b00000000;
else if(~spi_busy)
  case(spi_rwqq)
  4'b0000:byte_tran=8'h2A;  //RX_ADDR_P0 通道0接收地址
  4'b0001:byte_tran=8'h30;  //TX_ADDR 发送地址
  4'b0010:byte_tran=8'h21;  //EN_AA 自动应答,禁止后可通信
  4'b0011:byte_tran=8'h22;  //EN_RXADDR 接收地址允许
  4'b0100:byte_tran=8'h24;  //SEPUT_RETR 建立自动重发
  4'b0101:byte_tran=8'h25;  //RF_CH 射频通道
  4'b0110:byte_tran=8'h26;  //RF_SERUP 射频寄存器
  4'b0111:byte_tran=8'h27;   //STATUS 状态寄存器
  4'b1000:byte_tran=8'h31;  //RX_PW_P0 接收通道0有效数据宽度
  4'b1001:byte_tran=8'hE2;   //FLUSH_RX 清除RX FIFO寄存器
  4'b1010:byte_tran=8'h20;   //配置寄存器  配置接收模式
  4'b1011:byte_tran=8'h61;  //R_RX_PAYLOAD读取存入寄存器
  default:byte_tran=8'h00;    //预防报错
 endcase
else if(byte_en_tran)
 case(byte_qq)
  6'b000000: case(spi_rwqq)
                 4'b0000:byte_tran=8'h57;  //RX_ADDR_P0 通道0接收地址
                 4'b0001:byte_tran=8'h57;  //TX_ADDR 发送地址
                 4'b0010:byte_tran=8'h01;  //EN_AA 自动应答,禁止后可通信
                 4'b0011:byte_tran=8'h01;  //EN_RXADDR 接收地址允许
                 4'b0100:byte_tran=8'h2F;  //SEPUT_RETR 建立自动重发
                 4'b0101:byte_tran=8'h28;  //RF_CH 射频通道
                 4'b0110:byte_tran=8'h07;  //RF_SERUP 射频寄存器
                 4'b0111:byte_tran=8'hFF;  //STATUS 状态寄存器
                 4'b1000:byte_tran=8'h02;  //RX_PW_P0 接收通道0有效数据宽度
                 4'b1001:byte_tran=8'hff;  //FLUSH_RX 清除RX FIFO寄存器
                 4'b1010:byte_tran=8'h0f;  //配置寄存器  配置接收模式
                 4'b1011:byte_tran=8'h00;  //R_RX_PAYLOAD读取存入寄存器
               default:byte_tran=8'h00;    //预防报错
             endcase
  6'b000001: case(spi_rwqq)
                 4'b0000:byte_tran=8'h68;  //RX_ADDR_P0 通道0接收地址
                 4'b0001:byte_tran=8'h68;  //TX_ADDR 发送地址
               default:byte_tran=8'h00;    //预防报错
             endcase
  6'b000010: case(spi_rwqq)
                 4'b0000:byte_tran=8'h94;  //RX_ADDR_P0 通道0接收地址
                 4'b0001:byte_tran=8'h94;  //TX_ADDR 发送地址
               default:byte_tran=8'h00;    //预防报错
             endcase
  6'b000011: case(spi_rwqq)
                 4'b0000:byte_tran=8'hA7;  //RX_ADDR_P0 通道0接收地址
                 4'b0001:byte_tran=8'hA7;  //TX_ADDR 发送地址
               default:byte_tran=8'h00;    //预防报错
             endcase
  6'b000100: case(spi_rwqq)
                 4'b0000:byte_tran=8'hE0;  //RX_ADDR_P0 通道0接收地址
// ... 以下代码略,完整源码请下载压缩包查看

代码文件(付费下载)

📥 付费后此处显示完整工程压缩包下载链接。
1、代码文件需要付费后才可见。
2、支付问题请联系微信公众号客服。
3、优质Verilog/VHDL代码资源,所见即所得。
Verilog/VHDL资源下载 » nRF24L01 无线收发控制 Verilog Quartus(2)

注册为本站会员,充值100得150,详情咨询客服

目前为止共有 *** 位优秀的会员加入! 立刻加入会员