当前文档版本为 v0.8.0,您可以访问当前页面的 开发中 版本以获取最近可能的更新。

PRF: NRF24L01 Transceiver

1 功能概述

此项目演示了nrf24l01普通型、增强型的收发功能。发射模式下每隔500ms发送一次数据,长度5个字节;接收模式下收到数据后打印出来,增强型自动回复ack。

2 环境要求

  • board: pan108xxb5_evb,核心板PAN1080 LB5A LQFP64。

  • uart: 显示串口输出log

  • PC串口工具:Panchip Serial Assistant V0.0.006.exe

3 编译和烧录

例程位置:zephyr\samples_panchip\proprietary_radio\sample_24l01

使用 ZAL 工具可以对其进行编译、烧录、打开 VS Code 调试等操作。关于 ZAL 工具的详细介绍请参考:Zephyr APP Launcher 工具介绍

4 演示说明

  1. 将PAN1080 EVB板串口接到PC的USB端口上。

  2. 用杜邦线将NRF24L01模块和PAN1080 EVB板的GPIO口进行连接,连接端口对应如下:

    PAN1080 EVB

    NRF24L01

    P43

    IRQ

    P44

    CE

    GND

    GND

    VBAT

    VCC

    P31

    MISO

    P30

    MOSI

    P02

    CS

    P03

    CLK

  3. 配置例程”sample_24l01”和PAN1080 2.4g例程的收发模式,分别对应如下:

    sample_24l01

    PAN1080

    TX_NORMAL_MODE

    prf_sample_rx(prj_24l01.conf)

    TX_ENHANCE_MODE

    prf_sample_rx(prj_24l01.conf)

    RX_NORMAL_MODE

    prf_sample_tx(prj_24l01.conf)

    RX_ENHANCE_MODE

    prf_sample_tx(prj_24l01.conf)

  4. 观察”sample_24l01”串口工具和PAN1080 2.4g例程串口工具的输出结果。

4.1 演示结果

  1. “sample_24l01”发射端输出结果:

    image

    发射端Log

  2. prf_sample_rx接收端输出结果:

    image

    接收端Log

5 开发说明

发射端每隔500ms发送一包2.4G数据。发送成功串口输出log”tx done”。

5.1 NRF24l01初始化

RX初始化:

uint8_t g_addr[4] = {0x71, 0x76, 0x41, 0x76};
uint8_t g_adr_width = 4;
uint8_t auto_ack = 0;
uint8_t rx_addr = 1;
uint8_t feature = 0x06;
uint8_t dy_pload = 0x3f;
uint8_t active = 0x73;
uint8_t g_pload_width = 5;
uint8_t channel = 50;
uint8_t phy = 1;
uint8_t crc = 0;
uint8_t irq_status = 0xff;

nrf24l01_ce_set(0);
nrf24l01_write_reg(TX_ADDR, g_addr, 4);
nrf24l01_write_reg(RX_ADDR_P0, g_addr, 4);

g_adr_width = g_adr_width - 2;
nrf24l01_write_reg(SETUP_AW, &g_adr_width, 1);
if (mode == 2) {                    /* enhance mode */
    auto_ack = 1;
    nrf24l01_write_reg(FEATURE, &feature, 1);
    nrf24l01_write_reg(DYNPD, &dy_pload, 1);
    nrf24l01_write_active(&active, 1);
    nrf24l01_write_reg(EN_AA, &auto_ack, 1);
} else {                            /* normal mode */
    nrf24l01_write_reg(EN_AA, &auto_ack, 1);
    nrf24l01_write_reg(RX_PW_P0, &g_pload_width, 1);
}
nrf24l01_write_reg(EN_RXADDR, &rx_addr, 1);
nrf24l01_write_reg(RF_CH, &channel, 1);

phy = (0x07 | (phy - 1) << 3);
nrf24l01_write_reg(RF_SETUP, &phy, 1);

if (crc == 0) {
    crc = 0x03;
} else {
    crc = (0x0B | (crc - 1) << 2);
}
nrf24l01_write_reg(CONFIG, &crc, 1);
nrf24l01_write_reg(STATUS, &irq_status, 1);
nrf24l01_ce_set(1);

TX初始化:

uint8_t g_addr[4] = {0x71, 0x76, 0x41, 0x76};
uint8_t g_adr_width = 4;
uint8_t auto_ack = 0;
uint8_t rx_addr = 0;
uint8_t retr = 0x00;
uint8_t feature = 0x06;
uint8_t dy_pload = 0x01;
uint8_t active = 0x73;
uint8_t channel = 50;
uint8_t phy = 1;
uint8_t crc = 0;
uint8_t irq_status = 0xff;

nrf24l01_ce_set(0);
nrf24l01_write_reg(TX_ADDR, g_addr, 4);
nrf24l01_write_reg(RX_ADDR_P0, g_addr, 4);

g_adr_width = g_adr_width - 2;
nrf24l01_write_reg(SETUP_AW, &g_adr_width, 1);

if (mode == 2) {                    /* enhance mode */
    auto_ack = 0x01;
    rx_addr = 0x01;
    retr = 0xf0;
    nrf24l01_write_reg(FEATURE, &feature, 1);
    nrf24l01_write_reg(DYNPD, &dy_pload, 1);
    nrf24l01_write_active(&active, 1);
}                                   /* normal mode */
nrf24l01_write_reg(EN_AA, &auto_ack, 1);
nrf24l01_write_reg(EN_RXADDR, &rx_addr, 1);
nrf24l01_write_reg(SETUP_RETR, &retr, 1);
nrf24l01_write_reg(RF_CH, &channel, 1);

phy = (0x07 | (phy - 1) << 3);
nrf24l01_write_reg(RF_SETUP, &phy, 1);

if (crc == 0) {
    crc = 0x02;
} else {
    crc = (0x0B | (crc - 1)<<2);
}
nrf24l01_write_reg(CONFIG, &crc, 1);
nrf24l01_write_reg(STATUS, &irq_status, 1);
nrf24l01_ce_set(1);

接收和发射可配置的参数如下:

Config

value

addr len

4(4byte)

addr

0x71, 0x76, 0x41, 0x76

rx payload len

5(normal mode)

channel

50(2450Mhz)

phy

1(1M phy)

crc

0(no crc)

5.2 中断处理

当有TX事件和RX事件时会 产生IRQ信号,触发GPIO产生中断,中断处理如下:

uint8_t state = 0;
uint8_t trx_fifo = 0xff;

nrf24l01_read_reg(STATUS, &state, 1);
nrf24l01_write_reg(STATUS, &state, 1);                  /* clear irq flag */
if(state == MAX_RT) {
    printk("tx enhance timeout\n");
    nrf24l01_write_flush_tx(&trx_fifo, 1);              /* clear tx fifo */
}

if((state & RX_DR) && (g_rx_mode > 0)) {
    if(g_rx_mode == 2) {
        static uint8_t ack_data[5] = {0x01};
        nrf24l01_write_flush_tx(&trx_fifo, 1);          /* clear tx fifo */
        nrf24l01_write_ack_pload(ack_data, sizeof(ack_data));
        ack_data[0]++;
    }
    uint8_t recv_data[32] = {0};
    uint8_t recv_len = 0;

    nrf24l01_read_pload_len(&recv_len, 1);
    nrf24l01_read_pload(recv_data, recv_len);
    nrf24l01_write_flush_rx(&trx_fifo, 1);              /* clear rx fifo */
    data_printk(recv_data, recv_len);
}

if((state & TX_DS) && (g_tx_mode > 0)) {
    if(g_tx_mode == 2) {
        uint8_t recv_data[32] = {0};
        uint8_t recv_len = 0;

        nrf24l01_read_pload_len(&recv_len, 1);
        nrf24l01_read_pload(recv_data, recv_len);
        nrf24l01_write_flush_rx(&trx_fifo, 1);          /* clear rx fifo */
        data_printk(recv_data, recv_len);
    } else {
        printk("tx done\n");
    }
}

普通型TX会打印”tx done”。

普通型RX会将收到的数据打印出来。

增强型TX会将收到的ack数据打印出来。

增强型RX收到数据后还会发送ack。

6 RAM/Flash资源使用情况

Memory region         Used Size  Region Size  %age Used
FLASH:       23496 B       256 KB      8.96%
SRAM:        5008 B        64 KB      7.64%