|
各位大大好,我是个新手,大概2个月前刚开始学习Arduino(为了参加一个比赛),在极客工坊潜水很久,学习了很多东西,现在也想把这段时间学习的东西和大家分享。
我看到论坛里关于无线发射模块的资料比较少,所以我来发一个无线方面的学习笔记,关于nRF24L01
关于无线模块大家比较熟悉的可能是APC220和Xbee这两种无线模块,网上的资料也很多,我也就不班门弄斧了,但这两种无线模块价格比较贵(因为这个比赛有一个要求是对成本的控制),所以我后来开始研究nRF24L01来进行2个Arduino板子之间的通讯(2块nRF24L01只有36块钱)
关于nRF24L01,工作于2.4 GHz~2.5 GHz ISM频段, 最高工作速率2Mbps,125 频道,满足多点通信和跳频通信需要,低功耗1.9 - 3.6V 工作,待机模式下状态为22uA;掉电模式下为900nA,可以用SPI控制
首先你需要有2块Arduino开发板和2块nRF24L01通信芯片,一个作为发射,一个作为接收。如果你使用的是标准的Arduino开发板,请注意使用开发板上的3.3V pin 作为电源,因为nRF24L01的工作电压是1.9~3.6V,如果使用5V的供电口会把nRF24L01芯片烧坏。
测试程序原文地址:http://www.elecfreaks.com/203.html
这个测试程序的接口如下:
GND – GND, VCC – 3.3V, CS – D8, CSN – D9, SCK – D10, MOSI – D11, MISO – D12, IRQ – D13
(IRQ这个口在这个例程中并没有用到,所以可以不接)
接好后的示意图如下:
这个测试程序是发射端不断发送0x00到0XFF的数据给接收端(程序中用到的头文件打包在附件里)
先是发射端的代码:- /*********************************************************************
- ** Device: nRF24L01+ **
- ** File: EF_nRF24L01_TX.c **
- ** **
- ** **
- ** Copyright (C) 2011 ElecFraks. **
- ** This example code is in the public domain. **
- ** **
- ** Description: **
- ** This file is a sample code for your reference. **
- ** It's the v1.1 nRF24L01+ by arduino **
- ** Created by ElecFreaks. Robi.W,24 July 2011 **
- ** **
- ** http://www.elecfreaks.com **
- ** **
- ** SPI-compatible **
- ** CS - to digital pin 8 **
- ** CSN - to digital pin 9 (SS pin) **
- ** SCK - to digital pin 10 (SCK pin) **
- ** MOSI - to digital pin 11 (MOSI pin) **
- ** MISO - to digital pin 12 (MISO pin) **
- ** IRQ - to digital pin 13 (MISO pin) **
- *********************************************************************/
- #include "NRF24L01.h"
- //***************************************************
- #define TX_ADR_WIDTH 5 // 5 unsigned chars TX(RX) address width
- #define TX_PLOAD_WIDTH 32 // 32 unsigned chars TX payload
- unsigned char TX_ADDRESS[TX_ADR_WIDTH] =
- {
- 0x34,0x43,0x10,0x10,0x01
- }; // Define a static TX address
- unsigned char rx_buf[TX_PLOAD_WIDTH] = {0}; // initialize value
- unsigned char tx_buf[TX_PLOAD_WIDTH] = {0};
- //***************************************************
- void setup()
- {
- pinMode(CE, OUTPUT);
- pinMode(SCK, OUTPUT);
- pinMode(CSN, OUTPUT);
- pinMode(MOSI, OUTPUT);
- pinMode(MISO, INPUT);
- pinMode(IRQ, INPUT);
- // 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); // There is read the mode鈥檚 status register, the default value should be 鈥楨鈥? 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) // if receive data ready (MAX_RT) interrupt, 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);
- }
- }
- //**************************************************
- // Function: init_io();
- // Description:
- // flash led one time,chip enable(ready to TX or RX Mode),
- // Spi disable,Spi clock line init high
- //**************************************************
- void init_io(void)
- {
- digitalWrite(IRQ, 0);
- digitalWrite(CE, 0); // chip enable
- digitalWrite(CSN, 1); // Spi disable
- }
- /**************************************************
- * Function: SPI_RW();
- *
- * Description:
- * Writes one unsigned char to nRF24L01, and return the unsigned char read
- * from nRF24L01 during write, according to SPI protocol
- **************************************************/
- unsigned char SPI_RW(unsigned char Byte)
- {
- unsigned char i;
- for(i=0;i<8;i++) // output 8-bit
- {
- if(Byte&0x80)
- {
- digitalWrite(MOSI, 1);
- }
- else
- {
- digitalWrite(MOSI, 0);
- }
- digitalWrite(SCK, 1);
- Byte <<= 1; // shift next bit into MSB..
- if(digitalRead(MISO) == 1)
- {
- Byte |= 1; // capture current MISO bit
- }
- digitalWrite(SCK, 0);
- }
- return(Byte); // return read unsigned char
- }
- /**************************************************/
- /**************************************************
- * Function: SPI_RW_Reg();
- *
- * Description:
- * Writes value 'value' to register 'reg'
- /**************************************************/
- unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)
- {
- unsigned char status;
- digitalWrite(CSN, 0); // CSN low, init SPI transaction
- status = SPI_RW(reg); // select register
- SPI_RW(value); // ..and write value to it..
- digitalWrite(CSN, 1); // CSN high again
- return(status); // return nRF24L01 status unsigned char
- }
- /**************************************************/
- /**************************************************
- * Function: SPI_Read();
- *
- * Description:
- * Read one unsigned char from nRF24L01 register, 'reg'
- /**************************************************/
- unsigned char SPI_Read(unsigned char reg)
- {
- unsigned char reg_val;
- digitalWrite(CSN, 0); // CSN low, initialize SPI communication...
- SPI_RW(reg); // Select register to read from..
- reg_val = SPI_RW(0); // ..then read register value
- digitalWrite(CSN, 1); // CSN high, terminate SPI communication
-
- return(reg_val); // return register value
- }
- /**************************************************/
- /**************************************************
- * Function: SPI_Read_Buf();
- *
- * Description:
- * Reads 'unsigned chars' #of unsigned chars from register 'reg'
- * Typically used to read RX payload, Rx/Tx address
- /**************************************************/
- unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
- {
- unsigned char status,i;
- digitalWrite(CSN, 0); // Set CSN low, init SPI tranaction
- status = SPI_RW(reg); // Select register to write to and read status unsigned char
- for(i=0;i<bytes;i++)
- {
- pBuf[i] = SPI_RW(0); // Perform SPI_RW to read unsigned char from nRF24L01
- }
- digitalWrite(CSN, 1); // Set CSN high again
- return(status); // return nRF24L01 status unsigned char
- }
- /**************************************************/
- /**************************************************
- * Function: SPI_Write_Buf();
- *
- * Description:
- * Writes contents of buffer '*pBuf' to nRF24L01
- * Typically used to write TX payload, Rx/Tx address
- /**************************************************/
- unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
- {
- unsigned char status,i;
- digitalWrite(CSN, 0); // Set CSN low, init SPI tranaction
- status = SPI_RW(reg); // Select register to write to and read status unsigned char
- for(i=0;i<bytes; i++) // then write all unsigned char in buffer(*pBuf)
- {
- SPI_RW(*pBuf++);
- }
- digitalWrite(CSN, 1); // Set CSN high again
- return(status); // return nRF24L01 status unsigned char
- }
- /**************************************************/
- /**************************************************
- * Function: TX_Mode();
- *
- * Description:
- * This function initializes one nRF24L01 device to
- * TX mode, set TX address, set RX address for auto.ack,
- * fill TX payload, select RF channel, datarate & TX pwr.
- * PWR_UP is set, CRC(2 unsigned chars) is enabled, & PRIM:TX.
- *
- * ToDo: One high pulse(>10us) on CE will now send this
- * packet and expext an acknowledgment from the RX device.
- **************************************************/
- void TX_Mode(void)
- {
- digitalWrite(CE, 0);
- SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // Writes TX_Address to nRF24L01
- SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack
- SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
- SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
- SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...
- SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40
- SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR
- SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // Set PWR_UP bit, enable CRC(2 unsigned chars) & Prim:TX. MAX_RT & TX_DS enabled..
- SPI_Write_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH);
- digitalWrite(CE, 1);
- }
复制代码
再是接收端的代码:
- /*********************************************************************
- ** Device: nRF24L01+ **
- ** File: EF_nRF24L01_TX.c **
- ** **
- ** **
- ** Copyright (C) 2011 ElecFraks. **
- ** This example code is in the public domain. **
- ** **
- ** Description: **
- ** This file is a sample code for your reference. **
- ** It's the v1.1 nRF24L01+ by arduino **
- ** Created by ElecFreaks. Robi.W,24 July 2011 **
- ** **
- ** http://www.elecfreaks.com **
- ** **
- ** SPI-compatible **
- ** CS - to digital pin 8 **
- ** CSN - to digital pin 9 (SS pin) **
- ** SCK - to digital pin 10 (SCK pin) **
- ** MOSI - to digital pin 11 (MOSI pin) **
- ** MISO - to digital pin 12 (MISO pin) **
- ** IRQ - to digital pin 13 (MISO pin) **
- *********************************************************************/
- #include "NRF24L01.h"
- //***************************************************
- #define TX_ADR_WIDTH 5 // 5 unsigned chars TX(RX) address width
- #define TX_PLOAD_WIDTH 32 // 32 unsigned chars TX payload
- unsigned char TX_ADDRESS[TX_ADR_WIDTH] =
- {
- 0x34,0x43,0x10,0x10,0x01
- }; // Define a static TX address
- unsigned char rx_buf[TX_PLOAD_WIDTH];
- unsigned char tx_buf[TX_PLOAD_WIDTH];
- //***************************************************
- void setup()
- {
- pinMode(CE, OUTPUT);
- pinMode(SCK, OUTPUT);
- pinMode(CSN, OUTPUT);
- pinMode(MOSI, OUTPUT);
- pinMode(MISO, INPUT);
- pinMode(IRQ, INPUT);
- // 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); // There is read the mode鈥檚 status register, the default value should be 鈥楨鈥?
- Serial.println("*****************RX_Mode start******************************R");
- RX_Mode(); // set RX mode
- }
- void loop()
- {
- for(;;)
- {
- unsigned char status = SPI_Read(STATUS); // read register STATUS's value
- if(status&RX_DR) // if receive data ready (TX_DS) interrupt
- {
- SPI_Read_Buf(RD_RX_PLOAD, rx_buf, TX_PLOAD_WIDTH); // read playload to rx_buf
- SPI_RW_Reg(FLUSH_RX,0); // clear RX_FIFO
- for(int i=0; i<32; i++)
- {
- Serial.print(" ");
- Serial.print(rx_buf[i],HEX); // print rx_buf
- }
- Serial.println(" ");
- }
- SPI_RW_Reg(WRITE_REG+STATUS,status); // clear RX_DR or TX_DS or MAX_RT interrupt flag
- delay(1000);
- }
- }
- //**************************************************
- // Function: init_io();
- // Description:
- // flash led one time,chip enable(ready to TX or RX Mode),
- // Spi disable,Spi clock line init high
- //**************************************************
- void init_io(void)
- {
- digitalWrite(IRQ, 0);
- digitalWrite(CE, 0); // chip enable
- digitalWrite(CSN, 1); // Spi disable
- }
- /**************************************************
- * Function: SPI_RW();
- *
- * Description:
- * Writes one unsigned char to nRF24L01, and return the unsigned char read
- * from nRF24L01 during write, according to SPI protocol
- **************************************************/
- unsigned char SPI_RW(unsigned char Byte)
- {
- unsigned char i;
- for(i=0;i<8;i++) // output 8-bit
- {
- if(Byte&0x80)
- {
- digitalWrite(MOSI, 1); // output 'unsigned char', MSB to MOSI
- }
- else
- {
- digitalWrite(MOSI, 0);
- }
- digitalWrite(SCK, 1); // Set SCK high..
- Byte <<= 1; // shift next bit into MSB..
- if(digitalRead(MISO) == 1)
- {
- Byte |= 1; // capture current MISO bit
- }
- digitalWrite(SCK, 0); // ..then set SCK low again
- }
- return(Byte); // return read unsigned char
- }
- /**************************************************/
- /**************************************************
- * Function: SPI_RW_Reg();
- *
- * Description:
- * Writes value 'value' to register 'reg'
- /**************************************************/
- unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)
- {
- unsigned char status;
- digitalWrite(CSN, 0); // CSN low, init SPI transaction
- status = SPI_RW(reg); // select register
- SPI_RW(value); // ..and write value to it..
- digitalWrite(CSN, 1); // CSN high again
- return(status); // return nRF24L01 status unsigned char
- }
- /**************************************************/
- /**************************************************
- * Function: SPI_Read();
- *
- * Description:
- * Read one unsigned char from nRF24L01 register, 'reg'
- /**************************************************/
- unsigned char SPI_Read(unsigned char reg)
- {
- unsigned char reg_val;
- digitalWrite(CSN, 0); // CSN low, initialize SPI communication...
- SPI_RW(reg); // Select register to read from..
- reg_val = SPI_RW(0); // ..then read register value
- digitalWrite(CSN, 1); // CSN high, terminate SPI communication
- return(reg_val); // return register value
- }
- /**************************************************/
- /**************************************************
- * Function: SPI_Read_Buf();
- *
- * Description:
- * Reads 'unsigned chars' #of unsigned chars from register 'reg'
- * Typically used to read RX payload, Rx/Tx address
- /**************************************************/
- unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
- {
- unsigned char status,i;
- digitalWrite(CSN, 0); // Set CSN low, init SPI tranaction
- status = SPI_RW(reg); // Select register to write to and read status unsigned char
- for(i=0;i<bytes;i++)
- {
- pBuf[i] = SPI_RW(0); // Perform SPI_RW to read unsigned char from nRF24L01
- }
- digitalWrite(CSN, 1); // Set CSN high again
- return(status); // return nRF24L01 status unsigned char
- }
- /**************************************************/
- /**************************************************
- * Function: SPI_Write_Buf();
- *
- * Description:
- * Writes contents of buffer '*pBuf' to nRF24L01
- * Typically used to write TX payload, Rx/Tx address
- /**************************************************/
- unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
- {
- unsigned char status,i;
- digitalWrite(CSN, 0); // Set CSN low, init SPI tranaction
- status = SPI_RW(reg); // Select register to write to and read status unsigned char
- for(i=0;i<bytes; i++) // then write all unsigned char in buffer(*pBuf)
- {
- SPI_RW(*pBuf++);
- }
- digitalWrite(CSN, 1); // Set CSN high again
- return(status); // return nRF24L01 status unsigned char
- }
- /**************************************************/
- /**************************************************
- * Function: RX_Mode();
- *
- * Description:
- * This function initializes one nRF24L01 device to
- * RX Mode, set RX address, writes RX payload width,
- * select RF channel, datarate & LNA HCURR.
- * After init, CE is toggled high, which means that
- * this device is now ready to receive a datapacket.
- /**************************************************/
- void RX_Mode(void)
- {
- digitalWrite(CE, 0);
- SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // Use the same address on the RX device as the TX device
- SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
- SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
- SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40
- SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // Select same RX payload width as TX Payload width
- SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR
- SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // Set PWR_UP bit, enable CRC(2 unsigned chars) & Prim:RX. RX_DR enabled..
- digitalWrite(CE, 1); // Set CE pin high to enable RX device
- // This device is now ready to receive one packet of 16 unsigned chars payload from a TX device sending to address
- // '3443101001', with auto acknowledgment, retransmit count of 10, RF channel 40 and datarate = 2Mbps.
- }
- /**************************************************/
复制代码 把程序分别烧进2块板子后,把发射端接一个9V的电源,接收端用USB连电脑,打开Arduino IDE 的串口监视器,就可以看到运行的结果:
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
评分
-
查看全部评分
|