OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3392|回复: 7

使用中断方式在一块战舰板上进行两个 NRF24L01 的通信实验

[复制链接]

8

主题

124

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
212
金钱
212
注册时间
2015-8-1
在线时间
7 小时
发表于 2015-8-22 10:44:48 | 显示全部楼层 |阅读模式
<p>
        昨天发了个求助帖子,是关于 SPI1 使用 NRF24L01 的问题(<a href="http://www.openedv.com/posts/list/58288.htm" target="_blank">http://www.openedv.com/posts/list/58288.htm</a>)。最后终于搞好。
</p>
<p>
        下一步就是想进行 2.4G 无线通信实验了。战舰的板子也准备了两块,准备弄这个实验。两块板子靓照
</p>
<p>
       


</p>
<p>
        <br />
</p>
<p>
        但是,感觉两块板子调试起来比较费劲。所以就像尝试下在一块 上进行2.4G收发实验。
</p>
<p>
        由于昨天已经在 SPI1 上连接了一个 NRF24L01,所以,在 SPI3 上连接另一个 NRF24L01。具体连接方式如下:
</p>
<p>
        <br />
</p>
<p>
        <span> </span>
</p>
<p>
        <span><span>SPI1:NRF24L01(实验中用于发射)</span></span>
</p>
<p>
        <span> </span>
</p>
<p>
        <span><span>C00:SPI1 CE(3)</span></span>
</p>
<p>
        <span> </span>
</p>
<p>
        <span><span>C02:SPI1 CSN(4)</span></span>
</p>
<p>
        <span> </span>
</p>
<p>
        <span><span>C08:SPI1 IRQ(8)</span></span>
</p>
<p>
        <span> </span>
</p>
<p>
        <span><span>A05:SPI1 SCK(5)</span></span>
</p>
<p>
        <span> </span>
</p>
<p>
        <span><span>A06:SPI1 MISO(7)</span></span>
</p>
<p>
        <span> </span>
</p>
<p>
        <span><span>A07:SPI1 MOSI(6)</span></span>
</p>
<p>
        <span> </span>
</p>
<p>
        <span><span><br />
</span></span>
</p>
<p>
        <span> </span>
</p>
<p>
        <span><span>SPI3:NRF24L01(实验中用于接收)</span></span>
</p>
<p>
        <span> </span>
</p>
<p>
        <span><span>C03:SPI3 CE(3)</span></span>
</p>
<p>
        <span> </span>
</p>
<p>
        <span><span>C04:SPI3 CSN(4)</span></span>
</p>
<p>
        <span> </span>
</p>
<p>
        <span><span>C09:SPI3 IRQ(8)</span></span>
</p>
<p>
        <span> </span>
</p>
<p>
        <span><span>B03:SPI3 SCK(5) </span></span>
</p>
<p>
        <span> </span>
</p>
<p>
        <span><span>PB04:SPI3 MISO(7)</span></span>
</p>
<p>
        <span> </span>
</p>
<p>
        <span><span>PB05:SPI3 MOSI(6)</span></span>
</p>
<p>
        <span> <br />
</span>
</p>
<p>
        现场连线情况(看个大概即可)
</p>
<p>
       


</p>
有软件开发经验,从0硬件基础学习STM32开发。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

8

主题

124

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
212
金钱
212
注册时间
2015-8-1
在线时间
7 小时
 楼主| 发表于 2015-8-22 10:57:33 | 显示全部楼层
<p>
        实验思路:<br />
1、在 main 中每两秒发射一次数据,调试输出发射的数据内容。<br />
2、在发射模块的 IRQ 中断(PC8)中,对发射情况进行调试输出。<br />
3、在接收模块的 IRQ 中断(PC9)中,对接收情况进行调试输出,并调试输出接收的内容。<br />
经过调试输出判断,NRF24L01 先进行发射,如果成功,会先在接收端产生 RX_OK 中断,然后是发送方产生 TX_OK 中断。如果发送不成功,仅在发送端产生 MAX_TX 中断。
</p>

<p>相关代码
</p>
        <div   style="background-color:#E8E8E8;">
[mw_shl_code=c,true]int main(void)
{
  _Init();
  while (1)
  {
    static u32 i = 0;
    u8 lTxBuffer[33];

    i++;
    sprintf((char *)lTxBuffer, "%032d", i);
    oDebug("RF1 =&gt; [%s]\r\n", lTxBuffer);
    WIRELESS_SendPacket(WIRELESS1, lTxBuffer);

    LED1 = !LED1;
   
    Wait_s(2);
  }
}[/mw_shl_code]
        </div>
<p>
NRF24L01 中为配合中断方式,做了些调整,代码如下
</p>
        <div   style="background-color:#E8E8E8;">
[mw_shl_code=c,true]static bool WIRELESS1_IsIrqHandled;
static bool WIRELESS2_IsIrqHandled;
...

void WIRELESS_IrqHandled(u8 aWhichWireless)
{
  switch(aWhichWireless)
  {
    case WIRELESS1: WIRELESS1_IsIrqHandled = TRUE; break;
    case WIRELESS2: WIRELESS2_IsIrqHandled = TRUE; break;
  }
}

void WIRELESS_SendPacket(u8 aWhichWireless, u8 *aBuffer)
{
  switch(aWhichWireless)
  {
    case WIRELESS1: WIRELESS1_CE = 0; WIRELESS1_IsIrqHandled = FALSE; break;
    case WIRELESS2: WIRELESS2_CE = 0; WIRELESS2_IsIrqHandled = FALSE; break;
  }
  WIRELESS_WriteBuffer(aWhichWireless, NFR_WRITE_TX_PAYLOAD, aBuffer, WIRELESS_TX_PAYLOAD_WIDTH);
  switch(aWhichWireless)
  {
    case WIRELESS1: WIRELESS1_CE = 1; do { Wait_us(10);} while(WIRELESS1_IsIrqHandled == FALSE); break;
    case WIRELESS2: WIRELESS2_CE = 1; do { Wait_us(10);} while(WIRELESS2_IsIrqHandled == FALSE); break;
  }

  return;   
}[/mw_shl_code]
        </div>
        <p>
                中断处理代码如下:
        </p>
                <div   style="background-color:#E8E8E8;">
[mw_shl_code=c,true]void EXTI9_5_IRQHandler(void)
{
  // WIRELESS1 触发的中断
  if(EXTI_GetITStatus(EXTI_Line8) == SET)
  {
    u8 lStatus = WIRELESS_ReadReg(WIRELESS1, NRF_READ_REG + NFR_STATUS);  // 读取状态寄存器的值

    oDebug("RF1 =&gt; ");
    if(lStatus &amp; NFR_MAX_TX)                                 // 达到最大重发次数
    {
      WIRELESS_WriteReg(WIRELESS1, NFR_FLUSH_TX, 0xFF);      // 清除TX FIFO寄存器
      oDebug("MAX_TX\r\n");
    }
   
    if(lStatus &amp; NFR_TX_OK)                                  // 发送完成
    {
      oDebug("TX_OK\r\n");
    }
  
    if(lStatus &amp; NFR_RX_OK)                                  // 接收完成
    {
      oDebug("RX_OK\r\n");
    }
   
    // 清除 RX_DS,TX_DS 或 MAX_RT 中断标志
    WIRELESS_WriteReg(WIRELESS1, NRF_WRITE_REG + NFR_STATUS, lStatus);

    WIRELESS_IrqHandled(WIRELESS1);

    EXTI_ClearITPendingBit(EXTI_Line8);
  }
  
  if(EXTI_GetITStatus(EXTI_Line9) == SET)
  {
    u8 lStatus = WIRELESS_ReadReg(WIRELESS2, NRF_READ_REG + NFR_STATUS);  // 读取状态寄存器的值

    oDebug("RF2 =&gt; ");
    if(lStatus &amp; NFR_MAX_TX)                                 // 达到最大重发次数
    {
      WIRELESS_WriteReg(WIRELESS2, NFR_FLUSH_TX, 0xFF);      // 清除TX FIFO寄存器
      oDebug("MAX_TX\r\n");
    }
   
    if(lStatus &amp; NFR_TX_OK)                                  // 发送完成
    {
      oDebug("TX_OK\r\n");
    }
  
    if(lStatus &amp; NFR_RX_OK)                                  // 接收完成
    {
      u8 lRxBuffer[33];
      oDebug("RX_OK");

      WIRELESS_ReadBuffer(WIRELESS2, NFR_READ_RX_PAYLOAD, lRxBuffer, WIRELESS_RX_PAYLOAD_WIDTH); // 读取数据
      WIRELESS_WriteReg(WIRELESS2, NFR_FLUSH_RX, 0xFF);      // 清除RX FIFO寄存器
      
      lRxBuffer[32] = 0;
      oDebug("[%s]\r\n", lRxBuffer);
    }

    // 清除 RX_DS,TX_DS 或 MAX_RT 中断标志
    WIRELESS_WriteReg(WIRELESS2, NRF_WRITE_REG + NFR_STATUS, lStatus);

    WIRELESS_IrqHandled(WIRELESS2);
   
    EXTI_ClearITPendingBit(EXTI_Line9);
  }
}[/mw_shl_code]
                </div>
                <p>
                        <br />
                </p>
有软件开发经验,从0硬件基础学习STM32开发。
回复 支持 反对

使用道具 举报

8

主题

124

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
212
金钱
212
注册时间
2015-8-1
在线时间
7 小时
 楼主| 发表于 2015-8-22 11:03:53 | 显示全部楼层
<p>
        用自己写的定制的串口助手查看输出情况,传输中有丢包的情况,具体问题还要分析。但是已经可以正常传输数据,单板双2.4G实验算是成功吧。
</p>
<p>
       


</p>
有软件开发经验,从0硬件基础学习STM32开发。
回复 支持 反对

使用道具 举报

3

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2015-7-23
在线时间
0 小时
发表于 2015-8-22 11:33:25 | 显示全部楼层
&nbsp;赞一个,我是弄了双板,4个NRF24L01才可以双向通信,不过这样太占引脚了。如果只用2个NRF,就只能单向。(个人编程能力有限)

回复 支持 反对

使用道具 举报

8

主题

124

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
212
金钱
212
注册时间
2015-8-1
在线时间
7 小时
 楼主| 发表于 2015-8-22 15:14:51 | 显示全部楼层
回复【4楼】飞翼:
<br>---------------------------------
<br>感觉如果实现双工,应该是半双工,只要安排好通信双方的收发顺序,对模块的发送接收模式进行实时切换,应该就可以一对儿进行双向通信了。
有软件开发经验,从0硬件基础学习STM32开发。
回复 支持 反对

使用道具 举报

3

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2015-7-23
在线时间
0 小时
发表于 2015-8-22 15:17:41 | 显示全部楼层
回复【5楼】dragon7799:
<br>---------------------------------
<br>调试了好多次了,中间卡住死机了多次,我的思路和你是一样的。真不好调。网上有种是用ACK&nbsp;With&nbsp;payload&nbsp;模式实现双向数据通信,不用手动切换收发状态,NRF24L01自动完成收发切换。但是我并不会用,有时间再探讨吧
回复 支持 反对

使用道具 举报

8

主题

124

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
212
金钱
212
注册时间
2015-8-1
在线时间
7 小时
 楼主| 发表于 2015-8-22 16:01:34 | 显示全部楼层
回复【6楼】飞翼:
<br>---------------------------------
<br>
<br>刚刚发现了一个现象就是这两个天线离的近了,比如20公分以内,几乎总丢包,挪到40公分左右,基本不丢包了。不知你有这个现象么。
有软件开发经验,从0硬件基础学习STM32开发。
回复 支持 反对

使用道具 举报

3

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2015-7-23
在线时间
0 小时
发表于 2015-8-22 16:23:09 | 显示全部楼层
回复【7楼】dragon7799:
<br>---------------------------------
<br>有,同你一样的情况,稍微远一点就没事
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-9-29 23:26

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表