在线情况
楼主
  • 头像
  • 级别
    • 积分30
    • 经验3160
    • 文章148
    • 注册2008-03-04
    nRF2401的C51驱动程序[已经调试通过]
    [CODE]
    /////////////////////////////////////////////////////////////////////
    //  Desc:    Demo App for RF2401 Module
    //      Vender:  http://www.newmsg.com
    //  Date:    2007-3-12
    //  Update   2007-9-8
    ////////////////////////////////////////////////////////////////////
    //这是我购买在nRF2401时从开发商中得到的代码。我已经验证过。
    //供大家学习用,只要修改下代码就可以应用到其他的单片机。
    //这个程序是一个半双工的通信模式.
    //
    //
    #include <reg51.h>
    // 常量定义
    #define uchar unsigned char
    #define uint  unsigned int

    #define BYTE_BIT0      0x01
    #define BYTE_BIT1      0x02
    #define BYTE_BIT2      0x04
    #define BYTE_BIT3      0x08
    #define BYTE_BIT4      0x10
    #define BYTE_BIT5      0x20
    #define BYTE_BIT6      0x40
    #define BYTE_BIT7      0x80

    // <RF2401_Pins 对应引脚> , 具体细节请参考相关电路图 NewMsg_RFDemo2401.SchDoc(用PortelDXP打开)
    sbit PWR_UP      = P1^6;
    sbit CE            = P1^2;
    //      sbit DR2      = P3^5;            //暂时没有用到
    //      sbit CLK2      = P3^4;
    //      sbit OUT2      = P3^3;
    sbit CS            = P1^1;
    sbit DR1      = P1^0;
    sbit CLK1      = P3^7;
    sbit DATA      = P3^3;

    sbit LED0      = P3^4;
    sbit LED1      = P3^5;
    sbit KEY0      = P3^0;
    sbit KEY1      = P3^1;

    /**************************************************************
         RF2401 Configuration                                    
         保存2401的配置信息                                    
    **************************************************************/
    /*=====<RF-Configuration-Register 配置信息>=====*/
    //芯片测试用,无需修改
    #define TEST_2            0x8E      //MSB      D143~D136
    #define TEST_1            0x08      //      D135~D128
    #define      TEST_0            0x1C      //      D127~D120

    /* 注意: DATAx_W + ADDRx_W + CRC 的值必须小于256 !  单个数据包的大小必须小于32字节(256位) */
    #define DATA2_W            0x10      //2字节      //频道2 数据长度(单位:Bit)
    #define DATA1_W            0xE0      //28字节      //频道1 数据长度(单位:Bit)

    //      0xE0 = 224
    //16bit Address + 224bit(28byte)Data + 16bit CRC = 256bit

    /* 注意:2401忽略ADDR中超过ADDR_W设定宽度的那些位,同时地址不能全部设置为0 */
    //频道2 接收地址(当前模块地址)
    #define ADDR2_4            0x00
    #define ADDR2_3            0x1c
    #define ADDR2_2            0xcc
    #define ADDR2_1            0xcc                                                
    #define ADDR2_0            0xcc
    //频道1 接收地址
    #define ADDR1_4            0x00
    #define ADDR1_3            0xcc
    #define ADDR1_2            0xcc
    #define ADDR1_1            0xcc
    #define ADDR1_0            0xcc

    #define ADDR_W            0x10            //2字节      //接收地址宽度(单位:Bit)
    #define CRC_L            0x1            //CRC模式 0:8位      1:16
    #define CRC_EN            0x1            //CRC校验启用

    #define RX2_EN            0x0            //双频道功能启用
    #define CM                  0x1            //0:Direct mode      1:ShockBurst mode
    #define RFDR_SB            0x0            //0:250kbps      1:1Mbps
    #define XO_F            0x3            //16M            //nRF2401晶振频率
    #define RF_PWR            0x3            //信号发射功率

    #define RF_CH            0x2            //Channel RF 频率
    #define RXEN            0x0//DEF_RXEN      //0:Tx      1:Rx
    //程序会重新设置此项参数

    //-----------------------------------------------------------
    //<将设置信息组合成每个字节的数据信息,此区域无需修改>
    #define RFConfig_Byte0      TEST_2
    #define RFConfig_Byte1      TEST_1
    #define RFConfig_Byte2      TEST_0
    #define RFConfig_Byte3      DATA2_W
    #define RFConfig_Byte4      DATA1_W
    #define RFConfig_Byte5      ADDR2_4
    #define RFConfig_Byte6      ADDR2_3
    #define RFConfig_Byte7      ADDR2_2
    #define RFConfig_Byte8      ADDR2_1
    #define RFConfig_Byte9      ADDR2_0
    #define RFConfig_Byte10      ADDR1_4
    #define RFConfig_Byte11      ADDR1_3
    #define RFConfig_Byte12      ADDR1_2
    #define RFConfig_Byte13      ADDR1_1
    #define RFConfig_Byte14      ADDR1_0
    #define RFConfig_Byte15      (ADDR_W<<2 | CRC_L<<1 | CRC_EN)
    #define RFConfig_Byte16      (RX2_EN<<7 | CM<<6    | RFDR_SB<<5 | XO_F <<2 | RF_PWR)
    #define RFConfig_Byte17      (RF_CH<<1  | RXEN)

    //------------------------------------------------------------
    //通过宏定义将18字节的寄存器参数按照各个功能分解,以便于参数的调整
    unsigned char code nRF2401_Conf[18] ={
         RFConfig_Byte0,      
         RFConfig_Byte1,      
         RFConfig_Byte2,      
         RFConfig_Byte3,      
         RFConfig_Byte4,
         RFConfig_Byte5,      
         RFConfig_Byte6,      
         RFConfig_Byte7,      
         RFConfig_Byte8,      
         RFConfig_Byte9,
         RFConfig_Byte10,
         RFConfig_Byte11,
         RFConfig_Byte12,
         RFConfig_Byte13,
         RFConfig_Byte14,
         RFConfig_Byte15,
         RFConfig_Byte16,
         RFConfig_Byte17
    };

    //------------------------------------------------------------
    /**************************************************************
    *      nRF2401 Tx/Rx functions                              
    *
    *      void Delay100(void);
    *      void Config2401(void);      //配置2401,写入初始化设置
    *      void SetTxMode(void);            //设置为发送模式
    *      void SetRxMode(void);            //设置为接收模式
    *      void nRF2401_TxPacket(unsigned char TxBuf[]);
    *      //发送TxBuf[]内的数据 长度由 DATA1_W 决定
    *      unsigned char nRF2401_RxPacket(unsigned char *RxBuf);
    *      //检查是否有数据需要接受 如果有,则保存至RxBuf[]
    *         //返回值 0:没有接收到数据      1:接收到数据
    **************************************************************/

    //16M晶振 600us左右
    void Delay100(void)
    {
         unsigned int i;
         for(i=0;i<100;i++);
    }

    void Delay(uchar n)
    {
         uint i;
         while(n--)
         for(i=0;i<80;i++);      
    }

    bdata unsigned  char DATA_BUF;
    #define DATA7      ((DATA_BUF & BYTE_BIT7) != 0)
    #define DATA0   ((DATA_BUF & BYTE_BIT0) != 0)
    /**********************************************************
    *      2401数据传输接口
    *      详细内容参见2401手册<Configuration mode timing>章节
    **********************************************************/
    unsigned char Spi_ByteRead(void)
    {
         unsigned char i = 0;
         for (i=0; i<8; i++)
         {
               DATA_BUF = DATA_BUF << 1;
               CLK1 = 1;
               DATA = 1;      //设置为输入状态
               if (DATA)      //读取最高位,保存至最末尾,通过左移位完成整个字节
               {
                     DATA_BUF |= BYTE_BIT0;
               }
               else
               {
                     DATA_BUF &= ~BYTE_BIT0;
               }
               CLK1 = 0;
          }

          return DATA_BUF;
    }

    void Spi_ByteWrite(unsigned char send)
    {
         unsigned char i;

         DATA_BUF = send;

         CLK1 = 0;

         for (i=0; i<8; i++)
         {
               
              if (DATA7)      //总是发送最高位
           {
                   DATA = 1;
            }
           else
             {
                DATA = 0;
             }
               CLK1 = 1;
               DATA_BUF = DATA_BUF << 1;
               CLK1 = 0;
         }
    }

    /*      <RF2401配置寄存器的写入方式>
    NOTE.
    On the falling edge of CS, the nRF2401A updates the number of bits actually shifted
    in during the last configuration.
    Ex:
    If the nRF2401A is to be configured for 2 channel RX in ShockBurst., a total of 120
    bits must be shifted in during the first configuration after VDD is applied.
    Once the wanted protocol, modus and RF channel are set, only one bit (RXEN) is
    shifted in to switch between RX and TX.
    */
    void Config2401(void)
    {
         unsigned int i = 0;
         unsigned char variablel;

         //RF2401进入配置方式
         CS = 0;
         CE = 0;
         PWR_UP = 1; //上电

         for(i=0; i<20; i++)
         {
               Delay100();
         }

         CS = 1;
         DATA = 0;
         CLK1 = 0;

         Delay100();//-----
       /*
         for(i=0; i<20; i++)
         {
               Delay100();
         }
       */
         //PWR_DWN -> Configuration_mode      Delay_3ms     

         for(i=0; i<18; i++)
         {
               variablel = nRF2401_Conf[I];
               Spi_ByteWrite(variablel);
         }

         Delay100();      // configuration mode -> stand by mode ??

         CS = 0; //CS置低使配置有效
         Delay100();
    }

    void SetTxMode(void)
    {
         //设置为配置模式
         PWR_UP = 1;
         CE = 0;
         CS = 1;

         Delay100();

         //配置寄存器0字节RXEN 设置为0:发送模式
         DATA = 0;
         CLK1=1;
         CLK1=0;

         //设置为Activemodes(Tx)
         CS=0;
         CE=1;
         Delay100();
    }

    void SetRxMode(void)
    {
         Delay100();
         //设置为配置模式
         PWR_UP = 1;
         CE=0;
         CS=1;
         Delay100(); /////----
         //配置寄存器0字节RXEN 设置为1:接收模式
         DATA = 1;
         CLK1 = 1;
         CLK1 = 0;

         //设置为Activemodes(Rx)
         CS=0;
         CE=1;
         Delay100();
    }

    //接收方通道硬件地址
    unsigned char TxAddress[]={0xcc,0xcc,0xcc,0xcc};

    //nRF2401数据发送函数定义如下:
    void RF2401_TxPacket(unsigned char TxBuf[])
    {
         int i;
         unsigned char variable2;
         CE=1;
         Delay100();
         for(i=0;i< (ADDR_W/8);i++)      //写入接收地址(按字节对齐)
         {
               variable2=TxAddress[I];
               Spi_ByteWrite(variable2);
         }

         for(i=0;i<(DATA1_W/8);i++)      //写入需要发送的数据(按字节对齐)
         {
               variable2=TxBuf[I];
               Spi_ByteWrite(variable2);
         }

         CE=0; //CE置低使发送有效
         
         Delay100(); //时钟信号高电平保持
         Delay100(); //时钟信号高电平保持
         Delay100(); //时钟信号高电平保持
         Delay100(); //时钟信号高电平保持
    }

    /*******************************************/
    //接收数据函数
    //返回 0:没有数据接收
    //     1:接收到数据
    unsigned char RF2401_RxPacket(unsigned char *RxBuf)
    {
         unsigned int i;

         DR1=1;

         if(DR1)
         {
               for (i=0; i<DATA1_W/8; i++)
               {
                     *RxBuf      = Spi_ByteRead();
                     RxBuf++;
               }
               return 1;
         }
         return 0;
    }


    //*****************************************************************
    //*****************************************************************
    //*****************************************************************
    unsigned char TxRxBuf[32];
    void main(void)
    {
         unsigned int i = 0;
         unsigned int j = 0;
         unsigned int led0_count = 0;
         unsigned int led1_count = 0;

        //
         Config2401();
         Delay100();

         TxRxBuf[0] = 1;
         TxRxBuf[DATA1_W/8 - 1] = 1;

         SetTxMode();                        // Set Tx Mode

         RF2401_TxPacket(TxRxBuf);                  // Transmit Tx buffer data

         LED0 = 0;
         LED1 = 0;

         Delay(500);                        // delay for led light      

         LED0 = 1;
         LED1 = 1;                        // led close
         TxRxBuf[0] = 0xff;
         TxRxBuf[DATA1_W/8 - 1] = 0xff;                              
         SetRxMode();                        // Set RF2401 in Rx mode
         while(1)
         {                                        
           for(i=0;i<30;i++) for(j=0;j<30;j++);
           if (RF2401_RxPacket(TxRxBuf) == 1)      //返回1 表明有数据包接收到
               {
                     if (TxRxBuf[0]==1)
                     {
                           led0_count=15;
                     }
                     if (TxRxBuf[DATA1_W/8 - 1]==1)
                     {
                           led1_count=15;
                     }
               }
               TxRxBuf[0]=0;
               TxRxBuf[DATA1_W/8 - 1]=0;
               //按键检测
               if (KEY0==0)
               {
                     TxRxBuf[0] = 1;
                     led0_count=15;
                     while(      KEY0==0);
               }
               if (KEY1==0)
               {
                     TxRxBuf[DATA1_W/8 - 1] = 1;
                     led1_count=15;
                     while(      KEY1==0);
               }
               if (TxRxBuf[0]==1 || TxRxBuf[DATA1_W/8 - 1]==1)
               {
                     SetTxMode();                        //设置为发射模式
                     RF2401_TxPacket(TxRxBuf);      //发送数据
                     SetRxMode();
               }
               TxRxBuf[0]=0;
               TxRxBuf[DATA1_W/8 - 1]=0;

               //LED显示延时
               if (led0_count>0)      
               {
                     led0_count--;
                     LED0 = 0;
               }
               else LED0 = 1;
               if (led1_count>0)
               {
                     led1_count--;
                     LED1 = 0;
               }
               else LED1 = 1;

         }//end_while(1);
    }
    [/CODE][/I][/I][/I]
    [ 此贴最后由DC在2008-8-3 22:18:23编辑过 ]
    微控网感谢您的参与
    在线情况
    2
    • 头像
    • 级别
      • 积分2
      • 经验72
      • 文章2
      • 注册2008-08-19
      好东西!
      微控网感谢您的参与
      在线情况
      3
      • 头像
      • 级别
        • 积分1
        • 经验76
        • 文章1
        • 注册2008-08-22
        顶,好东西
        微控网感谢您的参与
        在线情况
        4
        • 头像
        • 级别
          • 积分30
          • 经验805
          • 文章147
          • 注册2008-07-09
          顶一个~~~
          经有关部门鉴定为帅哥
          在线情况
          5
          • 头像
          • 级别
            • 积分1
            • 经验39
            • 文章1
            • 注册2008-10-22
            和24E1很相像啊
            微控网感谢您的参与
            在线情况
            6
            • 头像
            • 级别
              • 积分6
              • 经验509
              • 文章12
              • 注册2008-08-23
              哈哈,我刚调试成功了2401,好辛苦啊!早知道这里有,那我就来了!这次用凌阳写的,下次改430上玩玩!
              疯狂的世界,疯狂的人!

              --------------------zigbee/nrf/tinyos讨论群:2431842

              --------------------MCU爱好者讨论群:2431842
              在线情况
              7
              • 头像
              • 级别
                • 积分1
                • 经验89
                • 文章1
                • 注册2008-12-16
                图纸在哪里找啊?
                微控网感谢您的参与
                在线情况
                8
                • 头像
                • 级别
                  • 积分2
                  • 经验40
                  • 文章3
                  • 注册2013-07-27
                  谢谢分享[EM01]
                  微控网感谢您的参与
                  在线情况
                  9
                  • 头像
                  • 级别
                    • 积分1
                    • 经验8
                    • 文章1
                    • 注册2013-08-21
                    请问楼主,宏定义那块地址宽度不是四个字节么,怎么你的程序是两个字节呢?[P]#define ADD_W 0x10[/P]
                    微控网感谢您的参与
                    Powered by LeadBBS 9.2 .
                    Page created in 0.1719 seconds with 5 queries.