Nordic NRF24L01+与NRF52832通信两个问题(地址设短、数据左移)

环境:Nordic NRF24L01+发送数据,无需自动应答;NRF52832接收收据。

问题一:NRF24L01+发送地址与NRF52832接收地址

一般情况下可以如下设置:

NRF24L01+发送地址设置:

void SPI1_Write_Buf(uint8_t address, uint8_t *pBuf, uint8_t datalen)
{
    uint8_t tmp,i;
    
    CSN_L;
    
    SPI1_DR = address;//写入需要操作的寄存器地址,
    while(!(SPI1_SR_RXNE));
    tmp = SPI1_DR;   //读取数据,仅仅是为了清除标志位
    while(!(SPI1_SR_TXE));//等待发送寄存器为空
    
    for(i=0;i<datalen;i++)
    {
         SPI1_DR = pBuf[i];
         while(!(SPI1_SR_TXE));
    }
    
    CSN_H;
}

#define TX_ADR_WIDTH  5;  //发射地址长度
const uint8_t TX_ADDRESS[TX_ADR_WIDTH] = {0x11, 0x22, 0x33, 0x44, 0x55};  //发射地址

SPI1_Write_Buf(SPI_WRITE_REG+TX_ADDR, (uint8_t*)TX_ADDRESS, TX_ADR_WIDTH);

NRF52832接收地址设置:

#define RX_ADR_LENGTH  5;  //接收地址长度
const uint8_t addr_prefix[1] = {0x11};
const uint8_t base_addr_0[RX_ADR_LENGTH -1] = {0x22, 0x33, 0x44, 0x55};

nrf_esb_set_address_length(RX_ADR_LENGTH);
nrf_esb_set_prefixes(addr_prefix, 1);
nrf_esb_set_base_address_0(base_addr_0);

但是当把地址长度改为4时(如下),就会出现问题,NRF52832接收不到数据,这是因为地址设置错误。

//NRF24L01+发射地址
#define TX_ADR_WIDTH  4;  //发射地址长度
const uint8_t TX_ADDRESS[TX_ADR_WIDTH] = {0x11, 0x22, 0x33, 0x44};  //发射地址

//NRF52832接收地址
#define RX_ADR_LENGTH  4;  //接收地址长度
const uint8_t addr_prefix[1] = {0x11};
const uint8_t base_addr_0[RX_ADR_LENGTH -1] = {0x22, 0x33, 0x44};

看一下NRF24L01+的TX_ADDR寄存器说明:

地址参数复位值类型描述
0x10TX_ADDR39:00xE7E7E7E7E7R/W发送地址(先写低字节)

当把4个字节的地址写入TX_ADDR寄存器前后变化是:

//TX_ADDR写入前:
[39:0] = {0xE7, 0xE7, 0xE7, 0xE7, 0xE7}

//TX_ADDR写入后:
[39:0] = {0xE7, 0x44, 0x33, 0x22, 0x11}

但是当NRF24L01+发射时,却取用4个高字节。这意味着NRF52832按着4个高字节的地址设置接收地址才能接收到数据,如下:

//NRF24L01+实际发射地址:
[39:8] = {0xE7, 0x44, 0x33, 0x22}

//NRF52832应该接收地址:
const uint8_t addr_prefix[1] = {0x22};
const uint8_t base_addr_0[RX_ADR_LENGTH -1] = {0x33, 0x44, 0xE7}

如要纠正上述问题,可以在写入寄存器时候,把低位的先写一个字节0xE7,然后再写4位实际地址,把NRF24L01+设置函数改为如下:

void SPI1_Write_ADDR(uint8_t address, uint8_t *pBuf, uint8_t datalen)
{
    uint8_t tmp,i;
    
    CSN_L;
    
    SPI1_DR = address;//写入需要操作的寄存器地址,
    while(!(SPI1_SR_RXNE));
    tmp = SPI1_DR;   //读取数据,仅仅是为了清除标志位
    while(!(SPI1_SR_TXE));//等待发送寄存器为空
    
    //先写入0xE7占位
    if(TX_ADR_WIDTH==4)
    {
        SPI1_DR=0xE7;
        while(!(SPI1_SR_TXE));
    }
   
    for(i=0;i<datalen;i++)
    {
         SPI1_DR = pBuf[i];
         while(!(SPI1_SR_TXE));
    }
    
    CSN_H;
}

#define TX_ADR_WIDTH  4;  //发射地址长度
const uint8_t TX_ADDRESS[TX_ADR_WIDTH] = {0x11, 0x22, 0x33, 0x44};  //发射地址

SPI1_Write_ADDR(SPI_WRITE_REG+TX_ADDR, (uint8_t*)TX_ADDRESS, TX_ADR_WIDTH);

这时NRF52832接收地址才是如下:

#define RX_ADR_LENGTH  4;  //接收地址长度
const uint8_t addr_prefix[1] = {0x11};
const uint8_t base_addr_0[RX_ADR_LENGTH -1] = {0x22, 0x33, 0x44};

nrf_esb_set_address_length(ADDRESS_LENGTH);
nrf_esb_set_prefixes(addr_prefix, 1);
nrf_esb_set_base_address_0(base_addr_0);

问题二:发送与接收过程中产生数据左移1bit

当NRF24L01+向NRF52832发送数据时候,会循环左移1bit,即从低字节的高位开始所有bit左移1bit,低字节的高位bit填充到高字节的低位空缺,如下:

//NRF24L01+发送数据{0x99, 0x88, 0x77}
uint8_t TX_DATA[3] = {0b10011001, 0b10001000, 0b01110111};

//NRF52832收到的数据{0x33, 0x10, 0xef},即把TX_DATA[1][8]=1填充到RX_DATA[2][0]
uint8_t RX_DATA[3] = {0b00110011, 0b00010000, 0b11101111};

解决的办法有两种,一种是在NRF52832接收时循环右移动回来,另外一种在NRF24L01+发送前先循环右移。两种操作都差不多了,视具体情况而采用哪种,参考代码如下:

uint8_t tbit = TX_DATA[2]<<7;
TX_DATA[2] = TX_DATA[2]>>1 | TX_DATA[1]<<7;
TX_DATA[1] = TX_DATA[1]>>1 | TX_DATA[0]<<7;
TX_DATA[0] = TX_DATA[0]>>1 | tbit;
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值