nRF2401的C51驱动程序[已经调试通过]

[复制链接]
2156|7
手机看帖
扫描二维码
随时随地手机跟帖
laslison|  楼主 | 2009-10-17 11:11 | 显示全部楼层 |阅读模式
nRF2401的C51驱动程序[已经调试通过]
Microcontrol CODE

  Desc    Demo App for RF2401 Module
      Vender  httpwww.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模式 08位      116
#define CRC_EN            0x1            CRC校验启用

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

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

-----------------------------------------------------------
将设置信息组合成每个字节的数据信息,此区域无需修改
#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_W2  CRC_L1  CRC_EN)
#define RFConfig_Byte16      (RX2_EN7  CM6     RFDR_SB5  XO_F 2  RF_PWR)
#define RFConfig_Byte17      (RF_CH1   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 TxRx 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;i100;i++);
}

void Delay(uchar n)
{
     uint i;
     while(n--)
     for(i=0;i80;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; i8; 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; i8; 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; i20; i++)
     {
           Delay100();
     }

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

     Delay100();-----
   
     for(i=0; i20; i++)
     {
           Delay100();
     }
   
     PWR_DWN - Configuration_mode      Delay_3ms      

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

     Delay100();       configuration mode - stand by mode  
     CS = 0; CS置低使配置有效
     Delay100();
}
laslison|  楼主 | 2009-10-17 11:12 | 显示全部楼层
接上···
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_W8);i++)      写入接收地址(按字节对齐)
     {
           variable2=TxAddress[I];
           Spi_ByteWrite(variable2);
     }

     for(i=0;i(DATA1_W8);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; iDATA1_W8; 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_W8 - 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_W8 - 1] = 0xff;                              
     SetRxMode();                         Set RF2401 in Rx mode
     while(1)
     {                                         
       for(i=0;i30;i++) for(j=0;j30;j++);
       if (RF2401_RxPacket(TxRxBuf) == 1)      返回1 表明有数据包接收到
           {
                 if (TxRxBuf[0]==1)
                 {
                       led0_count=15;
                 }
                 if (TxRxBuf[DATA1_W8 - 1]==1)
                 {
                       led1_count=15;
                 }
           }
           TxRxBuf[0]=0;
           TxRxBuf[DATA1_W8 - 1]=0;
           按键检测
           if (KEY0==0)
           {
                 TxRxBuf[0] = 1;
                 led0_count=15;
                 while(      KEY0==0);
           }
           if (KEY1==0)
           {
                 TxRxBuf[DATA1_W8 - 1] = 1;
                 led1_count=15;
                 while(      KEY1==0);
           }
           if (TxRxBuf[0]==1  TxRxBuf[DATA1_W8 - 1]==1)
           {
                 SetTxMode();                        设置为发射模式
                 RF2401_TxPacket(TxRxBuf);      发送数据
                 SetRxMode();
           }
           TxRxBuf[0]=0;
           TxRxBuf[DATA1_W8 - 1]=0;

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

     }end_while(1);
}

使用特权

评论回复
huamunv| | 2009-10-18 10:52 | 显示全部楼层
挺长的,谢楼主分享了!

使用特权

评论回复
laslison|  楼主 | 2009-10-18 11:08 | 显示全部楼层
希望对大家有用!

使用特权

评论回复
suoma| | 2009-10-18 11:55 | 显示全部楼层
顶!

使用特权

评论回复
Cypress-lh| | 2009-10-19 09:22 | 显示全部楼层
好东西,谢谢LZ分享

使用特权

评论回复
lovelyegle| | 2009-10-20 21:26 | 显示全部楼层
好东西!

使用特权

评论回复
suoma| | 2009-10-21 12:38 | 显示全部楼层
nRF2401?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

95

主题

791

帖子

1

粉丝