nrf24le1学习笔记
24L01详细经验之谈

每次开始spi写,读回来的都是状态字。
射频收发工作在2.4~2.4835G
收发共用天线接口
GFSK调制
250k,1M,2M的空中速率
发射输出功率最高0dBm,即1mW
6路1对6星型网络(使用6个data pipe)
#define NOP 0xFF//保留
//*****************SPI(nRF24L01)寄存器地址****************************************************
#define CONFIG 0x00 //配置收发状态,CRC校验模式以及收发状态响应方式
/*reg:待写入的寄存器;value:待写入的值*/
ucharSPI_RW_Reg(uchar reg, uchar value)
{
ucharstatus;定义uchar变量status
CSN = 0;//片选非
status = SPI_RW(reg);//待写入的寄存器地址reg
SPI_RW(value);//写入值为value
自动应答的延时和重发次数是可编程的。
/********************************************************************************/
/*函数:void SetRX_Mode(void)
/*功能:数据接收配置
/********************************************************************************/
nRF24L01无线模块讲解解读

数据通道
nRF24L01 在接收模式下可以接收6 路不同通道的数据。
数据通道
• 每一个数据通道使用不同的地址,但是共用相同的频道。 也就是说6 个不同的nRF24L01 设置为发送模式后可以与 同一个设置为接收模式的nRF24L01 进行通讯,而设置为 接收模式的nRF24L01 可以对这6 个发射端进行识别。 • 数据通道是通过寄存器EN_RXADDR 来设置的,默认状 态下只有数据通道0 和数据通道1 是开启状态的。 • nRF24L01在确认收到数据后记录地址,并以此地址为目 标地址发送应答信号,在发送端,数据通道0被用作接收 应答信号,因此属通道0 的接收地址要与发送地址端地址 相等,以确保接收到正确的应答信号。
封装引脚及其引脚功能
nRF单端50Ω射频输出原理图
nRF24L10与单片机应用电路图
举例:NRF24L01模块口与STM32连接原理图中断
• nRF24L01 的中断引脚(IRQ)为低电平触发,当状态寄 存器中TX_DS(数据发送完成中断位)、RX_DR(接收 数据中断位) 或MAX_RT(达到最多次重发中断位)为 高时触发中断。 • 当MCU 给中断源写‘1’时,中断引脚被禁止。可屏蔽中 断可以被IRQ 中断屏蔽。通过设置可屏蔽中断位为高,则 中断响应被禁止。默认状态下所有的中断源是被禁止的。
nRF24l01的SPI通信时序
增强型ShockBurstTM 发送模式
• 1、 配置寄存器位PRIM_RX 为低 • 2、 当MCU 有数据要发送时,接收节点地址(TX_ADDR) 和有效数据(TX_PLD)通过SPI 接口写入nRF24L01。发送 数据的长度以字节计数从MCU 写入TX FIFO。当CSN 为 低时数据被不断的写入。发送端发送完数据后,将通道0 设置为接收模式来接收应答信号,其接收地址 (RX_ADDR_P0)与接收端地址(TX_ADDR)相同。 例:在上图 中数据通道5 的发送端(TX5)及接收端(RX)地 址设置如下: TX5:TX_ADDR=0xB3B4B5B605 TX5:RX_ADDR_P0=0xB3B4B5B605 RX:RX_ADDR_P5=0xB3B4B5B605
nrf24l01中文资料

nrf24l01中⽂资料NRF24L01⼀、初步认识⼀下NRF24L01是Nordic公司研发的⼀款2.4G通信芯⽚。
它不是zigbee、不是蓝⽛、不是wifi,它拥有的是⾃⼰的⼀套协议。
既然是通信芯⽚,⽽且有⾃⼰的协议,那说明这个芯⽚只能是⽤在NRF24L01与NRF24L01或者Nordic公司此系列的芯⽚通信,⼀般情况下,⽤在2个NRF24L01之间的通信,任何⼀个模块都可以设置为接收或者发送模式,⽽且可由主控单⽚机随时根据需要设置为发送或者接收模式。
⼆、深⼊认识⼀下NRF24L01是⼀个长着20个引脚的数字射频芯⽚,内部有若⼲寄存器,外部留有spi接⼝,外部单⽚机通过spi接⼝配置此芯⽚内部的寄存器。
内部寄存器⼤概分为控制寄存器和数据寄存器。
我们可以利⽤⽤单⽚机把它配置为接收模式或发送模式,还可以配置频道、地址、每次发送的字节数、是否带CRC校验、功率等。
配置成发送模式以后,⽤单⽚机把要发送的数据写进去,它就会⾃动把数据发出去;配置成接收模式以后,单⽚机通过观察它的IRQ引脚,就可以知道是否接收到了数据,IRQ为低电平,说明接收到了数据,单⽚机可以通过SPI⼝把接收到数据取出来。
三、通信条件两个nrf24l01通信,需要满⾜3个条件相同:1.频道相同(设置频道寄存器RF_CH)2.地址相同(设置TX_ADDR和RX_ADDR_P0相同)3.每次发送接收的字节数相同(如果设置了通道的有效数据宽度为n,那么每次发送的字节数也必须为n,当然,n<=32)四、是否可以⼀对多相互通信?答:可以。
nrf24l01最多⼀对⼏个呢?答案是⽆数个!官⽅⼿册上说,nrf24l01可以⼀对六,指的是⾃⾝的通道有6个,⽽且这种模式只能是1收6发,不能1发6收。
所以我们⼀般不⽤这种⽅式。
我们⼀般只⽤nrf24l01的通道0,通过改变频道和地址来实现1对多的互发。
它属于2.4G芯⽚,但实际上,可以在2.4G到2.5G之间的频道上通信,⼀共有125个频道,它的地址是5字节的。
NRF24L01通道使用(DOC)

网上面关于多通道通信的好多资源都可以去共享,我也下了好多去调试,结果发现基本上都是调不通的。
其实这个归根到底还是一个地址匹配问题,通道0和1还好说,它是默认开启的,一般没问题,但通道2至5,通道如何匹配,数据手册上也只是说地址要匹配,到底要怎么做它没讲。
下面什么都不说了,直接上程序,这是用PIC16F877A来控制的,我会把要注意的重点标记出来,当然主要是多通道地址匹配的,其它的我就不多说了自己领悟。
接收部分:#include <pic.h> //调用头文件,可以去PICC软件下去查找PIC16F88X单片机的头文件__CONFIG(XT&WDTDIS&LVPDIS&BORDIS); //定义配置字,晶振类型:XT,关闭开门狗,禁止低电压编程,禁止欠压复位#define u8 unsigned char#define u16 unsigned int#define BUZZER RB1u8 i=0,a=0,data[13]=0;#define NRF24L01_MISO RC4#define NRF24L01_MOSI RC5 //输出#define NRF24L01_SCK RC3 //输出#define NRF24L01_CE RC0 //使能控制设为输出#define NRF24L01_CSN RC2 //片选控制设为输出#define NRF24L01_IRQ RC1 //中断标志设为输入#define RS RE0#define RW RE1#define E RE2unsigned char SPIx_ReadWriteByte(unsigned char byte){unsigned char data;SSPBUF=byte;do{;}while(SSPIF==0);SSPIF=0;data=SSPBUF;return(data); // return read byte}//24L01操作线//#define NRF24L01_CE PAout(4) //24L01片选信号//#define NRF24L01_CSN PCout(4) //SPI片选信号//#define NRF24L01_IRQ PCin(5) //IRQ主机数据输入#define READ_REG 0x00 //读配置寄存器,低5位为寄存器地址#define 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 pop 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 FIFO_STATUS 0x17 //FIFO状态寄存器;bit0,RXFIFO寄存器空标志;bit1,RX FIFO满标志;bit2,3,保留//bit4,TX FIFO空标志;bit5,TX FIFO满标志;bit6,1,循环发送上一数据包.0,不循环;///////////////////////////////////////////////////// /////////////////////////////////////////24L01发送接收数据宽度定义#define TX_ADR_WIDTH 5 //5字节的地址宽度#define RX_ADR_WIDTH 5 //5字节的地址宽度#define TX_PLOAD_WIDTH 32 //20字节的用户数据宽度#define RX_PLOAD_WIDTH 32 //20字节的用户数据宽度void NRF24L01_Init(void);//初始化void RX_Mode(void);//配置为接收模式void 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);//接收一个包的数据const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x0 1}; //本地发送地址const u8 RX_ADDRESS0[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0 x01}; //接收0通道地址const u8 RX_ADDRESS1[RX_ADR_WIDTH]={0xc2,0xc2,0xc2,0xc2,0x c1}; //接收1通道地址const u8 RX_ADDRESS2[1]={0xb3}; //接收2通道地址const u8 RX_ADDRESS3[1]={0xa5}; //接收3通道地址const u8 RX_ADDRESS4[1]={0x35}; //接收4通道地址const u8 RX_ADDRESS5[1]={0x8f}; //接收5通道地址/********************************************/void delay1(unsigned char n){unsigned int m;for(;n>0;n--)for(m=0;m<100;m++){asm("NOP");}}void lcd_busy(){TRISD7=1; /*1602上DB7=1表明总线忙,同时RS=0 选择指令寄存器,RSS=1是选择数据寄存器*/RS=0;RW=1;E=1;while(RD7==1);E=0;TRISD7=0;}void lcd_write_commend(unsigned char u){lcd_busy();RS=0;RW=0;PORTD=u;E=1;asm("NOP");E=0;}void lcd_write_data(unsigned char k){lcd_busy();RS=1;RW=0;PORTD=k;E=1;asm("NOP");E=0;}void lcd_1602_ddram_add(u8 x,u8 y)//x是列,y是行,ddram是字符显示的地址{if(y==1){lcd_write_commend(0x80+x);}if(y==2){lcd_write_commend(0xc0+x);}}void lcd_disp(unsigned char x,unsigned char y,unsigned char l){x&=0x0f;//列地址限制在0-15y&=0x01;if(y==0x00)lcd_write_commend(x|0x80); //第一行的列地址写入elselcd_write_commend((x+0x40)|0x80); //第二行的列地址写入lcd_write_data(l+0x30);}void lcd_1602_display_shu(u8 num,u16 shu,u8 x,u8 y)//在液晶的任何位置显示五位内的数字{u8 wan,qian,bai,shi,ge;if(num>=1) ge=shu%10;if(num>=2) shi=shu%100/10;if(num>=3) bai=shu%1000/100;if(num>=4) qian=shu%10000/1000; if(num==5) wan=shu/10000;lcd_1602_ddram_add(x,y);if(num==1)lcd_write_data(ge|0x30);if(num==2){lcd_write_data(shi|0x30);lcd_write_data(ge|0x30);}if(num==3){lcd_write_data(bai|0x30);lcd_write_data(shi|0x30);lcd_write_data(ge|0x30);}if(num==4){lcd_write_data(qian|0x30);lcd_write_data(bai|0x30);lcd_write_data(shi|0x30);lcd_write_data(ge|0x30);}if(num==5){lcd_write_data(wan|0x30);lcd_write_data(qian|0x30);lcd_write_data(bai|0x30);lcd_write_data(shi|0x30);lcd_write_data(ge|0x30);}}void init_1602(){TRISD=0x00;TRISE=0x00;ADCON1=0X82;PORTE=0;PORTD=0;lcd_write_commend(0x38); /*这里的设置是更具需要,选择1602的各项配置,1602共有11条指令*/delay1(100);lcd_write_commend(0x38); /*这里的设置是更具需要,选择1602的各项配置,1602共有11条指令*/delay1(100);lcd_write_commend(0x38); /*这里的设置是更具需要,选择1602的各项配置,1602共有11条指令*/delay1(100);lcd_write_commend(0x38); //8位数据,双列,5*7字形lcd_write_commend(0x08);//显示功能关,无光标lcd_write_commend(0x01);//清屏指令lcd_write_commend(0x06);//写入新的数据后,光标右移,显示屏不移动lcd_write_commend(0x0c);//显示功能开,无光标,}/**********************汉字显示的代码******************************/const u8 hz1[]={0x1F,0x11,0x11,0x1F,0x11,0x11,0x11,0x1F};//日const u8 hz2[]={0x0F,0x09,0x0F,0x09,0x0F,0x09,0x09,0x13};//月const u8 hz3[]={0x04,0x0F,0x12,0x0F,0x0A,0x1F,0x02,0x02};//年const u8 hz4[]={0x1F,0x1F,0x04,0x04,0x04,0x04,0x1F,0x1F};//工const u8 hz5[]={0x0E,0x0A,0x0E,0x1F,0x04,0x07,0x03,0x01};//号void CGRAM(const u8 *hz,const u8 temp) //自定义字符存储{u8 i;for(i=0;i<8;i++){lcd_write_commend(temp+i);lcd_write_data(*(hz+i));}}/*******************************************///SPI写寄存器//reg:指定寄存器地址//value:写入的值u8 NRF24L01_Write_Reg(u8 reg,u8 value){u8 status;NRF24L01_CSN=0; //使能SPI传输status =SPIx_ReadWriteByte(reg);//发送寄存器号SPIx_ReadWriteByte(value); //写入寄存器的值NRF24L01_CSN=1; //禁止SPI传输return(status); //返回状态值}//读取SPI寄存器值//reg:要读的寄存器u8 NRF24L01_Read_Reg(u8 reg){u8 reg_val;NRF24L01_CSN = 0; //使能SPI传输SPIx_ReadWriteByte(reg); //发送寄存器号reg_val=SPIx_ReadWriteByte(0XFF);//读取寄存器内容NRF24L01_CSN = 1; //禁止SPI传输return(reg_val); //返回状态值}//在指定位置读出指定长度的数据//reg:寄存器(位置)//*pBuf:数据指针//len:数据长度//返回值,此次读到的状态寄存器值u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len){u8 status,u8_ctr;NRF24L01_CSN = 0; //使能SPI传输status=SPIx_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值for(u8_ctr=0;u8_ctr<len;u8_ctr++)pBuf[u8_ctr]=SPIx_Rea dWriteByte(0XFF);//读出数据NRF24L01_CSN=1; //关闭SPI传输return status; //返回读到的状态值}//在指定位置写指定长度的数据//reg:寄存器(位置)//*pBuf:数据指针//len:数据长度//返回值,此次读到的状态寄存器值u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len){u8 status,u8_ctr;NRF24L01_CSN = 0; //使能SPI传输status = SPIx_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值for(u8_ctr=0; u8_ctr<len; u8_ctr++)SPIx_ReadWriteByte(*pBuf++); //写入数据NRF24L01_CSN = 1; //关闭SPI传输return status; //返回读到的状态值}//启动NRF24L01发送一次数据//txbuf:待发送数据首地址//返回值:0,接收完成;其他,错误代码u8 NRF24L01_RxPacket(u8 *rxbuf){u8 sta;//SPIx_SetSpeed(SPI_SPEED_8); //spi速度为9Mhz (24L01的最大SPI时钟为10Mhz)sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值NRF24L01_Write_Reg(WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志if(sta&RX_OK)//接收到数据{NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WID TH);//读取数据NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器return 0;}return 1;//没收到任何数据}//该函数初始化NRF24L01到RX模式//设置RX地址,写RX数据宽度,选择RF频道,波特率和LNA HCURR //当CE变高后,即进入RX模式,并可以接收数据了void RX_Mode(void){NRF24L01_CE=0;NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,(u8*)TX_ ADDRESS,RX_ADR_WIDTH);//接收设备接收通道0使用和发送设备相同的发送地址NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P1,(u8*)RX_ ADDRESS1,RX_ADR_WIDTH);//接收设备接收通道1使用和发送设备相同的发送地址NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P2,(u8*)RX_ ADDRESS2,1);//接收设备接收通道2使用和发送设备相同的发送地址NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P3,(u8*)RX_ ADDRESS3,1);//接收设备接收通道3使用和发送设备相同的发送地址NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P4,(u8*)RX_ ADDRESS4,1);//接收设备接收通道4使用和发送设备相同的发送地址NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P5,(u8*)RX_ ADDRESS5,1);//接收设备接收通道5使用和发送设备相同的发送地址NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x3f);//使能通道0到5的自动应答NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x3f);//使能通道0到5的接收地址NRF24L01_Write_Reg(WRITE_REG+RF_CH,40); //设置RF通信频率NRF24L01_Write_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_ WIDTH);//选择通道0的有效数据宽度NRF24L01_Write_Reg(WRITE_REG+RX_PW_P1,RX_PLOAD_ WIDTH);//选择通道1的有效数据宽度NRF24L01_Write_Reg(WRITE_REG+RX_PW_P2,RX_PLOAD_ WIDTH);//选择通道2的有效数据宽度NRF24L01_Write_Reg(WRITE_REG+RX_PW_P3,RX_PLOAD_ WIDTH);//选择通道3的有效数据宽度NRF24L01_Write_Reg(WRITE_REG+RX_PW_P4,RX_PLOAD_ WIDTH);//选择通道4的有效数据宽度NRF24L01_Write_Reg(WRITE_REG+RX_PW_P5,RX_PLOAD_ WIDTH);//选择通道5的有效数据宽度NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x0f);//设置TX发射参数,0db增益,2Mbps,低噪声增益开启NRF24L01_Write_Reg(WRITE_REG+CONFIG, 0x0f);//配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式NRF24L01_CE = 1; //CE为高,进入接收模式}void delay(unsigned int m){unsigned int n;n=m;for(;n>0;n--)NOP();}void spi_init(){TRISC=0x13;SSPSTAT=0xc0;SSPCON=0x20;}void INT1(){TRISB=0x00;PORTB=0xfc;INTEDG = 1;INTF = 0;INTE = 1;GIE = 1;}void main(){u8 x=3;spi_init();init_1602();INT1();NRF24L01_CE=0;// chip enableNRF24L01_CSN=1;// Spi disable//NRF24L01_SCK=0;// Spi clock line init highCGRAM(hz1,0x40);CGRAM(hz2,0x48);CGRAM(hz3,0x50);CGRAM(hz4,0x58);CGRAM(hz5,0x60);//将这五个字写到1602用户自定义CGRAM中while(1){RX_Mode();NOP();if(NRF24L01_RxPacket(data)==0){lcd_write_commend(0x80);//第一行第一个字lcd_write_data(0x52);//显示接收的字母Rlcd_1602_display_shu(4,2013,x,1);//显示4位数的年份lcd_write_data(2); //显示汉字年lcd_1602_display_shu(2,8,x+5,1);//显示月份lcd_write_data(1); //显示汉字月lcd_1602_display_shu(2,7,x+8,1);//显示日期lcd_write_data(0); //显示汉字日lcd_write_commend(0xc0);//第二行显示lcd_write_data(3); //显示汉字工lcd_write_data(4); //显示汉字号lcd_write_commend(0xc0|0x02);//隔两格lcd_write_data(0x3A);//显示封号for(i=0;i<13;i++)//显示工人编号{lcd_disp(i+3,1,data[i]);}if(data[12]==1)RB0=1;elseRB0=0;}}}void interrupt ISR(void) {u16 y;if(INTF == 1){INTF = 0;asm("NOP");for(y=0;y<4000;y++){BUZZER=1;delay(20);BUZZER=0;}}}发送部分:#include <pic.h> //调用头文件,可以去PICC软件下去查找PIC16F88X单片机的头文件__CONFIG(XT&WDTDIS&LVPDIS&BORDIS); //定义配置字,晶振类型:XT,关闭开门狗,禁止低电压编程,禁止欠压复位#define u8 unsigned char#define u16 unsigned int#define key RB0u8 test[13]={2,0,1,2,5,8,0,8,0,2,1,5};u16 i=0;#define NRF24L01_MISO RC4#define NRF24L01_MOSI RC5 //输出#define NRF24L01_SCK RC3 //输出#define NRF24L01_CE RC0 //使能控制设为输出#define NRF24L01_CSN RC2 //片选控制设为输出#define NRF24L01_IRQ RC1 //中断标志设为输入*/#define RS RE0 //数据/命令选择#define RW RE1 //读/写选择#define E RE2 //使能信号unsigned char SPIx_ReadWriteByte(unsigned char byte){unsigned char data;SSPBUF=byte;do{;}while(SSPIF==0);SSPIF=0;data=SSPBUF;return(data); // return read byte}#define READ_REG 0x00 //读配置寄存器,低5位为寄存器地址#define 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 pop 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 FIFO_STATUS 0x17 //FIFO状态寄存器;bit0,RX FIFO寄存器空标志;bit1,RX FIFO满标志;bit2,3,保留//bit4,TX FIFO空标志;bit5,TX FIFO满标志;bit6,1,循环发送上一数据包.0,不循环;///////////////////////////////////////////////////// ///////////////////////////////////////////////////////24L01发送接收数据宽度定义#define TX_ADR_WIDTH 5 //5字节的地址宽度#define RX_ADR_WIDTH 5 //5字节的地址宽度#define TX_PLOAD_WIDTH 32 //20字节的用户数据宽度#define RX_PLOAD_WIDTH 32 //20字节的用户数据宽度void NRF24L01_Init(void);//初始化void RX_Mode(void);//配置为接收模式void 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);//接收一个包的数据//下面这里就是重点啦,看看我用线条标出的是32位公用的地址,红色部分是低八位,注意位置啊啊啊啊啊啊const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x35,0xc2,0xc2,0xc2,0xc 1}; //发送地址const u8 RX_ADDRESS0[RX_ADR_WIDTH]={0x35,0xc2,0xc2,0xc2,0x c1}; //接收3通道地址,就以通道3为例,其它都一个样//SPI写寄存器//reg:指定寄存器地址//value:写入的值u8 NRF24L01_Write_Reg(u8 reg,u8 value){u8 status;NRF24L01_CSN=0; //使能SPI传输status =SPIx_ReadWriteByte(reg);//发送寄存器号SPIx_ReadWriteByte(value); //写入寄存器的值NRF24L01_CSN=1; //禁止SPI传输return(status); //返回状态值}//读取SPI寄存器值//reg:要读的寄存器u8 NRF24L01_Read_Reg(u8 reg){u8 reg_val;NRF24L01_CSN = 0; //使能SPI传输SPIx_ReadWriteByte(reg); //发送寄存器号reg_val=SPIx_ReadWriteByte(0XFF);//读取寄存器内容NRF24L01_CSN = 1; //禁止SPI传输return(reg_val); //返回状态值}//在指定位置读出指定长度的数据//reg:寄存器(位置)//*pBuf:数据指针//len:数据长度//返回值,此次读到的状态寄存器值u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len){u8 status,u8_ctr;NRF24L01_CSN =0; //使能SPI传输status=SPIx_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值for(u8_ctr=0;u8_ctr<len;u8_ctr++)pBuf[u8_ctr]=SPIx_ReadWriteByte(0XFF);//读出数据NRF24L01_CSN=1; //关闭SPI传输return status; //返回读到的状态值}//在指定位置写指定长度的数据//reg:寄存器(位置)//*pBuf:数据指针//len:数据长度//返回值,此次读到的状态寄存器值u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len){u8 status,u8_ctr;NRF24L01_CSN = 0; //使能SPI传输status = SPIx_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值for(u8_ctr=0; u8_ctr<len; u8_ctr++)SPIx_ReadWriteByte(*pBuf++); //写入数据NRF24L01_CSN = 1; //关闭SPI传输return status; //返回读到的状态值}void delay(unsigned int n){for(;n>0;n--)NOP();}//启动NRF24L01发送一次数据//txbuf:待发送数据首地址//返回值:发送完成状况u8 NRF24L01_TxPacket(u8 *txbuf){u8 sta;//SPIx_SetSpeed(SPI_SPEED_8);//spi速度为9Mhz (24L01的最大SPI时钟为10Mhz)NRF24L01_CE=0; NRF24L01_IRQ=0;NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WID TH);//写数据到TX BUF 32个字节delay(5000);NRF24L01_CE=1;//启动发送delay(5000);while(NRF24L01_IRQ!=0);//等待发送完成sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值NRF24L01_Write_Reg(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;}elsereturn 0xff;//其他原因发送失败}//该函数初始化NRF24L01到TX模式//设置TX地址,写TX数据宽度,设置RX自动应答的地址,填充TX发送数据,选择RF频道,波特率和LNA HCURR//PWR_UP,CRC使能//当CE变高后,即进入RX模式,并可以接收数据了//CE为高大于10us,则启动发送.void TX_Mode(void){NRF24L01_CE=0;NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,(u8*)TX_ADD RESS,TX_ADR_WIDTH);//写TX节点地址NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,(u8*)RX_ ADDRESS0,RX_ADR_WIDTH); //设置RX节点地址,主要为了使能ACK,TX_ADDRESS和RX_ADDRESS0一定要一致,不然就调不通的NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x01);//使能通道0的自动应答NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址NRF24L01_Write_Reg(WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次NRF24L01_Write_Reg(WRITE_REG+RF_CH,40);//设置RF通道为40NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0e);//配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断NRF24L01_CE=1;//CE为高,10us后启动发送NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();}void delay1(unsigned int n){unsigned int m;for(;n>0;n--)for(m=0;m<100;m++){asm("NOP");}}void read_1602_bz()//测忙{TRISD7=1;RS=0;RW=1;E=1;while(RD7==1);E=0;TRISD7=0;}void write_1602_dat(u8 data_1)//写数据{read_1602_bz();RS=1;RW=0;PORTD=data_1;delay(5);E=1;delay(5);E=0;}void write_1602_com(u8 com)//写指令{read_1602_bz();RS=0;RW=0;PORTD=com;delay(5);E=1;delay(5);E=0;}void lcd_1602_ddram_add(u8 x,u8 y)//x是列,y是行,ddram是字符显示的地址{if(y==1){write_1602_com(0x80+x);}if(y==2){write_1602_com(0xc0+x);}}void lcd_disp(unsigned char x,unsigned char y,unsigned charl){x&=0x0f;//列地址限制在0-15y&=0x01;if(y==0x00)write_1602_com(x|0x80); //第一行的列地址写入elsewrite_1602_com((x+0x40)|0x80); //第二行的列地址写入write_1602_dat(l+0x30);}void lcd_1602_display_shu(u8 num,u16 shu,u8 x,u8 y)//在液晶的任何位置显示五位内的数字{u8 wan,qian,bai,shi,ge;if(num>=1) ge=shu%10;if(num>=2) shi=shu%100/10;if(num>=3) bai=shu%1000/100;if(num>=4) qian=shu%10000/1000;if(num==5) wan=shu/10000;lcd_1602_ddram_add(x,y);if(num==1)if(num==2){write_1602_dat(shi|0x30); write_1602_dat(ge|0x30); }if(num==3){write_1602_dat(bai|0x30); write_1602_dat(shi|0x30); write_1602_dat(ge|0x30); }if(num==4){write_1602_dat(qian|0x30); write_1602_dat(bai|0x30); write_1602_dat(shi|0x30); write_1602_dat(ge|0x30); }if(num==5){write_1602_dat(wan|0x30);write_1602_dat(bai|0x30);write_1602_dat(shi|0x30);write_1602_dat(ge|0x30);}}/**********************汉字显示的代码******************************/const u8 hz1[]={0x1F,0x11,0x11,0x1F,0x11,0x11,0x11,0x1F};//日const u8 hz2[]={0x0F,0x09,0x0F,0x09,0x0F,0x09,0x09,0x13};//月const u8 hz3[]={0x04,0x0F,0x12,0x0F,0x0A,0x1F,0x02,0x02};//年void CGRAM(const u8 *hz,const u8 temp) //自定义字符存储{u8 i;for(i=0;i<8;i++){write_1602_com(temp+i);write_1602_dat(*(hz+i));}void init_1602(){TRISE=0x00;TRISD=0x00;//ADCON1=0X82;PCFG3=0;PCFG2=1;PCFG1=1;PCFG0=1; //A端口全部数字化PORTE=0;PORTD=0;write_1602_com(0x38);delay(50);write_1602_com(0x38);delay(50);write_1602_com(0x38);delay(50);write_1602_com(0x0c);write_1602_com(0x06);write_1602_com(0x01);void spi_init(){TRISC=0x13;SSPCON=0x20;SSPSTAT=0xc0;PIR1=0;}void main(){u8 x=3;TRISB0=0;spi_init();init_1602();CGRAM(hz1,0x40);CGRAM(hz2,0x48);CGRAM(hz3,0x50);//将这三个字写到1602用户自定义CGRAM中NRF24L01_CE=0; //使能24L01NRF24L01_CSN=1;//SPI片选取消SPIx_ReadWriteByte(0xff);//启动传输while(1){TX_Mode();if(key==0){delay(1);if(key==0)test[12]=1;}elsetest[12]=0;if(NRF24L01_TxPacket(test)==TX_OK){write_1602_com(0x80);//第一行第一个位置write_1602_dat(0x53);//显示发送的字母Slcd_1602_display_shu(4,2013,x,1);//显示4位数的年份write_1602_dat(2); //显示汉字年lcd_1602_display_shu(2,8,x+5,1);//显示月份write_1602_dat(1); //显示汉字月lcd_1602_display_shu(2,7,x+8,1);//显示日期write_1602_dat(0); //显示汉字日write_1602_com(0xc0);//第二行显示write_1602_dat(0x49); //显示字母Iwrite_1602_dat(0x44); //显示字母Dwrite_1602_com(0xc0|0x02);//隔两格write_1602_dat(0x3A);//显示封号for(i=0;i<13;i++)//显示工人编号{lcd_disp(i+3,1,test[i]);}}}}。
_及_NRF24L01_调试方法经验总结

_及_NRF24L01_调试方法经验总结NRF24L01 :在通信中的应用方法,经验总结(1)2011-07-31 13:15首先说一下:nRF24.L01是一款新型单片射频收发器件,工作于2.4 GHz~2.5 GHz ISM频段。
内置频率合成器、功率放大器、晶体振荡器、调制器等功能模块,并融合了增强型ShockBurst技术,其中输出功率和通信频道可通过程序进行配置。
nRF24L01功耗低,在以-6 dBm的功率发射时,工作电流也只有9 mA;接收时,工作电流只有12.3 mA,多种低功率工作模式(掉电模式和空闲模式)使节能设计更方便。
是想将这个IC调通,首先要多读一下技术文档:下载技术文档以下C51驱动nRF24.L01 的源代码库(nRF24.L01.h)此库文件适合发送端使用,在接收端会有所不同,请看第2 部分的分析在使用过程中,需要引用//****************************************NRF24L01端口定义***************************************sbit CE =P2^0;sbit CSN =P2^1;sbit SCK =P2^2;sbit MOSI =P2^3;sbit MISO =P2^4;sbit IRQ =P2^5;//*********************************************NRF24L01********* ****************************#define TX_ADR_WIDTH 5 // 接收地址宽度,一般设置为5 不要动它#define RX_ADR_WIDTH 5 // 接收地址宽度,一般设置为5 不要动它#define TX_PLOAD_WIDTH 1 //接收数据的数据宽度(最大为32 字节),这里我设置为最小的1 字节,方便调试#define RX_PLOAD_WIDTH 1 //发送数据的数据宽度(最大为32 字节),这里我设置为最小的1 字节,方便调试uchar const TX_ADDRESS[TX_ADR_WIDTH]={0x35,0x43,0x10,0x10,0x03}; // 这里就是设置了5 个字节的本地地址/*此处的地址:在IC内部真实地址是反过来的。
NRF24LE1无线通信机制

1 系统框图如下:NRF24LE1通过SPI与模块NM1010、无线收发器通信。
通信流程如下:1) NM1010采集数据,通过SPI发送NRF24LE1, 这一通信过程简记为SPI_1;2) NRF24LE1转发给无线收发器,这一通信过程简记为SPI_2;3) 无线收发器将数据打包成无线通信协议中的格式,将数据由空中传输给dongle端4) dongle端解析后交上层处理。
2NRF24LE1与模块通信过程Main流程图如下:SPI_1过程直接返回Motion、Delta_X_L、Delta_Y_L、Delta_X|Y_H的值。
主机根据HID报告描述符里的mouse_report,转换数据格式,发送给无线模块。
SPI_2过程传输的数据包格式如下:3 无线收发器模块鼠标与dongle 之间通过彼此的射频收发器通信,MCU 通过三个接口(RFCON.rfce ,RFCON.rfcsn ,RFIRQ )对射频收发器进行控制;register map 为寄存器映射,用于保存MCU 对于射频收发的配置;TX FIFOs 、RX FIFOs 分别用于存储待发送和接收到的数据包。
在两个射频收发器之间进行的包的交换,一个射频收发器作为主接收(PRX ),另一个射频收发器作为主发送(PTX)。
包的自动处理过程如下:图1 发送模式 图2 接收模式在增强型 ShockBurst 中可以设定重发的次数和重发的间隔参数,而后所有的工作均由增强型ShockBurst 自动完成而无需MCU 的干预。
表1 数据包描述4 无线传输过程nRF24L01 在接收模式下可以接收6 路不同通道的数据,见图。
每一个数据通道使用不同的地址,但是共用相同的频道。
数据通道0是唯一的一个可以配置为40 位自身地址的数据通道。
1~5 数据通道都为8 位自身地址和32 位公用地址,地址设置在RX_ADDR_Px寄存器,高四字节相同,byte 0地址唯一,如下图所示。
NRF24l01使用手册函数介绍

NRF24l01使⽤⼿册函数介绍NRF24l01使⽤⼿册以及函数指令寄存器介绍芯⽚简介NRF24L01 是NORDIC 公司最近⽣产的⼀款⽆线通信通信芯⽚,采⽤FSK 调制,内部集成NORDIC ⾃⼰的Enhanced Short Burst 协议。
可以实现点对点或是1 对 6 的⽆线通信。
⽆线通信速度可以达到2M(bps)。
NORDIC 公司提供通信模块的GERBER ⽂件,可以直接加⼯⽣产。
嵌⼊式⼯程师或是单⽚机爱好者只需要为单⽚机系统预留5 个GPIO,1 个中断输⼊引脚,就可以很容易实现⽆线通信的功能,⾮常适合⽤来为MCU 系统构建⽆线通信功能。
NRF24L01功能框图NRF24L01 的框图如Fig.1 所⽰,从单⽚机控制的⾓度来看,我们只需要关注Fig.1 右⾯的六个控制和数据信号,分别为CSN、SCK、MISO、MOSI、IRQ、CE。
CSN:芯⽚的⽚选线,CSN 为低电平芯⽚⼯作。
SCK:芯⽚控制的时钟线(SPI 时钟)MISO:芯⽚控制数据线(Master input slave output)MOSI:芯⽚控制数据线(Master output slave input)IRQ:中断信号。
⽆线通信过程中MCU 主要是通过IRQ 与NRF24L01 进⾏通信。
CE:芯⽚的模式控制线。
在CSN 为低的情况下,CE 协同NRF24L01 的CONFIG 寄存器共同决定NRF24L01 的状态(参照NRF24L01 的状态机)。
NRF24L01状态机NRF24L01 的状态机见Fig.2 所⽰,对于NRF24L01 的固件编程⼯作主要是参照NRF24L01 的状态机。
主要有以下⼏个状态Power Down Mode:掉电模式Tx Mode:发射模式Rx Mode:接收模式Standby-1Mode:待机1 模式Standby-2 Mode:待机2 模式上⾯五种模式之间的相互切换⽅法以及切换所需要的时间参照Fig.2。
nrf24l01多通道通信的几点提示

nrf24l01实现多通道通信的步骤一、收发端共同的设置1、设置信道工作频率(发射端和接收端必须一致)如:SPI_RW_Reg(WRITE_REG+RF_CH,40);2、设置发射速率(2mbps或1mbps)和发射功率(收发必须一致);如:SPI_RW_Reg(WRITE_REG+RF_SETUP,0x0f); //发射速率为2Mbps,发射功率最大为0dB二、接收端的设置(最关键)1、设置频道0-5,自动ACK应答允许如:SPI_RW_Reg(WRITE_REG+EN_AA,0x3f);2、设置接收通道全部允许如:SPI_RW_Reg(WRITE_REG+EN_RXADDR,0x3f);3、向发送地址寄存器写入本地地址(5byte)4、向各个频道的接收地址寄存器写入接收地址(调试成不成功的关键)频道0:5个字节的地址频道1:5个字节的地址(和频道0的地址必须不同)频道2:1个字节的地址(为该通道发射机地址的第一个字节)如:有一个配置为发射模式的24l01要通过该通道与接收机通信,发射机的本地地址为{0x37,0xa1,0xb3,0xc9,0xda};则接收机频道2的地址为(0x37)频道3:1个字节的地址(同上)频道4:1个字节的地址(同上)频道5:1个字节的地址(同上)5、向各个频道接收数据长度寄存器写入接收数据宽度(最快均为32)频道n:SPI_RW_Reg(WRITE_REG + RX_PW_Pn,RX_PLOAD_WIDTH);如:频道5:SPI_RW_Reg(WRITE_REG + RX_PW_P5,RX_PLOAD_WIDTH);6、配置为接收模式如:SPI_RW_Reg(WRITE_REG+CONFIG,0x0f);三、发射端的设置1、向发送地址寄存器写入本地地址(5byte)对发给接收机频道0的发射机:发射机本地地址必须和接收机写入该频道的接收地址一致;对发给接收机频道1的发射机:发射机本地地址必须和接收机写入该频道的接收地址一致;对发给接收机频道2的发射机:发射机本地地址的第1个字节必须和接收机写入该频道的接收地址一致;后4个字节必须和接收机写入频道1的接收地址的后4个字节一致;其他频道类同频道2;如:接收机地址如下:uchar RX_ADDRESS0[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x00}; //频道0接收地址uchar RX_ADDRESS1[RX_ADR_WIDTH]={0x35,0xa1,0xb3,0xc9,0xda}; //频道1接收地址uchar RX_ADDRESS2[1]={0x36}; //频道2接收地址uchar RX_ADDRESS3[1]={0x37}; //频道3接收地址uchar RX_ADDRESS4[1]={0x38}; //频道4接收地址uchar RX_ADDRESS5[1]={0x39}; //频道5接收地址对发给接收机频道0的发射机:uchar TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x00}; //本地地址对发给接收机频道1的发射机:uchar TX_ADDRESS[TX_ADR_WIDTH]= {0x35,0xa1,0xb3,0xc9,0xda}; //本地地址对发给接收机频道2的发射机:uchar TX_ADDRESS[TX_ADR_WIDTH]= {0x36,0xa1,0xb3,0xc9,0xda}; //本地地址对发给接收机频道3的发射机:uchar TX_ADDRESS[TX_ADR_WIDTH]= {0x37,0xa1,0xb3,0xc9,0xda}; //本地地址.............2、向接收地址寄存器写入接收地址(5byte)均写接收机的本地地址3、设置为发送模式如:SPI_RW_Reg(WRITE_REG+CONFIG,0x0e);4、设置自动重发(可有可无)如:SPI_RW_Reg(WRITE_REG+SETUP_RETR ,0x3f); //自动重发15次,等待最长时间。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1、写卡时,需要将两根绿色的线进行短接,否则写卡失败!!!
除此之外,当写卡烧录完写程序后,配置完读卡参数之后,需要重新上电,并且还需要重新关闭串口再打开串口。
否则不能写卡
另外,注意卡片电池,如果电池电源太低,也不能写卡。
写卡器刚烧录完程序后,当配置完读卡器配置后,需要重新关闭和打开串口,再进行写卡器配置(或者软件重开),否则无法写卡。
2、所有的内存在没有写之前都是FF
3、RC振荡器:
在振荡电路中的频率选择部分可以只用电阻和电容构成。
这种只用电阻和电容构成的振荡器称为RC振荡器。
晶振:
只要在晶体板极上施加交变电压,就会使晶片产生机械变形振动,此现象即所谓逆压电效应。
当外加电压频率等于晶体谐振器的固有频率时,就会发生压电谐振,从而导致机械变形的振幅突然增大。
4、温度系统:温度系数表征标称值受温度变化影响的程度,单位是ppm/°C。
如电
阻的阻值,基准电压源的电压值等。
温度系数通常非常小,采用百万分比(ppm)表示更容易。
5、编程总结:
1、nrf24le1芯片使用时,有一个寄存器,是用于控制端口操作的,如果关闭此
端口则不能正确操作此端口。
OPMCON = 0x02;则表示关闭了端口,在使用端口时,应该重新打开端口。
如OPMCON = 0x00;
2、nrf24le1芯片,当使用它与C8051F120进行SLAVE SPI通信时,如果已经完
数据,而要从已写完的数据中,再读取出来,则需要一定的延时!
3、两块单片机使用SPI通信时,如果配置的晶振频率过高,有可能使得程序在
while循环等待过程中接收不到另一发起人单片机的程序,从而出现单片机死机的现象。
4、使用nrf24le1时,在使用二维数组,不能将二维数组的地址传递给一个数a,再把a传递给b而就直接交二维数组传递给b
5、关于return和break:使用return时是跳出此子函数,回到调用该子函数的后面。
而使用break时是跳出该循环体。
6. 关于卡片睡眠醒来操作内存:当卡片醒来,若是要操作内存,则必须将系统时钟重新配置:CLKCTRL=0;delay_nms(30);(延时是为了等待时钟响应)。
否则操作不了内存。
7、if和while不满足时,程序如何执行:当程序中,如果if或while不满足条件时,程序将跳过if或while的条件判断语句及,执行语句,直接执行后面的语句。
4/25/2013 11:31:24 PM
6、如何计算数据在空中传送的时间:4BYTE数据,空速1M
则T=4*(8/1M)=32us
7、参数传递可以分为两种:一各是数值传递,另一各是引用传递。
前者仅仅是交数值传递
给了形参,而不返回结果,后者其实是把的地址传递给形参,实参和形参其实都是同一个变量,被调用函数通过修改该变量的值返回给调用函数,从而把结果带回,在参数传递过程中,通过在参数前加上&,表示引用传递,如果参数前没有&,表示数值传递。
8、指针变量和变量一样,都可以对数据进行操作,指针变量的操作主要是通过取地址运算
符&和指针运算符*来实现的。
例如,&a指的是变量a的地址,*prt表示变量ptr所指向的内存单元存放的内容。
另外:“*”和“&”这两个运算符是互逆的。
9、当使用extern时,被exrern的参数必须是在主函数中定义,不能只是在子函数中定义。
否则虽然编译时没有问题,但是不能生成HEX文件。
10、关于->运算符:
若是指针就用->,若是结构名就用.就是了.这个是成员操作符,控制具体的成员.
11、对于nrf24le1芯片,当对端口进行执行操作时,如指令P11=1,P11=0;这两个指令之间的执行时间为750ns。
12、对于卡片,当写卡已经写好600ms发送一次卡号时,大致还是600ms多一点发送一次数据,但是并不是每隔600ms发送一次,有可能某一次没有发送。
也就是说并不能保证每一次都发送数据。
13、使用Keil软件时,HEX文件以及包含HEX文件的文件夹,不能使用逗号进行命名。
否则烧录程序的时候会出现错误的文件名提示。
使用Keil软件时,文件名的命名不能使用小括号“()”,否则会造成调试程序时,当查找某一个变量时,虽然查找到了该变量,但跳转不到该变量的位置。
但是可以使用中括号“[]”
14、读卡器配置为主动上传时,功率调节只能设置为硬件可调,因为如果设置为软件调节时,主动上传会占用系统总线使得无法从上位机上下发数据至读卡器。
当读卡器配置为组网时,功率真调节既可设置为组硬件可调也可以设置为软件可调。
15、关于2I03硬件问题:当使用通用485时,会出现乱码,有时也无法授权;而当使用黑盒子时,没有任何类似的问题。
解决方法:将SIPEX485EEN-L/NSOIC-8的输出A和B线的上拉电阻除去。
因为SIPEX485EEN-L/NSOIC-8这个芯片本身已经带了上拉了。
16、当使用端口灯,或者蜂鸣器作为标志跟踪数据,在反复循环过程中,如果没有发现灯闪,或者蜂鸣器鸣叫,则有可能是灯闪了或蜂鸣器叫了,只是人眼/耳朵没有分辨出来。
特别是蜂鸣器,示波器是看不出来的,因为它是鸣叫一声一个高电平,所以即使有反复的鸣叫,也只能看到高电平一次,而不是一个反复的波形。
17、hal_flash_bytes_read(DEVICEID,IDE,4);这个函数,不能读取程序存储区里的数据。
若要读取程序存储区里的数据,只需要将hal_flash_bytes_read(DEVICEID,IDE,4);函数里的关键字Xdata换成code即可。
18、当发射等待用delay_nms(1)等待发射完成时,有可能造成卡片数据多次重发。
所以建议使用while(!TX_DS);
19、2.4G腕带卡死机情况:卡片板子焊接有问题,重新烫一下就好了。
20、卡片程序功耗问题:配置void rf_init(void),沿用之前的机制,即swith语句,否则功耗则非常大。
21、卡片程序连续再次发送卡号:程序如下(必须重新配置射频,必须清sta。
)
TX_TEST_Mode();
while(!(TX_DS));
sta=0;
rf_init();
TX_Mode();
while(!(TX_DS));。