nRF2401的C51驅動程序[已經調試通過]
Microcontrol CODE
Desc Demo App for RF2401 Module Vender httpwww.newmsg.com Date 2007-3-12 Update 2007-9-8 供大家學習用,只要修改下代碼就可以應用到其他的單片機。 這個程序是一個半雙工的通信模式. #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(); }
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); } 專業無線總匯 QQ:1002421875 無線技術交流群(群號65332649 81070007) MSN:yunjiakeji@hotmail.com Skype:yunjiakeji EMAIL:myb33695@163.com PHONE:13430551040 http://shop35991384.taobao.com
|