NRF24L01無線通訊模塊驅(qū)動(dòng)
1)2.4G全球開放的ISM頻段,免許可證使用。
本文引用地址:http://www.ex-cimer.com/article/201611/318105.htm2)最高工作速率2Mbps,高校的GFSK調(diào)制,抗干擾能力強(qiáng)。
3)125個(gè)可選的頻道,滿足多點(diǎn)通信和調(diào)頻通信的需要。
4)內(nèi)置CRC檢錯(cuò)和點(diǎn)對(duì)多點(diǎn)的通信地址控制。
5)低工作電壓(1.9~3.6V)。
6)可設(shè)置自動(dòng)應(yīng)答,確保數(shù)據(jù)可靠傳輸。
模塊引腳圖如下所示
模塊VCC腳的電壓范圍為1.9~3.6V,建議不要超過3.6V,否則可能燒壞模塊,一般用3.3V
電壓比較合適。除了VCC和GND腳,其他引腳都可以和5V單片機(jī)的IO口直連,正是因?yàn)槠?/p>
兼容5V單片機(jī)的IO,故使用上具有很大優(yōu)勢
該芯片在接收模式下可以同時(shí)接收六個(gè)發(fā)送端信息,因?yàn)槠鋬?nèi)部有六個(gè)通道,發(fā)送模式下只能一個(gè)發(fā)
該芯片有兩種傳輸模式,第一個(gè)是無雙向鏈接的模式,也就是單向發(fā)送沒有ACK,第二種芯片自帶ACK模式,推薦用第二種,只要是使能動(dòng)應(yīng)答即可,并且,在第二種模式下,發(fā)送端的接收通道0用來作為ACK的接收通道,接收端的發(fā)送通道用來做ack的發(fā)送通道,設(shè)置地址時(shí)要注意這兩個(gè)地方地址應(yīng)當(dāng)相同
主要命令如下
寫寄存器命令只有在CE為0處于待機(jī)狀態(tài)下時(shí)才有效,使用時(shí)應(yīng)當(dāng)注意這一點(diǎn)
具體去掉那個(gè)代碼如下
24l01.h
#ifndef __24L01_H#define __24L01_H #include "ioremap.h" #include "delay.h"#include "spi.h"http://設(shè)備地址設(shè)置#define ADDR1_VALUE 0X34#define ADDR2_VALUE 0X43#define ADDR3_VALUE 0X10#define ADDR4_VALUE 0X10#define ADDR5_VALUE 0X01////////////////////////////////////////////////////////////////////////////////////////////////////////////NRF24L01寄存器操作命令#define READ_REG_NRF 0x00 //讀配置寄存器,低5位為寄存器地址#define WRITE_REG_NRF 0x20 //寫配置寄存器,低5位為寄存器地址#define RD_RX_PLOAD 0x61 //讀RX有效數(shù)據(jù),1~32字節(jié),應(yīng)用于接收模式下,讀取完成后自動(dòng)清除FIFO#define WR_TX_PLOAD 0xA0 //寫TX有效數(shù)據(jù),1~32字節(jié),應(yīng)用于發(fā)射模式下#define FLUSH_TX 0xE1 //清除TX FIFO寄存器.發(fā)射模式下用#define FLUSH_RX 0xE2 //清除RX FIFO寄存器.接收模式下用,傳輸應(yīng)答信號(hào)過程中用這個(gè)指令會(huì)讓應(yīng)答數(shù)據(jù)不能完整傳輸#define REUSE_TX_PL 0xE3 //重新使用上一包數(shù)據(jù),CE為高,數(shù)據(jù)包被不斷發(fā)送.發(fā)射過程中必須禁止用這個(gè)功能#define NOP 0xFF //空操作,可以用來讀狀態(tài)寄存器 //SPI(NRF24L01)寄存器地址#define CONFIG 0x00 //配置寄存器地址;//bit0:1接收模式,0發(fā)射模式;//bit1:1上電 2掉電;//bit2:CRC模式; 0八位CRC 1 16位CRC//bit3:CRC使能;1使能 0不使能(若是使能自動(dòng)應(yīng)答,這一位必須為高)//bit4 可屏蔽中斷 MAX_RT 1 屏蔽 0不屏蔽 發(fā)生中斷IRQ為低電平(最大重發(fā)中斷)//bit5 可屏蔽中斷TX_DS 1屏蔽 0不 數(shù)據(jù)發(fā)送完成并收到應(yīng)答//bit6 可屏蔽中斷RX_DR 接收數(shù)據(jù)完成 1屏蔽 0不屏蔽//bit7 默認(rèn)為0#define EN_AA 0x01 //bit0~5,使能自動(dòng)應(yīng)答功能 (自動(dòng)應(yīng)答必然啟動(dòng)CRC)對(duì)應(yīng)通道0~5#define EN_RXADDR 0x02 //bit0~5,接收數(shù)據(jù)通道允許,對(duì)應(yīng)通道0~5#define SETUP_AW 0x03 //bit1,0:設(shè)置地址寬度(所有數(shù)據(jù)通道) 01,3字節(jié); 10,4字節(jié); 11,5字節(jié);(默認(rèn)11)#define SETUP_RETR 0x04 //建立自動(dòng)重發(fā);//bit3:0,自動(dòng)重發(fā)計(jì)數(shù)器;0 15次//bit7:4,自動(dòng)重發(fā)延時(shí) 0 250*x+86us#define RF_CH 0x05 //RF通道,bit6:0,工作通道頻率#define RF_SETUP 0x06 //bit4: pll lock允許,僅用于測試模式,應(yīng)當(dāng)為1//bit3: 傳輸速率(0:1Mbps,1:2Mbps);//bit2:1,發(fā)射功率 11 0dbm;//bit0:低噪聲放大器增益 #define STATUS 0x07 //bit0:TX FIFO滿標(biāo)志;//bit3:1,接收數(shù)據(jù)通道號(hào)(最大:6);接收到數(shù)據(jù)的通道號(hào)碼//bit4,達(dá)到最多次重發(fā) max_rt中斷//bit5:數(shù)據(jù)發(fā)送完成中斷;寫1清除中斷//bit6:接收數(shù)據(jù)中斷; 寫1清除中斷#define OBSERVE_TX 0x08 //發(fā)送檢測寄存器,//bit7:4,數(shù)據(jù)包丟失計(jì)數(shù)器;//bit3:0,重發(fā)計(jì)數(shù)器#define CD 0x09 //載波檢測寄存器,//bit0,載波檢測;#define RX_ADDR_P0 0x0A //數(shù)據(jù)通道0接收地址,最大長度5個(gè)字節(jié),低字節(jié)在前#define RX_ADDR_P1 0x0B //數(shù)據(jù)通道1接收地址,最大長度5個(gè)字節(jié),低字節(jié)在前#define RX_ADDR_P2 0x0C //數(shù)據(jù)通道2接收地址,最低字節(jié)可設(shè)置,高字節(jié),必須同RX_ADDR_P1[39:8]相等;#define RX_ADDR_P3 0x0D //數(shù)據(jù)通道3接收地址,最低字節(jié)可設(shè)置,高字節(jié),必須同RX_ADDR_P1[39:8]相等;#define RX_ADDR_P4 0x0E //數(shù)據(jù)通道4接收地址,最低字節(jié)可設(shè)置,高字節(jié),必須同RX_ADDR_P1[39:8]相等;#define RX_ADDR_P5 0x0F //數(shù)據(jù)通道5接收地址,最低字節(jié)可設(shè)置,高字節(jié),必須同RX_ADDR_P1[39:8]相等;#define TX_ADDR 0x10 //發(fā)送地址(低字節(jié)在前),ShockBurstTM模式下,RX_ADDR_P0與此地址相等#define RX_PW_P0 0x11 //接收數(shù)據(jù)通道0有效數(shù)據(jù)寬度(1~32字節(jié)),設(shè)置為0則非法#define RX_PW_P1 0x12 //接收數(shù)據(jù)通道1有效數(shù)據(jù)寬度(1~32字節(jié)),設(shè)置為0則非法#define RX_PW_P2 0x13 //接收數(shù)據(jù)通道2有效數(shù)據(jù)寬度(1~32字節(jié)),設(shè)置為0則非法#define RX_PW_P3 0x14 //接收數(shù)據(jù)通道3有效數(shù)據(jù)寬度(1~32字節(jié)),設(shè)置為0則非法#define RX_PW_P4 0x15 //接收數(shù)據(jù)通道4有效數(shù)據(jù)寬度(1~32字節(jié)),設(shè)置為0則非法#define RX_PW_P5 0x16 //接收數(shù)據(jù)通道5有效數(shù)據(jù)寬度(1~32字節(jié)),設(shè)置為0則非法#define NRF_FIFO_STATUS 0x17 //FIFO狀態(tài)寄存器;//bit0,RX FIFO寄存器空標(biāo)志;//bit1,RX FIFO滿標(biāo)志;//bit2,3,保留//bit4,TX FIFO空標(biāo)志;//bit5,TX FIFO滿標(biāo)志;//bit6,1,循環(huán)發(fā)送上一數(shù)據(jù)包.0,不循環(huán);#define MAX_TX 0x10 //達(dá)到最大發(fā)送次數(shù)中斷#define TX_OK 0x20 //TX發(fā)送完成中斷#define RX_OK 0x40 //接收到數(shù)據(jù)中斷////////////////////////////////////////////////////////////////////////////////////////////////////////////24L01操作線#define NRF24L01_CE PGout(6) //24L01片選信號(hào)#define NRF24L01_CSN PGout(7) //SPI片選信號(hào) #define NRF24L01_IRQ PGin(8) //IRQ主機(jī)數(shù)據(jù)輸入//24L01發(fā)送接收數(shù)據(jù)寬度定義#define TX_ADR_WIDTH 5 //5字節(jié)的地址寬度#define RX_ADR_WIDTH 5 //5字節(jié)的地址寬度#define TX_PLOAD_WIDTH 32 //32字節(jié)的用戶數(shù)據(jù)寬度#define RX_PLOAD_WIDTH 32 //32字節(jié)的用戶數(shù)據(jù)寬度void Nrf24l01Init(void);//初始化void Nrf24l01RxMode(void);//配置為接收模式void Nrf24l01TxMode(void);//配置為發(fā)送模式u8 Nrf24l01WriteBuf(u8 reg, u8 *pBuf, u8 u8s);//寫數(shù)據(jù)區(qū)u8 Nrf24l01ReadBuf(u8 reg, u8 *pBuf, u8 u8s);//讀數(shù)據(jù)區(qū)u8 Nrf24l01ReadReg(u8 reg); //讀寄存器u8 Nrf24l01WriteReg(u8 reg, u8 value);//寫寄存器u8 Nrf24l01Check(void);//檢查24L01是否存在u8 Nrf24l01TxPacket(u8 *txbuf);//發(fā)送一個(gè)包的數(shù)據(jù)u8 Nrf24l01RxPacket(u8 *rxbuf);//接收一個(gè)包的數(shù)據(jù)#endif
24l01.c
#include "24l01.h"const u8 TX_ADDRESS[TX_ADR_WIDTH]={ADDR1_VALUE,ADDR2_VALUE,ADDR3_VALUE,ADDR4_VALUE,ADDR5_VALUE}; //發(fā)送地址const u8 RX_ADDRESS[RX_ADR_WIDTH]={ADDR1_VALUE,ADDR2_VALUE,ADDR3_VALUE,ADDR4_VALUE,ADDR5_VALUE}; //發(fā)送地址//初始化24L01的IO口void Nrf24l01Init(void){ GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef SPI_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOBRCC_APB2Periph_GPIODRCC_APB2Periph_GPIOG, ENABLE); //使能PB,D,G端口時(shí)鐘GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //PB12上拉 防止W25X的干擾GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化指定IOGPIO_SetBits(GPIOB,GPIO_Pin_12);//上拉 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PD2推挽輸出上拉 禁止SD卡的干擾GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出GPIO_SetBits(GPIOD,GPIO_Pin_2);//初始化指定IOGPIO_InitStructure.GPIO_Pin = GPIO_Pin_6GPIO_Pin_7; //PG6 7 推挽 GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化指定IOGPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PG8 輸入 GPIO_Init(GPIOG, &GPIO_InitStructure);GPIO_ResetBits(GPIOG,GPIO_Pin_6GPIO_Pin_7GPIO_Pin_8);//PG6,7,8上拉 Spi2Init(); //初始化SPI SPI_Cmd(SPI2, DISABLE); // SPI外設(shè)不使能SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //SPI設(shè)置為雙線雙向全雙工SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //SPI主機(jī)SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //發(fā)送接收8位幀結(jié)構(gòu)SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //時(shí)鐘懸空低SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //數(shù)據(jù)捕獲于第1個(gè)時(shí)鐘沿SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信號(hào)由軟件控制SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; //定義波特率預(yù)分頻的值:波特率預(yù)分頻值為16SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //數(shù)據(jù)傳輸從MSB位開始SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值計(jì)算的多項(xiàng)式SPI_Init(SPI2, &SPI_InitStructure); //根據(jù)SPI_InitStruct中指定的參數(shù)初始化外設(shè)SPIx寄存器SPI_Cmd(SPI2, ENABLE); //使能SPI外設(shè)NRF24L01_CE=0; //使能24L01,初始化低電平進(jìn)入待機(jī)模式NRF24L01_CSN=1; //SPI片選取消 }//SPI寫寄存器//reg:指定寄存器地址//value:寫入的值//每一個(gè)命令的執(zhí)行都需要一次CSN由低到高的過程u8 Nrf24l01WriteReg(u8 reg,u8 value){u8 status; NRF24L01_CSN=0; //使能SPI傳輸NRF24L01_CE=0; //待機(jī)模式才能進(jìn)行寄存器寫入status =Spi2ReadWriteByte(WRITE_REG_NRF+reg);//發(fā)送寄存器號(hào) +讀寄存器命令Spi2ReadWriteByte(value); //寫入寄存器的值NRF24L01_CSN=1; //禁止SPI傳輸 return(status); //返回狀態(tài)值}//讀取SPI寄存器值//reg:要讀的寄存器u8 Nrf24l01ReadReg(u8 reg){u8 reg_val; NRF24L01_CSN = 0; //使能SPI傳輸 Spi2ReadWriteByte(READ_REG_NRF+reg); //發(fā)送寄存器號(hào)+讀寄存器命令reg_val=Spi2ReadWriteByte(0XFF);//讀取寄存器內(nèi)容NRF24L01_CSN = 1; //禁止SPI傳輸 return(reg_val); //返回狀態(tài)值}//在指定位置讀出指定長度的數(shù)據(jù)//reg:寄存器(位置)//*pBuf:數(shù)據(jù)指針//len:數(shù)據(jù)長度//返回值,此次讀到的狀態(tài)寄存器值 u8 Nrf24l01ReadBuf(u8 reg,u8 *pBuf,u8 len){u8 status,u8_ctr; NRF24L01_CSN = 0; //使能SPI傳輸status=Spi2ReadWriteByte(reg);//發(fā)送寄存器值(位置),并讀取狀態(tài)值 for(u8_ctr=0;u8_ctr
評(píng)論