查看: 8528|回复: 6

nRF51822 AK II Radio模块 2.4Ghz 通信测试

[复制链接]
  • TA的每日心情

    2017-12-20 08:26
  • 签到天数: 449 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2014-3-10 22:34:10 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 ご★東☆ゞ 于 2014-3-10 22:34 编辑

          nRF51822板子到手后,工作较忙也没有时间学习和调试,决定从nRF51822最有特色的外设Radio开始学习。
    Radio系统框图:
    radio-frame.png

         系统主要包括2.4Ghz的收发器、数据包管理(地址匹配,数据组包/解包,CRC校验)和easyDMA模块,传输速度可选250kbps、1Mbps(蓝牙低功耗模式)和2Mbps。
    easyDMA与自动打包和解包,自动CRC产生和校验等功能相结合,使2.4Ghz无线通讯更简单、方便。
    数据包结构:
    radio-packet.png

         前导码、地址位和CRC校验位都被忽略,发送时硬件自动添加,接收时自动去除。地址位和PAYLOAD总是低位在前,而CRC数据高位在前,S0,LENGTH,S1和PAYLOAD可通过PCNF1寄存器配置数据顺序(大端还是小端)。S0,LENGTH和S1的大小可分别通过PCNF0寄存器中的S0S,LS和S1S配置,如果这三个任意一个小于8,S0,LENGTH和S1域的数据就是低位在前(LSB),如果它们都被定义成零,则这些位就在内存中被忽略,否则就被当做独立的字节进行存储。内存中实际需要关系的内容如下:
    radio-datainram.png

         包的长度 = S0+LENGTH+S1+PAYLOAD,最大不超过255个字节(MAXLEN<=255)。个人理解S0、Length和S1用于对不同无线芯片不同数据包的兼容,如芯片BK2421这一段就定义为6-bit payload length(对应Length)+2-bit PID+1-bit NO_ACK,如果让nRF51822与BK2421通信,首先要保证频段、对应通道的地址相同,为了让它们的数据包格式也应相同,只要设置S0=0,Length=6,S1=3既可
         地址段包括两部分:基本地址和前缀地址,基址通过寄存器BASE0和BASE1设置,前缀地址使用PREFIX0和PREFIX1配置,最多可配置8个逻辑地址,它们之间的对应关系如图
    radio-address.png
    如配置程序(地址长度设置为4,前缀地址1个,总共5个字节)
      NRF_RADIO->PREFIX0 = 0xC4C3C2E7UL;  // Prefix byte of addresses 3 to 0
      NRF_RADIO->PREFIX1 = 0xC5C6C7C8UL;  // Prefix byte of addresses 7 to 4
      NRF_RADIO->BASE0   = 0xE7E7E7E7UL;  // Base address for prefix 0
      NRF_RADIO->BASE1   = 0x00C2C2C2UL;  // Base address for prefix 1-7
    其实我们得到的逻辑地址0-7(即8个通道)的地址分别为
    LOGIC0:0xE7E7E7E7E7          LOGIC1:0xC200C2C2C2
    LOGIC2:0xC300C2C2C2         LOGIC3:0xC400C2C2C2
    LOGIC4:0xC800C2C2C2         LOGIC5:0xC700C2C2C2
    LOGIC6:0xC600C2C2C2         LOGIC7:0xC500C2C2C2
           nRF51822设置通道0(地址0xE7E7E7E7E7)发送,另一侧BK2421设置为接收,实现了两者的简单数据通信(单向)。BK2421隔500ms发送0x00,再隔500ms发送0xff,循环发送,更改官方程序led_radio_example_rx可让nRF51822板上LED交替闪烁。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2014-5-8 10:02
  • 签到天数: 14 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2014-3-11 11:26:25 | 显示全部楼层
    好文章!!!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2014-4-24 15:31
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2014-4-9 12:07:46 | 显示全部楼层
    //我写这函数的原因是51822和nrf24L01+地址bit位需要调校
    //每8个bit首尾对调,这寄存器真他妈SB设计
    uint8_t SB(int8_t inp)
    {
       int8_t num=0x00;
       int8_t i;
        for(i = 0; i < 8; i++)
        {
            num |= ((inp >> i) & 0x01) << (7 - i);     
        }
       return num;
    }


    // 无线地址设置
    //地址一共40个add_bit是add0~add39
    //在2401地址add0先写(add0,add1,add2......add39)

    //那2401和51822的地址关系如下
    // 2401[add0 :add7] =PREFIX0[bit7:bit0](add7,add6,add5,add4,add3,add2,add1,add0)
    // 2401[add8 :add15]=BASE0[bit31:bit24](add15,add14,add13,add12,add11,add10,add9,add8)
    // 2401[add16:add23]=BASE0[bit23:bit16](add23,add22,add21,add20,add19,add18,add17,add16)
    // 2401[add24:add31]=BASE0[bit15:bit8] (add31,add30,add29,add28,add27,add26,add25,add24)
    // 2401[add32:add39]=BASE0[bit7 :bit0] (add39,add38,add37,add36,add35,add34,add33,add32)

    //以上结论得出的2401地址是每8个bit首尾对调。以下是官方用的地址
    //const u8  ip[6]={0xE7,0xE7,0xE7,0xE7,0xE7,0x00};//发射地址  从[bit0~7] [bit8~15] [bit16~23] [bit24~31] [bit32~39]
    //const u8 ip0[6]={0xE7,0xE7,0xE7,0xE7,0xE7,0x00};//接收地址0 和51822通讯我调了(bit0先写)

    //const u8 ip1[6]={0xC2,0xC2,0xC2,0xC2,0xC2,0x00};//接收地址1 bit39~bit8为"0x43"(bit0先写)
    //const u8 ip2[6]={0xC3,0x00};//接收地址2 bit39~8和通道1共用,只写bit0~bit7
    //const u8 ip3[6]={0xC4,0x00};//接收地址3        通道2345只能设置char
    //const u8 ip4[6]={0xC5,0x00};//接收地址4        写的时候顺序是bit0~bit39
    //const u8 ip5[6]={0xC6,0x00};//接收地址5                只有bit0~7有用。接收地址6:0xC7 接收地址7:0xC8

    //无线电设置,2400MHz+,字节,速度0蓝牙1M 2M 250K。
    void radio_configure(uint8_t MHz,uint8_t LONGER,uint8_t quickly)//无线配置,准备和nrf24L01+通讯
    {
              
      //无线功率04:+4分贝,0:0分贝,FC:-4分贝,F8:-8分贝
            //    F4:-12分贝,F0:-16分贝,EC:-20分贝,D8:-30分贝
            NRF_RADIO->TXPOWER = (0x04<<0);//无线功率de分贝  
            NRF_RADIO->FREQUENCY = MHz&0x3F;//无线频率24MHz+2400MHz=2424MHz

            //无线速率:00:1Mbit,01:2Mbit,02:250Kbit,03:1Mbit(蓝牙)
            if(quickly==1)NRF_RADIO->MODE = (00<<0);//速率1Mbit
      else if(quickly==2)NRF_RADIO->MODE = (01<<0);//速率2Mbit
      else if(quickly==250)NRF_RADIO->MODE = (2<<0);//速率250Kbit

            else   NRF_RADIO->MODE = (01<<0);//速率1Mbit(蓝牙)

    //nrf24L01+和51822的地址关系如下
    // 2401[add0 :add7] =PREFIX0[bit7:bit0](add7,add6,add5,add4,add3,add2,add1,add0)
    // 2401[add8 :add15]=BASE0[bit31:bit24](add15,add14,add13,add12,add11,add10,add9,add8)
    // 2401[add16:add23]=BASE0[bit23:bit16](add23,add22,add21,add20,add19,add18,add17,add16)
    // 2401[add24:add31]=BASE0[bit15:bit8] (add31,add30,add29,add28,add27,add26,add25,add24)
    // 2401[add32:add39]=BASE0[bit7 :bit0] (add39,add38,add37,add36,add35,add34,add33,add32)

    // 通道3 到 0 的低字节
            NRF_RADIO->PREFIX0 =(SB(RX3[0])<<24) // 通道3的低字节地址C4 1100 0100/0010 0011 23
                               |(SB(RX2[0])<<16) // 通道2的低字节地址C3 1100 0011/1100 0011 C3
                               |(SB(RX1[0])<< 8) // 通道1的低字节地址C2 1100 0010/0100 0011 43
                               |(SB(RX0[0])<< 0);// 通道0的低字节地址E7 1110 0111/1110 0111 E7

    // 通道7 到 4 的低字节地址
            NRF_RADIO->PREFIX1 =(SB(RX7[0])<<24) // 通道7的低字节地址C8 1100 1000/0001 0011 13
                               |(SB(RX6[0])<<16) // 通道6的低字节地址C7 1100 0111/1110 0011 E3
                               |(SB(RX5[0])<< 8) // 通道5的低字节地址C6 1100 0110/0110 0011 63
                               |(SB(RX4[0])<< 0);// 通道4的低字节地址C5 1100 0101/1010 0011 A3

      NRF_RADIO->BASE0   = (SB(RX0[1])<<24)  // 通道0的高字节E7  1110 0111/1110 0111 E7
                          |(SB(RX0[2])<<16)
                                |(SB(RX0[3])<<8)
                                |(SB(RX0[4])<<0);

      NRF_RADIO->BASE1   = (SB(RX1[1])<<24)  // 通道1-7的高字节C2 1100 0010/0100 0011 43
                          |(SB(RX1[2])<<16)
                                |(SB(RX1[3])<<8)
                                |(SB(RX1[4])<<0);
                     
      NRF_RADIO->TXADDRESS = 0x00UL;      // 发射使用的通道号:0通道
      NRF_RADIO->RXADDRESSES = (1<<0);    // 接收使用的通道号:0通道  1111 1111

      // 配置包0的设置
      NRF_RADIO->PCNF0 = (0<<16)| //S1领域的长度
                         (0<<8) | //S0场的长度
                         (0<<0);  //长度字段中的比特数

      // 配置包1的设置
       NRF_RADIO->PCNF1 = (0<<25)| //效验位(0关,1开)
                          (1<<24)| //数据大小端(高低字节哪个先发 0低字节,1高字节)1为数组的最高位先发
                          (4<<16)| //通道0~7地址高字长度( nrf24L01+高低字节5字节:4个高字+1个低字)
                          (LONGER<<8) | //数据字节长度(255~1)32字节QxC
                          (LONGER<<0);  //硬件传输字节长度(255~1)32字节QxC

      // CRC 校验长度配置
      NRF_RADIO->CRCCNF = 2; // 校验长度 2个char
           
      if ((NRF_RADIO->CRCCNF & 0x03)== 2 )
      {
        NRF_RADIO->CRCINIT = 0xFFFFUL;      // 校验初始值
        NRF_RADIO->CRCPOLY = 0x11021UL;     // CRC poly: x^16+x^12^x^5+1
      }
      else if ((NRF_RADIO->CRCCNF & 0x03) == 1 )
      {
        NRF_RADIO->CRCINIT = 0xFFUL;        // 校验初始值
        NRF_RADIO->CRCPOLY = 0x107UL;       // CRC poly: x^8+x^2^x^1+1
      }
           
    //接收/发射寄存器是  NRF_RADIO->PACKETPTR       
    }




    //nrf51822发射函数
    uint8_t NRF51_TX()
    {
                    NRF_RADIO->EVENTS_READY = 0U;//收发模式切换完成指示灯。
        NRF_RADIO->TASKS_TXEN = 1U;//启动无线发射模式
        while (NRF_RADIO->EVENTS_READY == 0U);//等待收发模式切换完成

            // 启动数据传输
        NRF_RADIO->EVENTS_END  = 0U;//传输完成指示灯 ,关灯   
        NRF_RADIO->TASKS_START = 1U;//开始传输               
            while(NRF_RADIO->EVENTS_END == 0U) //等待传输结束
            {                                        
                IO_OUT(21,0);//传输等待led4
            }   
                                   
            NRF_RADIO->EVENTS_DISABLED = 0U;//无线电已关闭指示灯,关灯
            NRF_RADIO->TASKS_DISABLE   = 1U; // 关闭无线电
            while(NRF_RADIO->EVENTS_DISABLED == 0U)//等待无线电设备关闭
            {
                // Do nothing.
            }
                                   
         return 1;
    }


    //nrf51822接收函数
    uint8_t NRF51_RX()
    {
                  uint8_t CRC=0;
                              NRF_RADIO->EVENTS_READY = 0U; //收发模式转换完成  标志位      
            NRF_RADIO->TASKS_RXEN   = 1U; //启动接收模式
            while(NRF_RADIO->EVENTS_READY == 0U); //等待收发模式转换完成(指示灯)
            NRF_RADIO->EVENTS_END  = 0U;//传输完成(指示灯)
            NRF_RADIO->TASKS_START = 1U; // 开始传输
           
                                                             IO_OUT(23,1);//接收指示灯
                      nrf_delay_ms(3);//接收空气中的无线信号
    //没收到数据                               
            while(NRF_RADIO->EVENTS_END == 0U)//等待传输完成(指示灯)
               {
                                                     //一直没收到数据
                                                      NRF_RADIO->EVENTS_DISABLED = 0U;//无线关闭   标志位
                  NRF_RADIO->TASKS_DISABLE   = 1U;// 关闭无线设备
                  while(NRF_RADIO->EVENTS_DISABLED == 0U);//等待设备关闭
                                                      return 0;
               }
                                             
    //成功收到数据
                                    if (NRF_RADIO->CRCSTATUS == 1U)//如果CRC校验正确
                                       {    CRC=1;   }
                                    else    CRC=0;
                                             
            NRF_RADIO->EVENTS_DISABLED = 0U;//无线关闭   标志位
            NRF_RADIO->TASKS_DISABLE   = 1U;// 关闭无线设备
            while(NRF_RADIO->EVENTS_DISABLED == 0U);//等待设备关闭
            if(CRC==1)
                                      {         
                                                    return 1;//接收成功
                                            }
                                    return 0;//由于CRC校验错误,所以接收失败       
    }   
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2014-4-24 15:31
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2014-4-10 16:06:03 | 显示全部楼层
    楼主可否详细讲下S0+LENGTH+S1的用法。和以下的
    __IO uint32_t  CRCCNF;                            /*!< CRC配置开关。                   */

      __IO uint32_t  CRCPOLY;                           /*!< CRC多项式。              */

      __IO uint32_t  CRCINIT;                           /*!< CRC的初始值。            */

      __IO uint32_t  TEST;                              /*!< 测试功能使能寄存器。         */

      __IO uint32_t  TIFS;                              /*!< 帧间间隔微秒。               */

      __IO uint32_t  RSSISAMPLE;                        /*!< 采集到的RSSI样品值。 */

      __I  uint32_t  RESERVED7;

      __I  uint32_t  STATE;                             /*!< 查看当前无线电状态。       */

      __IO uint32_t  DATAWHITEIV;                       /*!< 数据校验初始值。           */

      __I  uint32_t  RESERVED8[2];

      __IO uint32_t  BCC;                               /*!< 位计数器比较。             */

      __I  uint32_t  RESERVED9[39];

      __IO uint32_t  DAB[8];                            /*!< 设备地址基地段。        */

      __IO uint32_t  DAP[8];                            /*!< 设备地址的前缀。        */

      __IO uint32_t  DACNF;                             /*!< 设备地址匹配配置。      */

      __I  uint32_t  RESERVED10[56];

      __IO uint32_t  OVERRIDE0;                         /*!< 修剪值覆盖寄存器0。          */

      __IO uint32_t  OVERRIDE1;                         /*!< 修剪值覆盖寄存器1。          */

      __IO uint32_t  OVERRIDE2;                         /*!< 修剪值覆盖寄存器2。          */

      __IO uint32_t  OVERRIDE3;                         /*!< 修剪值覆盖寄存器3。          */

      __IO uint32_t  OVERRIDE4;                         /*!< 修剪值覆盖寄存器4。 总开关位  */

      __I  uint32_t  RESERVED11[561];

      __IO uint32_t  POWER;                             /*!< 外设的功率控制。      */

    回复 支持 反对

    使用道具 举报

    该用户从未签到

    发表于 2014-4-14 15:34:57 | 显示全部楼层
    看来都是研究底层的东东啊,有经验及时总结啊~~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2014-4-24 15:31
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2014-4-22 00:47:50 | 显示全部楼层
    我找到S0+LENGTH+S1的意思了。无线模块在空中传输的数据:触发信号,地址(高字,低字),xx,数据,CRC校验。      S0+LENGTH+S1是指的xx部分。那么S0+LENGTH+S1最大长度是17bit。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2014-4-24 15:31
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2014-5-4 12:17:57 | 显示全部楼层
    2401+ACK模式。空中的数据包0x55或0xaa是触发信号(前导码)地址3~5字节,标志位(9bit)数据(1~32字节)CRC校验(0~2字节)
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /5 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-12-22 09:02 , Processed in 0.175205 second(s), 28 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.