1 頁 (共 1 頁)

nRF24L01 無線模組 2.4G 24L01+升級版

發表於 : 2012-09-22 22:04:08
yehlu

Re: nRF24L01 無線模組 2.4G 24L01+升級版

發表於 : 2012-09-22 22:06:52
yehlu
https://sites.google.com/site/xuexiardu ... 1-bi-ji-qu

傳送
設定 暫存器位元: PRIM_RX (00.0)為低電位。
當單晶片有資料要傳送時,位址和資料使用bytes為單位,透過SPI 指令寫入。暫存器:TX_PLD (N/A) 必須在 腳位:CSN 維持低電位時,持續寫入。暫存器:TX_ADDR (10) 不一定要重新寫入。如果主要傳送器(PTX)要接收ACK packet (認證封包)。主要傳送器(PTX)的暫存器:RX_ADDR_P0 (0A) 必須和 暫存器:TX_ADDR (10) 設定的地址相同。例子在 P37 的第12張圖。
TX5 device: TX_ADDR = 0xB3B4B5B605
TX5 device::RX_ADDR_P0 = 0xB3B4B5B605
RX device: RX_ADDR_P5 = 0xB3B4B5B605
設定 腳位:CE 為高電位 開始傳送(最小高電位持續時間為:10μs)。
(就是它的特性= =)
如果設定自動承認{應該是自動確定對方的功能:很像自動交涉}為高電位(暫存器:ENAA_P0 (01.0) =1)他會馬上轉換成接收模式,直到[ NO_ACK (N/A) 這個位元]被寫在接收到的封包中。如果[有效的封包]在[有效的自動承認時間]內被接收,這個傳輸就被認為成功。[暫存器電位:TX_DS (07.5) ]在[暫存器:STATUS (07) ]會被設定為高電位,然後在 [TX FIFO] 的資料都會被移除。如果 [有效的ACK packet]沒有在有限的時間內接收到,資料會被重新傳送(當開啟自動重新傳送時)。如果[自動重新傳送計數暫存器:ARC_CNT (08.3:0) ]超過設定的最大限制[暫存器:ARC (04.3:0) ]和[暫存器位元:MAX_RT (07.4) ]會在[暫存器STATUS (07) ] 被設定為高電位。在[TX FIFO] 的資料不會被刪除。[暫存器位元:MAX_RT (07.4) ] 或是 [暫存器位元:TX_DS (07.5) ] 被設定為高電位時,[腳位:IRQ]會被啟動。去關閉[腳位:IRQ],必須透過寫入[暫存器:STATUS (07) ](詳情請去看Interrupt 章節)。如果[ACK packet]沒有在設定的[最大重新發送次數]裡被接收,就不會有新的封包被傳送出去,必須清除[暫存器位元:MAX_RT (07.4) ]的中斷。[封包遺失計數暫存器:PLOS_CNT (08.7:4) ]會在 [暫存器位元:MAX_RT (07.4) ]每次中斷時 遞增。也就是說,[暫存器:ARC_CNT (08.3:0) ]計算重新發送的次數會發送封包,而[暫存器:PLOS_CNT (08.7:4) ]在超過[最大重新發送次數]後並不會發送封包。{這一段我不太確定}
nRF24L01 在 腳位:CE 被設定為低電位時會進入[待命模式1(standby-I mode)],不然當 資料發送完後,TX FIFO 為空、[腳位:CE]還是維持高電位,就會進入[待命模式2(standby-II mode)]。
如果再[待命模式2(standby-II mode)]想要回去[待命模式1(standby-I mode)],就把[腳位:CE]設定為低電位。

接收
接收模式 透過設定 在暫存器:CONFIG (00) 的暫存器位元:PRIM_RX (00.0) 為高電位。所有[資料管線]接收到的資料必須被打開(暫存器:EN_RXADDR (02) ){這到底是啥?},想在在所有資料通道自動承認{應該是自動確定對方的功能}必須打開Enhanced ShockBurst™(暫存器:EN_AA (01) ),而且更正資料寬度必須設定(暫存器:RX_PW_Px (11~16) )。地址設定方法在上面的Enhanced ShockBurst™章節裡的item 2{物品2}。
設定腳位:CE 為高電位開啟接收模式。
經過130μs 後nRF24L01 後監測空氣中傳過來的資料。
當[有效的封包]被接收(匹配的位址和正確的CRC),資料就會被放入RX FIFO,而且暫存器位元:RX_DR (07.6) 會在 暫存器:STATUS (07) 裡面被設定高電位。腳位:IRQ 會在 暫存器位元:RX_DR (07.6) 被設定為高電位,被啟動。在暫存器:STATUS (07) 裡面的 暫存器位元:RX_P_NO (07.3:1) 會指示哪一個[資料管線]已經接收資料進去。
如果自動承認{應該是自動確定對方的功能:很像自動交涉}被打開,ACK packet 被傳送回去,直到[ NO_ACK (N/A) 這個位元]被寫入在接收到的封包中。如果有資料在 暫存器:TX_PLD (N/A) FIFO,這個資料會被增加 ACK packet。
單晶片設定腳位:CE 為低電位去進入[待命模式1(standby-I mode)]。
單晶片可以透過SPI 在合適的速率把資料讀出。
nRF24L01 現在已經準備可以進入TX(傳送)、RX(接收)或是省電模式。

Re: nRF24L01 無線模組 2.4G 24L01+升級版

發表於 : 2012-09-22 22:42:34
yehlu

Re: nRF24L01 無線模組 2.4G 24L01+升級版

發表於 : 2012-09-22 22:44:42
yehlu
http://www.elecfreaks.com/203.html

GND – GND, VCC – 3.3V, CS – D8, CSN – D9, SCK – D10, MOSI – D11, MISO – D12, IRQ – D13

代碼: 選擇全部

void setup()
{
  SPI_DIR = ( CE + SCK + CSN + MOSI);
  SPI_DIR &=~ ( IRQ + MISO);
  //  attachInterrupt(1, _ISR, LOW);// interrupt enable
  Serial.begin(9600);
  init_io();                        // Initialize IO port
  unsigned char status=SPI_Read(STATUS);
  Serial.print("status = ");
  Serial.println(status,HEX);      // read the mode’s status register, the default value should be ‘E’
  Serial.println("*******************TX_Mode Start****************************");
  TX_Mode();                       // set TX mode
}
void loop()
{
  int k = 0;
  for(;;)
  {
    for(int i=0; i<32; i++)
        tx_buf[i] = k++;
    unsigned char status = SPI_Read(STATUS);                // read register STATUS's value
    if(status&TX_DS)                                        // if receive data ready (TX_DS) interrupt
    {
      SPI_RW_Reg(FLUSH_TX,0);
      SPI_Write_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH);     // write playload to TX_FIFO
    }
    if(status&MAX_RT)                                       // this is retransmit than  SETUP_RETR
    {
      SPI_RW_Reg(FLUSH_TX,0);
      SPI_Write_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH);     // disable standy-mode
    }
    SPI_RW_Reg(WRITE_REG+STATUS,status);                    // clear RX_DR or TX_DS or MAX_RT interrupt flag
    delay(1000);
  }
}

NRF24L01 2.4G摇控收发纯数字2通道PWM(可以转为4,8...N个双向通道)

發表於 : 2012-09-22 22:47:17
yehlu
http://www.geek-workshop.com/forum.php? ... d&tid=1228

代碼: 選擇全部

//MISO -> D12  
// * MOSI ->D11  
// * SCK ->D13

 //* CE ->D8
 //* CSN ->D7

#include "SPI.h"      //24L01库文件
#include "Mirf.h"
#include "nRF24L01.h"
#include "MirfHardwareSpiDriver.h"

int aaa;
int aaaa;
int bbb;
int bbbb;

void setup(){
  Mirf.spi = &MirfHardwareSpi;  //加载24L01  SPI
  Mirf.init();                                 //开始
   Mirf.setTADDR((byte *)"serv1");//发送到"接收地址"
  Mirf.payload = sizeof(int);          //数据类型(整数)
   Mirf.config();  //发送通道??
}
void loop(){
  aaa=analogRead(A4)+1;            //读取 X 向电平PWM(1至1024)
  bbb= -analogRead(A5)-1;      //读取 Y向电平PWM(-1至-1024)
   if (aaa !=aaaa)                    //如果 X 向电平与之前电平不一样则执行
   {
      Mirf.send((byte *)&aaa); //发送X向电平
     aaaa=aaa;                       //保存X 向当前电平
     while(Mirf.isSending()){     //等待或继续发送??
  }
    }
if (bbb !=bbbb)                    //如果 Y 向电平与之前电平不一样则执行
{
   Mirf.send((byte *)&bbb);  //发送Y向电平
  bbbb=bbb;                      //保存Y 向当前电平
  while(Mirf.isSending()){    //等待或继续发送?
  }
}
 delay(10);                        // 等待0.01秒
}  

代碼: 選擇全部

//MISO -> D12  
// * MOSI ->D11  
// * SCK ->D13

 //* CE ->D8
 //* CSN ->D7
//LCD 1602 IIC SDA---A4  328
//LCD 1602 IIC SCL---A5 328


#include "Wire.h"                                //LCD1602 IIC 库文件
#include ;
LiquidCrystal_I2C lcd(0x27,16,2);

#include "SPI.h"                              //24L01库文件
#include "Mirf.h"
#include "nRF24L01.h"
#include "MirfHardwareSpiDriver.h"

int data;
int aaa;
int bbb;

void setup(){   
   lcd.init();                                        //加载LCD1602 IIC
    lcd.backlight();
    //lcd.setBacklight(120);               //设置LCD背光亮度,好象没作用
        delay(20); 
  Mirf.spi = &MirfHardwareSpi;          //加载24L01  SPI
  Mirf.init();
  Mirf.setRADDR((byte *)"serv1"); //接收地址" "
  Mirf.payload = sizeof(int);            //数据类型(整数)
      Mirf.config(); 
}

void loop(){
 
  if(Mirf.dataReady()){                          //如果接收到数据则执行
     
      Mirf.getData((byte *)&data);   //接收数据
      
      if (data>=1)               //如果大于或等于1为X向 (如果设为 >=0就会 X,Y通道冲突,所以设为1开始)
      {
 aaa=data-1;
      }
         if (data<=-1)         //如果小于或等于-1为Y向(............)
         { 
    bbb=data+1;
      }
   
    Mirf.rxFifoEmpty();            //清理24L01援存??
  }
     lcd.clear();                     //清屏
      lcd.setCursor(0, 0); 
      lcd.print(aaa);                  //显示X向 1至1024
      lcd.setCursor(6, 0);
      lcd.print(0-bbb);             //显示Y向,并将负数变为正数 1至1024
  delay(10); 
}