模块介绍
NRF24L01是NORDIC公司生产的一款无线通信芯片,采用FSK调制,内部集成NORDIC自己的Enhanced Short Burst 协议,可以实现点对点或者1对6 的无线通信,通信速率最高可以达到2Mbps. NRF24L01采用SPI通信。
①MOSI 主器件数据输出,从器件数据输入
②MISO 主器件数据输入,从器件数据输出
③SCK 时钟信号,主器件产生
④CSN 从器件使能信号
⑤CE 使能器件的发送模式或接收模式
⑥IRQ 中断信号,发生中断变低电平。TxFIFO发完并且收到ACK、RxFIFO收到数据、 达到最大重发次数
工作模式
NRF24L01工作模式,由CE和CONFIG寄存器的PWR_UP和PRIM_RX位共同控制
主要指令
配置寄存器
状态寄存器
接收模式:
Rx模式初始化过程: 初始化步骤24L01相关寄存器
①写Rx节点的地址RX_ADDR_P0
②使能AUTO ACK EN_AA
③使能PIPE 0 (通道0) EN_RXADDR
④选择通信频率 RF_CH
⑤选择通道0 有效数据宽度 RX_Pw_P0
⑥配置发射参数(低噪放大器增益、发射功率、无线速率)RF_SETUP
⑦配置24L01 的基本参数以及切换工作模式 CONFIG
发送模式:
Tx模式初始化过程:
①写Tx节点的地址TX_ADDR
②写RX节点的地址(主要是为了使能Auto Ack) RX_ADDR_P0
③使能AUT0 ACK EN_AA
④使能PIPE 0 EN_RXADDR
⑤配置自动重发次数 SETUP_RETR
⑥选择通信频率 RF_CH
⑦配置发射参数(低噪放大器增益,发射功率,无限速率) RF_SETUP
⑧选择通道0 有效数据宽度 RX_Pw_P0
⑨配置24L01 的基本参数以及切换工作模式 CONFIG
下面用无线模块给串口发送数据:
移植驱动程序:
NRF24L01.c
#include "NRF24L01.h"
#include "stm32f10x.h"
#include "spi.h"
u8 tx_buf[33]="不是哥们,你吴彦祖啊";
u8 rx_buf[33]={0};
const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //·¢Ë͵ØÖ·
const u8 RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};
//³õʼ»¯24L01µÄIO¿Ú
void NRF24L01_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
//ʹÄÜPB,F,D¶Ë¿ÚʱÖÓ //PF8-CE PF9-CSN PD3-IRQ
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //PG13ÉÏÀ ·ÀÖ¹EN25XµÄ¸ÉÈÅ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //ÍÆÍìÊä³ö
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOG, &GPIO_InitStructure); //³õʼ»¯Ö¸¶¨IO
GPIO_SetBits(GPIOG,GPIO_Pin_13);//ÉÏÀ
GPIO_InitStructure.GPIO_Pin = NRF24L01_CSN|NRF24L01_CE; //PF8 9 ÍÆÍì
GPIO_Init(NRF24L01_Port, &GPIO_InitStructure);//³õʼ»¯Ö¸¶¨IO
GPIO_ResetBits(NRF24L01_Port,NRF24L01_CSN|NRF24L01_CE);//PF6,7,8ÏÂÀ
GPIO_InitStructure.GPIO_Pin = NRF24L01_IRQ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PD3 ÊäÈë
GPIO_Init(NRF24L01_Port, &GPIO_InitStructure);
GPIO_ResetBits(NRF24L01_Port,NRF24L01_IRQ);//PD3ÏÂÀ
SPI2_Init(); //³õʼ»¯SPI
SPI_Cmd(SPI2, DISABLE); // SPIÍâÉ費ʹÄÜ
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //SPIÉèÖÃΪ˫ÏßË«Ïòȫ˫¹¤
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //SPIÖ÷»ú
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //·¢ËͽÓÊÕ8λ֡½á¹¹
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //ʱÖÓÐü¿ÕµÍ
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //Êý¾Ý²¶»ñÓÚµÚ1¸öʱÖÓÑØ
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSSÐźÅÓÉÈí¼þ¿ØÖÆ
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; //¶¨Òå²¨ÌØÂÊÔ¤·ÖƵµÄÖµ:²¨ÌØÂÊÔ¤·ÖƵֵΪ16
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //Êý¾Ý´«Êä´ÓMSBλ¿ªÊ¼
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRCÖµ¼ÆËãµÄ¶àÏîʽ
SPI_Init(SPI2, &SPI_InitStructure); //¸ù¾ÝSPI_InitStructÖÐÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèSPIx¼Ä´æÆ÷
SPI_Cmd(SPI2, ENABLE); //ʹÄÜSPIÍâÉè
NRF24L01_CE_L; //ʹÄÜ24L01
NRF24L01_CSN_H; //SPIƬѡȡÏû
}
//¼ì²â24L01ÊÇ·ñ´æÔÚ
//·µ»ØÖµ:0£¬³É¹¦;1£¬Ê§°Ü
u8 NRF24L01_Check(void)
{
u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};
u8 i;
SPI2_SetSpeed(SPI_BaudRatePrescaler_4); //spiËÙ¶ÈΪ9Mhz£¨24L01µÄ×î´óSPIʱÖÓΪ10Mhz£©
NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,buf,5);//дÈë5¸ö×ֽڵĵØÖ·.
NRF24L01_Read_Buf(TX_ADDR,buf,5); //¶Á³öдÈëµÄµØÖ·
for(i=0;i<5;i++)if(buf[i]!=0XA5)break;
if(i!=5)return 1;//¼ì²â24L01´íÎó
return 0; //¼ì²âµ½24L01
}
//SPIд¼Ä´æÆ÷
//reg:Ö¸¶¨¼Ä´æÆ÷µØÖ·
//value:дÈëµÄÖµ
u8 NRF24L01_Write_Reg(u8 reg,u8 value)
{
u8 status;
NRF24L01_CSN_L; //ʹÄÜSPI´«Êä
status =SPI2_ReadWriteByte(reg);//·¢ËͼĴæÆ÷ºÅ
SPI2_ReadWriteByte(value); //дÈë¼Ä´æÆ÷µÄÖµ
NRF24L01_CSN_H; //½ûÖ¹SPI´«Êä
return(status); //·µ»Ø×´Ì¬Öµ
}
//¶ÁÈ¡SPI¼Ä´æÆ÷Öµ
//reg:Òª¶ÁµÄ¼Ä´æÆ÷
u8 NRF24L01_Read_Reg(u8 reg)
{
u8 reg_val;
NRF24L01_CSN_L; //ʹÄÜSPI´«Êä
SPI2_ReadWriteByte(reg); //·¢ËͼĴæÆ÷ºÅ
reg_val=SPI2_ReadWriteByte(0XFF);//¶ÁÈ¡¼Ä´æÆ÷ÄÚÈÝ
NRF24L01_CSN_H; //½ûÖ¹SPI´«Êä
return(reg_val); //·µ»Ø×´Ì¬Öµ
}
//ÔÚÖ¸¶¨Î»ÖöÁ³öÖ¸¶¨³¤¶ÈµÄÊý¾Ý
//reg:¼Ä´æÆ÷(λÖÃ)
//*pBuf:Êý¾ÝÖ¸Õë
//len:Êý¾Ý³¤¶È
//·µ»ØÖµ,´Ë´Î¶Áµ½µÄ״̬¼Ä´æÆ÷Öµ
u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len)
{
u8 status,u8_ctr;
NRF24L01_CSN_L; //ʹÄÜSPI´«Êä
status=SPI2_ReadWriteByte(reg);//·¢ËͼĴæÆ÷Öµ(λÖÃ),²¢¶Áȡ״ֵ̬
for(u8_ctr=0;u8_ctr<len;u8_ctr++)
pBuf[u8_ctr]=SPI2_ReadWriteByte(0XFF);//¶Á³öÊý¾Ý
NRF24L01_CSN_H; //¹Ø±ÕSPI´«Êä
return status; //·µ»Ø¶Áµ½µÄ״ֵ̬
}
//ÔÚÖ¸¶¨Î»ÖÃдָ¶¨³¤¶ÈµÄÊý¾Ý
//reg:¼Ä´æÆ÷(λÖÃ)
//*pBuf:Êý¾ÝÖ¸Õë
//len:Êý¾Ý³¤¶È
//·µ»ØÖµ,´Ë´Î¶Áµ½µÄ״̬¼Ä´æÆ÷Öµ
u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len)
{
u8 status,u8_ctr;
NRF24L01_CSN_L; //ʹÄÜSPI´«Êä
status = SPI2_ReadWriteByte(reg);//·¢ËͼĴæÆ÷Öµ(λÖÃ),²¢¶Áȡ״ֵ̬
for(u8_ctr=0; u8_ctr<len; u8_ctr++)
SPI2_ReadWriteByte(*pBuf++); //дÈëÊý¾Ý
NRF24L01_CSN_H; //¹Ø±ÕSPI´«Êä
return status; //·µ»Ø¶Áµ½µÄ״ֵ̬
}
//Æô¶¯NRF24L01·¢ËÍÒ»´ÎÊý¾Ý
//txbuf:´ý·¢ËÍÊý¾ÝÊ×µØÖ·
//·µ»ØÖµ:·¢ËÍÍê³É×´¿ö
u8 NRF24L01_TxPacket(u8 *txbuf)
{
u8 sta;
SPI2_SetSpeed(SPI_BaudRatePrescaler_4);//spiËÙ¶ÈΪ9Mhz£¨24L01µÄ×î´óSPIʱÖÓΪ10Mhz£©
NRF24L01_CE_L;
NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//дÊý¾Ýµ½TX BUF 32¸ö×Ö½Ú
NRF24L01_CE_H;//Æô¶¯·¢ËÍ
while(GPIO_ReadOutputDataBit(NRF24L01_Port,NRF24L01_IRQ)!=0);//µÈ´ý·¢ËÍÍê³É
sta = NRF24L01_Read_Reg(STATUS); //¶Áȡ״̬¼Ä´æÆ÷µÄÖµ
NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //Çå³ýTX_DS»òMAX_RTÖжϱêÖ¾
if(sta&MAX_TX)//´ïµ½×î´óÖØ·¢´ÎÊý
{
NRF24L01_Write_Reg(FLUSH_TX,0xff);//Çå³ýTX FIFO¼Ä´æÆ÷
return MAX_TX;
}
if(sta&TX_OK)//·¢ËÍÍê³É
{
return TX_OK;
}
return 0xff;//ÆäËûÔÒò·¢ËÍʧ°Ü
}
//Æô¶¯NRF24L01·¢ËÍÒ»´ÎÊý¾Ý
//txbuf:´ý·¢ËÍÊý¾ÝÊ×µØÖ·
//·µ»ØÖµ:0£¬½ÓÊÕÍê³É£»ÆäËû£¬´íÎó´úÂë
u8 NRF24L01_RxPacket(u8 *rxbuf)
{
u8 sta;
SPI2_SetSpeed(SPI_BaudRatePrescaler_8); //spiËÙ¶ÈΪ9Mhz£¨24L01µÄ×î´óSPIʱÖÓΪ10Mhz£©
sta=NRF24L01_Read_Reg(STATUS); //¶Áȡ״̬¼Ä´æÆ÷µÄÖµ
NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //Çå³ýTX_DS»òMAX_RTÖжϱêÖ¾
if(sta&RX_OK)//½ÓÊÕµ½Êý¾Ý
{
NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//¶ÁÈ¡Êý¾Ý
NRF24L01_Write_Reg(FLUSH_RX,0xff);//Çå³ýRX FIFO¼Ä´æÆ÷
return 0;
}
return 1;//ûÊÕµ½ÈκÎÊý¾Ý
}
//¸Ãº¯Êý³õʼ»¯NRF24L01µ½RXģʽ
//ÉèÖÃRXµØÖ·,дRXÊý¾Ý¿í¶È,Ñ¡ÔñRFƵµÀ,²¨ÌØÂʺÍLNA HCURR
//µ±CE±ä¸ßºó,¼´½øÈëRXģʽ,²¢¿ÉÒÔ½ÓÊÕÊý¾ÝÁË
void NRF24L01_RX_Mode(void)
{
NRF24L01_CE_L;
NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);//дRX½ÚµãµØÖ·
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //ʹÄÜͨµÀ0µÄ×Ô¶¯Ó¦´ð
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01);//ʹÄÜͨµÀ0µÄ½ÓÊÕµØÖ·
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40); //ÉèÖÃRFͨÐÅÆµÂÊ
NRF24L01_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//Ñ¡ÔñͨµÀ0µÄÓÐЧÊý¾Ý¿í¶È
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);//ÉèÖÃTX·¢Éä²ÎÊý,0dbÔöÒæ,2Mbps,µÍÔëÉùÔöÒæ¿ªÆô
NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG, 0x0f);//ÅäÖûù±¾¹¤×÷ģʽµÄ²ÎÊý;PWR_UP,EN_CRC,16BIT_CRC,½ÓÊÕģʽ
NRF24L01_CE_H; //CEΪ¸ß,½øÈë½ÓÊÕģʽ
}
//¸Ãº¯Êý³õʼ»¯NRF24L01µ½TXģʽ
//ÉèÖÃTXµØÖ·,дTXÊý¾Ý¿í¶È,ÉèÖÃRX×Ô¶¯Ó¦´ðµÄµØÖ·,Ìî³äTX·¢ËÍÊý¾Ý,Ñ¡ÔñRFƵµÀ,²¨ÌØÂʺÍLNA HCURR
//PWR_UP,CRCʹÄÜ
//µ±CE±ä¸ßºó,¼´½øÈëRXģʽ,²¢¿ÉÒÔ½ÓÊÕÊý¾ÝÁË
//CEΪ¸ß´óÓÚ10us,ÔòÆô¶¯·¢ËÍ.
void NRF24L01_TX_Mode(void)
{
NRF24L01_CE_L;
NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//дTX½ÚµãµØÖ·
NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //ÉèÖÃTX½ÚµãµØÖ·,Ö÷ҪΪÁËʹÄÜACK
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //ʹÄÜͨµÀ0µÄ×Ô¶¯Ó¦´ð
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //ʹÄÜͨµÀ0µÄ½ÓÊÕµØÖ·
NRF24L01_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);//ÉèÖÃ×Ô¶¯ÖØ·¢¼ä¸ôʱ¼ä:500us + 86us;×î´ó×Ô¶¯ÖØ·¢´ÎÊý:10´Î
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40); //ÉèÖÃRFͨµÀΪ40
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f); //ÉèÖÃTX·¢Éä²ÎÊý,0dbÔöÒæ,2Mbps,µÍÔëÉùÔöÒæ¿ªÆô
NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG,0x0e); //ÅäÖûù±¾¹¤×÷ģʽµÄ²ÎÊý;PWR_UP,EN_CRC,16BIT_CRC,½ÓÊÕģʽ,¿ªÆôËùÓÐÖжÏ
NRF24L01_CE_H;//CEΪ¸ß,10usºóÆô¶¯·¢ËÍ
}
NRF24L01.h
#ifndef _nrf24l01_H
#define _nrf24l01_H
#include "SPI.h"
#include "stm32f10x.h"
#include "usart.h"
//24L01²Ù×÷Ïß Ò»¹²8¸ùÏߣ¬ÆäÖÐÁ½¸ùµçÔ´Ïß ÒÔÏÂΪÆäÓàÁù¸ùÏß×öÈçÏ·â×°
#define NRF24L01_Port GPIOB
#define NRF24L01_CE GPIO_Pin_8 //24L01ƬѡÐźÅ
#define NRF24L01_CSN GPIO_Pin_9 //SPIƬѡÐźÅ
#define NRF24L01_IRQ GPIO_Pin_6 //IRQÖ÷»úÊý¾ÝÊäÈë
//ĬÈÏÈý¸ùÏ߸úSPIÓ²¼þÓйØ
#define NRF24L01_CSN_L GPIO_ResetBits(NRF24L01_Port,NRF24L01_CSN)
#define NRF24L01_CSN_H GPIO_SetBits(NRF24L01_Port,NRF24L01_CSN)
#define NRF24L01_CE_L GPIO_ResetBits(NRF24L01_Port,NRF24L01_CE)
#define NRF24L01_CE_H GPIO_SetBits(NRF24L01_Port,NRF24L01_CE)
#define NRF24L01_IRQ_L GPIO_ResetBits(NRF24L01_Port,NRF24L01_IRQ)
#define NRF24L01_IRQ_H GPIO_SetBits(NRF24L01_Port,NRF24L01_IRQ)
//24L01·¢ËͽÓÊÕÊý¾Ý¿í¶È¶¨Òå
#define TX_ADR_WIDTH 5 //5×ֽڵĵØÖ·¿í¶È
#define RX_ADR_WIDTH 5 //5×ֽڵĵØÖ·¿í¶È
#define TX_PLOAD_WIDTH 32 //32×Ö½ÚµÄÓû§Êý¾Ý¿í¶È
#define RX_PLOAD_WIDTH 32 //32×Ö½ÚµÄÓû§Êý¾Ý¿í¶È
//NRF24L01¼Ä´æÆ÷²Ù×÷ÃüÁî
#define NRF_READ_REG 0x00 //¶ÁÅäÖüĴæÆ÷,µÍ5λΪ¼Ä´æÆ÷µØÖ·
#define NRF_WRITE_REG 0x20 //дÅäÖüĴæÆ÷,µÍ5λΪ¼Ä´æÆ÷µØÖ·
#define RD_RX_PLOAD 0x61 //¶ÁRXÓÐЧÊý¾Ý,1~32×Ö½Ú
#define WR_TX_PLOAD 0xA0 //дTXÓÐЧÊý¾Ý,1~32×Ö½Ú
#define FLUSH_TX 0xE1 //Çå³ýTX FIFO¼Ä´æÆ÷.·¢ÉäģʽÏÂÓÃ
#define FLUSH_RX 0xE2 //Çå³ýRX FIFO¼Ä´æÆ÷.½ÓÊÕģʽÏÂÓÃ
#define REUSE_TX_PL 0xE3 //ÖØÐÂʹÓÃÉÏÒ»°üÊý¾Ý,CEΪ¸ß,Êý¾Ý°ü±»²»¶Ï·¢ËÍ.
#define NOP 0xFF //¿Õ²Ù×÷,¿ÉÒÔÓÃÀ´¶Á״̬¼Ä´æÆ÷
//SPI(NRF24L01)¼Ä´æÆ÷µØÖ·
#define CONFIG 0x00 //ÅäÖüĴæÆ÷µØÖ·;bit0:1½ÓÊÕģʽ,0·¢Éäģʽ;bit1:µçÑ¡Ôñ;bit2:CRCģʽ;bit3:CRCʹÄÜ;
//bit4:ÖжÏMAX_RT(´ïµ½×î´óÖØ·¢´ÎÊýÖжÏ)ʹÄÜ;bit5:ÖжÏTX_DSʹÄÜ;bit6:ÖжÏRX_DRʹÄÜ
#define EN_AA 0x01 //ʹÄÜ×Ô¶¯Ó¦´ð¹¦ÄÜ bit0~5,¶ÔӦͨµÀ0~5
#define EN_RXADDR 0x02 //½ÓÊÕµØÖ·ÔÊÐí,bit0~5,¶ÔӦͨµÀ0~5
#define SETUP_AW 0x03 //ÉèÖõØÖ·¿í¶È(ËùÓÐÊý¾ÝͨµÀ):bit1,0:00,3×Ö½Ú;01,4×Ö½Ú;02,5×Ö½Ú;
#define SETUP_RETR 0x04 //½¨Á¢×Ô¶¯ÖØ·¢;bit3:0,×Ô¶¯ÖØ·¢¼ÆÊýÆ÷;bit7:4,×Ô¶¯ÖØ·¢ÑÓʱ 250*x+86us
#define RF_CH 0x05 //RFͨµÀ,bit6:0,¹¤×÷ͨµÀƵÂÊ;
#define RF_SETUP 0x06 //RF¼Ä´æÆ÷;bit3:´«ÊäËÙÂÊ(0:1Mbps,1:2Mbps);bit2:1,·¢É书ÂÊ;bit0:µÍÔëÉù·Å´óÆ÷ÔöÒæ
#define STATUS 0x07 //״̬¼Ä´æÆ÷;bit0:TX FIFOÂú±êÖ¾;bit3:1,½ÓÊÕÊý¾ÝͨµÀºÅ(×î´ó:6);bit4,´ïµ½×î¶à´ÎÖØ·¢
//bit5:Êý¾Ý·¢ËÍÍê³ÉÖжÏ;bit6:½ÓÊÕÊý¾ÝÖжÏ;
#define MAX_TX 0x10 //´ïµ½×î´ó·¢ËÍ´ÎÊýÖжÏ
#define TX_OK 0x20 //TX·¢ËÍÍê³ÉÖжÏ
#define RX_OK 0x40 //½ÓÊÕµ½Êý¾ÝÖжÏ
#define OBSERVE_TX 0x08 //·¢Ëͼì²â¼Ä´æÆ÷,bit7:4,Êý¾Ý°ü¶ªÊ§¼ÆÊýÆ÷;bit3:0,ÖØ·¢¼ÆÊýÆ÷
#define CD 0x09 //ÔØ²¨¼ì²â¼Ä´æÆ÷,bit0,ÔØ²¨¼ì²â;
#define RX_ADDR_P0 0x0A //Êý¾ÝͨµÀ0½ÓÊÕµØÖ·,×î´ó³¤¶È5¸ö×Ö½Ú,µÍ×Ö½ÚÔÚǰ
#define RX_ADDR_P1 0x0B //Êý¾ÝͨµÀ1½ÓÊÕµØÖ·,×î´ó³¤¶È5¸ö×Ö½Ú,µÍ×Ö½ÚÔÚǰ
#define RX_ADDR_P2 0x0C //Êý¾ÝͨµÀ2½ÓÊÕµØÖ·,×îµÍ×Ö½Ú¿ÉÉèÖÃ,¸ß×Ö½Ú,±ØÐëͬRX_ADDR_P1[39:8]ÏàµÈ;
#define RX_ADDR_P3 0x0D //Êý¾ÝͨµÀ3½ÓÊÕµØÖ·,×îµÍ×Ö½Ú¿ÉÉèÖÃ,¸ß×Ö½Ú,±ØÐëͬRX_ADDR_P1[39:8]ÏàµÈ;
#define RX_ADDR_P4 0x0E //Êý¾ÝͨµÀ4½ÓÊÕµØÖ·,×îµÍ×Ö½Ú¿ÉÉèÖÃ,¸ß×Ö½Ú,±ØÐëͬRX_ADDR_P1[39:8]ÏàµÈ;
#define RX_ADDR_P5 0x0F //Êý¾ÝͨµÀ5½ÓÊÕµØÖ·,×îµÍ×Ö½Ú¿ÉÉèÖÃ,¸ß×Ö½Ú,±ØÐëͬRX_ADDR_P1[39:8]ÏàµÈ;
#define TX_ADDR 0x10 //·¢Ë͵ØÖ·(µÍ×Ö½ÚÔÚǰ),ShockBurstTMģʽÏÂ,RX_ADDR_P0Óë´ËµØÖ·ÏàµÈ
#define RX_PW_P0 0x11 //½ÓÊÕÊý¾ÝͨµÀ0ÓÐЧÊý¾Ý¿í¶È(1~32×Ö½Ú),ÉèÖÃΪ0Ôò·Ç·¨
#define RX_PW_P1 0x12 //½ÓÊÕÊý¾ÝͨµÀ1ÓÐЧÊý¾Ý¿í¶È(1~32×Ö½Ú),ÉèÖÃΪ0Ôò·Ç·¨
#define RX_PW_P2 0x13 //½ÓÊÕÊý¾ÝͨµÀ2ÓÐЧÊý¾Ý¿í¶È(1~32×Ö½Ú),ÉèÖÃΪ0Ôò·Ç·¨
#define RX_PW_P3 0x14 //½ÓÊÕÊý¾ÝͨµÀ3ÓÐЧÊý¾Ý¿í¶È(1~32×Ö½Ú),ÉèÖÃΪ0Ôò·Ç·¨
#define RX_PW_P4 0x15 //½ÓÊÕÊý¾ÝͨµÀ4ÓÐЧÊý¾Ý¿í¶È(1~32×Ö½Ú),ÉèÖÃΪ0Ôò·Ç·¨
#define RX_PW_P5 0x16 //½ÓÊÕÊý¾ÝͨµÀ5ÓÐЧÊý¾Ý¿í¶È(1~32×Ö½Ú),ÉèÖÃΪ0Ôò·Ç·¨
#define NRF_FIFO_STATUS 0x17 //FIFO״̬¼Ä´æÆ÷;bit0,RX FIFO¼Ä´æÆ÷¿Õ±êÖ¾;bit1,RX FIFOÂú±êÖ¾;bit2,3,±£Áô
//bit4,TX FIFO¿Õ±êÖ¾;bit5,TX FIFOÂú±êÖ¾;bit6,1,Ñ»··¢ËÍÉÏÒ»Êý¾Ý°ü.0,²»Ñ»·;
//
void NRF24L01_Init(void); //³õʼ»¯
void NRF24L01_RX_Mode(void); //ÅäÖÃΪ½ÓÊÕģʽ
void NRF24L01_TX_Mode(void); //ÅäÖÃΪ·¢ËÍģʽ
u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 u8s);//дÊý¾ÝÇø
u8 NRF24L01_Read_Buf(u8 reg, u8 *pBuf, u8 u8s); //¶ÁÊý¾ÝÇø
u8 NRF24L01_Read_Reg(u8 reg); //¶Á¼Ä´æÆ÷
u8 NRF24L01_Write_Reg(u8 reg, u8 value); //д¼Ä´æÆ÷
u8 NRF24L01_Check(void); //¼ì²é24L01ÊÇ·ñ´æÔÚ
u8 NRF24L01_TxPacket(u8 *txbuf); //·¢ËÍÒ»¸ö°üµÄÊý¾Ý
u8 NRF24L01_RxPacket(u8 *rxbuf); //½ÓÊÕÒ»¸ö°üµÄÊý¾Ý
#endif
初始化串口1usart.c以及printf重定向
// USART1初始化
void myusart_init(void)
{
GPIO_InitTypeDef GPIOInitStruct;
USART_InitTypeDef USARTInitStruct;
NVIC_InitTypeDef NVIC_Initstruct;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);
//A9 TX
GPIOInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIOInitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIOInitStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOA,&GPIOInitStruct);
//A10 RX
GPIOInitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIOInitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA,&GPIOInitStruct);
USARTInitStruct.USART_BaudRate = 115200;
USARTInitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USARTInitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USARTInitStruct.USART_Parity = USART_Parity_No;
USARTInitStruct.USART_StopBits = USART_StopBits_1;
USARTInitStruct.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1,&USARTInitStruct);
USART_Cmd(USART1,ENABLE);
USART_ITConfig(USART1, USART_IT_RXNE,ENABLE);
NVIC_Initstruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_Initstruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_Initstruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Initstruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_Initstruct);
}
int fputc(int ch, FILE *p)//printfÖØ¶¨Ïò
{
USART_SendData(USART1, (u8)ch);
while (USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
return ch;
}
spi.c(这里初始化SPI2可以随意因为驱动程序里重新初始化了)
#include "stm32f10x.h"
#include "spi.h"
void SPI2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
SPI_InitTypeDef SPI_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
//SPI2:SCK:PB13、MISO:PB14、MOSI:PB15
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
GPIO_SetBits(GPIOB, GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
SPI_InitStruct.SPI_Direction =SPI_Direction_2Lines_FullDuplex;//SPI设置为双线双向全双工
SPI_InitStruct.SPI_Mode = SPI_Mode_Master; //设置为主模式
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;//设置SPI数据大小为8位
SPI_InitStruct.SPI_CPOL = SPI_CPOL_High; //设置SPI默认时钟悬空为高电平
SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge; //设置SPI数据捕获在第二个时钟沿
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft; //设置SPI NSS引脚由软件管理
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;//设置波特率预分频值为256
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;//设置SPI模式为从高位传输
SPI_InitStruct.SPI_CRCPolynomial = 7;//设置SPI_CRC值计算的多项式
SPI_Init(SPI2,&SPI_InitStruct);
SPI_Cmd(SPI2, ENABLE ); //使能SPI2外设
}
//SPI2读写一个字节
u8 SPI2_ReadWriteByte(u8 dat)
{
u8 t;
while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE) == RESET)//等待发送缓存器为空
{
t++;
if(t>=200)
{
return 0;//超时返回错误标志
}
}
SPI_I2S_SendData(SPI2,dat);
while( SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET)//等待接收
{
t++;
if(t>=200)
{
return 0;//超时返回错误标志
}
}
return SPI_I2S_ReceiveData(SPI2);
}
//设置SPI波特率
void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler )
{
SPI_Cmd(SPI2,DISABLE);//修改波特率前需禁用SPI
assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
SPI2->CR1 &= 0XFFC7;//将SPI控制寄存器1(CR1)的BR[2:0]3、4、5位清零,其他位不变这三位控制波特率预分频系数
SPI2->CR1 |= SPI_BaudRatePrescaler;//将新的预分频值写入CR1的BR位
SPI_Cmd(SPI2, ENABLE );
}
spi.h
#ifndef _SPI_H_
#define _SPI_H_
#include "stm32f10x.h"
void SPI2_Init(void);
u8 SPI2_ReadWriteByte(u8 dat);
void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler );
#endif
main.c
extern u8 tx_buf[33];
extern u8 rx_buf[33];
int main(void)
{
myusart_init();
NRF24L01_Init();
while(NRF24L01_Check()) //检测NRF24L01是否存在
{
printf("Error \n ");
}
NRF24L01_TX_Mode(); //TX模式
if(NRF24L01_TxPacket(tx_buf) == MAX_TX )//达到最大重发次数
{
printf(" %s \r\n",tx_buf); //打印发送的数据
}
while(1)
{
}
}
接线的话参考NRF24L01.h和SPI.c的标注