NRF24L01的C51单片机讲解.docx

上传人:小飞机 文档编号:3161962 上传时间:2023-03-11 格式:DOCX 页数:17 大小:41.87KB
返回 下载 相关 举报
NRF24L01的C51单片机讲解.docx_第1页
第1页 / 共17页
NRF24L01的C51单片机讲解.docx_第2页
第2页 / 共17页
NRF24L01的C51单片机讲解.docx_第3页
第3页 / 共17页
NRF24L01的C51单片机讲解.docx_第4页
第4页 / 共17页
NRF24L01的C51单片机讲解.docx_第5页
第5页 / 共17页
亲,该文档总共17页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《NRF24L01的C51单片机讲解.docx》由会员分享,可在线阅读,更多相关《NRF24L01的C51单片机讲解.docx(17页珍藏版)》请在三一办公上搜索。

1、NRF24L01的C51单片机讲解#include #include /*/ /* NRF24L01 的管脚定义,以及在本程序中的应用,VCC接3.3V电源,可以通过5V用电压转换芯片 /*得到,NC 管脚可以接可以不接,暂时没用途。本程序应用于51或者52单片机,是两个模块进行通讯 /*成功的简单指示,现象是:模块1的 KEY1 对应模块1的LED1 和模块2的LED3 ,模块1的 KEY2 对应模 /*块1的LED2 和模块2的LED4,发过来也对应。 /*/ typedef unsigned char uchar; typedef unsigned char uint; /*NRF24L

2、01端口定义*/ =P13; sbit MOSI =P12; sbit SCK =P11; sbit CSN =P10; sbit IRQ =P32; /数字输入 /*按键*/ sbit KEY1=P27;/按键S1 sbit KEY2=P22;/按键S2 /*数码管位选*/ sbit led1=P10; /LED0 sbit led2=P11; /LED1 sbit led3 =P12; /LED2 sbit led4 =P13; /LED3 sbit led5 =P14; /LED4 /*NRF24L01*/ #define TX_ADR_WIDTH 5 / 5 uints TX addr

3、ess width #define RX_ADR_WIDTH 5 / 5 uints RX address width #define TX_PLOAD_WIDTH 20 / 20 uints TX payload #define RX_PLOAD_WIDTH 20 / 20 uints TX payload uint const TX_ADDRESSTX_ADR_WIDTH= 0x34,0x43,0x10,0x10,0x01; /本地地址 uint const RX_ADDRESSRX_ADR_WIDTH= 0x34,0x43,0x10,0x10,0x01; /接收地址 /*NRF24L01

4、寄存器指令*/ #define READ_REG 0x00 / 读寄存器指令 #define WRITE_REG 0x20 / 写寄存器指令 #define RD_RX_PLOAD 0x61 / 读取接收数据指令 读RX 有效数据 #define WR_TX_PLOAD 0xA0 / 写待发数据指令 写TX 有效数据 #define FLUSH_TX 0xE1 / 冲洗发送 FIFO指令 /清除TX FIFO 寄存器应用于发射模式下 #define FLUSH_RX 0xE2 / 冲洗接收 FIFO指令 /清除RX FIFO 寄存器应用于接收模式下 #define REUSE_TX_PL 0x

5、E3 / 定义重复装载数据指令 /重新使用上一包有效数据 #define NOP 0xFF / 保留 /*SPI(nRF24L01)寄存器地址*/ #define CONFIG 0x00 / 配置收发状态,CRC校验模式以及收发状态响应方式 #define EN_AA 0x01 / 自动应答功能设置 /使能自动应答功能 /此功能禁止后可与nRF2401 通讯 #define EN_RXADDR 0x02 / 可用信道设置 /接收地址允许 #define SETUP_AW 0x03 / 收发地址宽度设置 #define SETUP_RETR 0x04 / 自动重发功能设置 #define RF_

6、CH 0x05 / 工作频率设置 #define RF_SETUP 0x06 / 发射速率、功耗功能设置 #define STATUS 0x07 / 状态寄存器 #define OBSERVE_TX 0x08 / 发送监测功能 #define CD 0x09 / 地址检测 #define RX_ADDR_P0 0x0A / 频道0接收数据地址 数据通道0 接收地址 #define RX_ADDR_P1 0x0B / 频道1接收数据地址 #define RX_ADDR_P2 0x0C / 频道2接收数据地址 #define RX_ADDR_P3 0x0D / 频道3接收数据地址 #define

7、RX_ADDR_P4 0x0E / 频道4接收数据地址 #define RX_ADDR_P5 0x0F / 频道5接收数据地址 #define TX_ADDR 0x10 / 发送地址寄存器 #define RX_PW_P0 0x11 / 接收频道0接收数据长度 #define RX_PW_P1 0x12 / 接收频道1接收数据长度 #define RX_PW_P2 0x13 / 接收频道2接收数据长度 #define RX_PW_P3 0x14 / 接收频道3接收数据长度 #define RX_PW_P4 0x15 / 接收频道4接收数据长度 #define RX_PW_P5 0x16 / 接

8、收频道5接收数据长度 #define FIFO_STATUS 0x17 / FIFO栈入栈出状态寄存器设置 /FIFO 状态寄存器 /*函数声明 */ void Delay(unsigned int s); /大延时 void inerDelay_us(unsigned char n); /小延时 void init_NRF24L01(void); /NRF24L01 初始化 uint SPI_RW(uint dat); /根据SPI协议,写一字节数据到nRF24L01,同时从nRF24L01读出一字节 uchar SPI_Read(uchar reg); /从reg寄存器读一字节 void

9、SetRX_Mode(void); /数据接收配置 uint SPI_RW_Reg(uchar reg, uchar value); /写数据value到reg寄存器 uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars); /从reg寄存器读出bytes个字节,通常用来 /读取接收通道数据或接收/发送地址 uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars); /把pBuf缓存中的数据写入到nRF24L01,通常用来写入发 /射通道数据或接收/发送地址 unsigned cha

10、r nRF24L01_RxPacket(unsigned char* rx_buf); /数据读取后放入rx_buf接收缓冲区中 void nRF24L01_TxPacket(unsigned char * tx_buf); /发送 tx_buf中数据 /*长延时*/ void Delay(unsigned int s) unsigned int i; for(i=0; is; i+); for(i=0; i0;n-) _nop_; /*/ /*NRF24L01初始化 /*/ void init_NRF24L01(void) inerDelay_us(100); CE=0; / 芯片使能 CS

11、N=1; / 禁止 SPI SCK=0; / SPI时钟置低 SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); / 写本地地址 / 发送地址先写低字节 本机地址 长度 SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); / 写接收端地址 SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); / 频道0自动 ACK应答允许 SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); / 允许接收地址只有频

12、道0,如果需要多频道可以参考Page21 SPI_RW_Reg(WRITE_REG + RF_CH, 0); / 设置信道工作为2.4GHZ,收发必须一致 SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); /设置接收数据长度,本次设置为32字节 SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); /设置发射速率为1MHZ,发射功率为最大值0dB /*/ /*函数:uint SPI_RW(uint uchar) /*功能:NRF24L01的SPI写时序-根据SPI协议,写一字节数据到nRF24L01,同时从nRF24L

13、01 读出一字节 /*要读/写的是最低字节的高位*/ uint SPI_ReadWrite(uint dat) uint i; for(i=0;i8;i+) / 循环8次 MOSI = (dat & 0x80); / dat的最高位输出到MOSI MSB to MOSI dat = (dat 1); / 从右向左进一位 shift next bit into MSB. SCK = 1; / 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据 Set SCK high. dat |= MISO; /读MISO到 dat 最低位 capture current MISO

14、 bit SCK = 0; / SCK置低 .then set SCK low again return(dat); /返回读出的一字节 return read dat /* /*函数:uchar SPI_Read_byte(uchar reg) /*功能:NRF24L01的SPI时序-从reg寄存器读一字节 /*/ uchar SPI_Read (uchar reg) uchar reg_val; CSN = 0; /CSN置低,开始传输数据 CSN low, initialize SPI communication. SPI_RW(reg); /选择寄存器 Select register

15、to read from. reg_val = SPI_RW(0); /然后从该寄存器读数据 /#define READ_REG 0x00 / 读寄存器指令 CSN = 1; /CSN拉高,结束数据传 return(reg_val); /返回寄存器数据 return register value /*/ /* uint SPI_Write_byte(uchar reg, uchar value) /*功能:NRF24L01读写寄存器函数 /*描述:写数据value到reg寄存器 /*/ uint SPI_RW_Reg(uchar reg, uchar value) uchar status;

16、CSN = 0; / CSN置低,开始传输数据 CSN low, init SPI transaction status = SPI_RW(reg); / 选择寄存器,同时返回状态字 select register SPI_RW(value); / 然后写数据到该寄存器 .and write value to it. CSN = 1; / CSN拉高,结束数据传输 CSN high again return(status); / 返回状态寄存器 return nRF24L01 status uchar /*/ /*函数:uint SPI_Read_Buf(uchar reg, uchar *p

17、Buf, uchar uchars) /*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数 /*描述: 从reg寄存器读出bytes个字节,通常用来读取接收通道数据或接收/发送地址 /*/ uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars) uint status,i; CSN = 0; /CSN置低,开始传输数据 Set CSN low, init SPI tranaction status = SPI_RW(reg); /选择寄存器,同时返回状态字 Select register

18、to write to and read status uchar for(i=0;iuchars;i+) pBufi = SPI_RW(0); /逐个字节从nRF24L01读出 CSN = 1; /CSN拉高,结束数据传输 return(status); /返回状态寄存器 return nRF24L01 status uchar /* /*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars) /*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数 /*描述:把pBuf缓存中的数据写入到n

19、RF24L01,通常用来写入发射通道数据或接收/发送地址 /*/ uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars) uint status,i; CSN = 0; /CSN置低,开始传输数据 status = SPI_RW(reg); /选择寄存器,同时返回状态字 inerDelay_us(10); for(i=0; iuchars; i+) SPI_RW(*pBuf+); /逐个字节写入nRF24L01 CSN = 1; /CSN拉高,结束数据传输 return(status); /返回状态寄存器 /*/ /*函数:void S

20、etRX_Mode(void) /*功能:数据接收配置 /*/ void SetRX_Mode(void) CE=0;/待机模式 SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);/CRC使能,16位CRC校验,上电,接收模式 CE = 1; / 拉高CE启动接收设备 inerDelay_us(130); /*/ /*函数:unsigned char nRF24L01_RxPacket(unsigned char *rx_buf) /*功能:数据读取后放入rx_buf接收缓冲区中 /*/ unsigned char nRF24L01_RxPacket(unsigned

21、char* rx_buf) unsigned char revale=0; sta=SPI_Read(STATUS); / 读取状态寄存其来判断数据接收状况 /#define STATUS 0x07 / 状态寄存器 if(RX_DR) / 判断是否接收到数据 /RX_DR 为 sta 的第六位当接收到有效数据后置一 CE = 0; /SPI使能 SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);/ read receive payload from RX_FIFO buffer /#define RD_RX_PLOAD 0x61 / 读取接收数据指

22、令 /#define TX_PLOAD_WIDTH 20 revale =1; /读取数据完成标志 SPI_RW_Reg(WRITE_REG+STATUS,sta); /接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志 #define WRITE_REG 0x20/ 写寄存器指令 return revale; /* /*函数:void nRF24L01_TxPacket(unsigned char * tx_buf) /*功能:发送 tx_buf中数据 /*/ void nRF24L01_TxPacket(unsigned char * tx_buf) CE=

23、0; /StandBy I模式 SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); / 装载接收端地址 /#define RX_ADDR_P0 0x0A / 频道0接收数据地址 数据通道0 接收地址 / uint const TX_ADDRESSTX_ADR_WIDTH= 0x34,0x43,0x10,0x10,0x01; /本地地址 SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); / 装载数据 SPI_RW_Reg(WRITE_REG + CONFIG, 0x

24、0e); / IRQ收发完成中断响应,16位CRC,主发送 CE=1; /置高CE,激发数据发送 inerDelay_us(10); /*主函数*/ void main(void) unsigned char tf =0; unsigned char TxBuf20=0; / 要发送的数组 unsigned char RxBuf20=0; / 接收的数据 数组 init_NRF24L01 ; /模块初始化 led1=1;led2=1;led3 =1;led4 =1; /led 灯关闭 Delay(1000); while(1) if(KEY1 =0 ) /按键 1 按下 TxBuf1 = 1

25、; /赋值 tf = 1 ; led1=0; /本地led 灯闪烁 Delay(200); led1=1; Delay(200); if(KEY2 =0 ) /按键 2 按下 TxBuf2 =1 ; /赋值 tf = 1 ; led2=0; /本地led 灯闪烁 Delay(200); led2=1; Delay(200); if (tf=1) /有键按下 nRF24L01_TxPacket(TxBuf); /发送数据 Transmit Tx buffer data TxBuf1 = 0x00; /清零 TxBuf2 = 0x00; tf=0; Delay(1000); SetRX_Mode;

26、 /设置成接受模式 RxBuf1 = 0x00; /接收的数组相应位清零 RxBuf2 = 0x00; Delay(1000); nRF24L01_RxPacket(RxBuf); /接收数据 if(RxBuf1|RxBuf2) if( RxBuf1=1) led3=RxBuf0; if( RxBuf2=1) led4=RxBuf4; Delay(3000); /old is 1000 RxBuf1 = 0x00; /清零 RxBuf2 = 0x00; led3=1; /关灯 led4=1; 本程序存在的问题:反应不够灵敏,当在按键1和按键2之间切换的时候,对方的灯闪烁会有一定的延时,另外本程

27、序没有消除按键的抖动。 对部分函数的解释: uint SPI_RW(uint dat) 最基本的函数,完成 GPIO模拟 SPI 的功能。将输出字节从 MSB 循环输出, 同时将输入字节从 LSB 循环移入。上升沿读入,下降沿输出。 uchar SPI_Read(uchar reg); /从reg寄存器读一字节 读取寄存器值的函数:基本思路就是通过 READ_REG命令 ,把 寄存器中的值读出来。对于函数来说也就是把 reg 寄存器的值读到 reg_val 中去。 uint SPI_RW_Reg(uchar reg, uchar value); /写数据value到reg寄存器 寄存器访问函数

28、:用来设置 24L01 的寄存器的值。基本思路就是通过 WRITE_REG命令把要设定的值写到相应的寄存器地址里面去,并读取返回值。对于 函数来说也就是把 value值写到 reg 寄存器中。 需要注意的是,访问 NRF24L01 之前首先要 enable 芯片 ,访问完了以后再 disable 芯片。 uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars); /从reg寄存器读出bytes个字节,通常用来 /读取接收通道数据或接收/发送地址 接收缓冲区访问函数:主要用来在接收时读取 FIFO 缓冲区中的值。基本思路就是通过 READ_R

29、EG命令把数据从接收 FIFO中读出并存到数组里面去。 uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars); /把pBuf缓存中的数据写入到nRF24L01,通常 /用来写入发 发射缓冲区访问函数:主要用来把数组里的数放到发射 FIFO缓冲区中。基本思路就是通过 WRITE_REG命令把数据存到发射 FIFO中去。 Tx 模式初始化过程 1)写 Tx 节点的地址 TX_ADDR 2)写 Rx 节点的地址 RX_ADDR_P0 3)使能 AUTO ACK EN_AA 4)使能 PIPE 0 EN_RXADDR 5)配置自动重发次数 SETUP_RETR 6)选择通信频率 RF_CH 7)配置发射参数 RF_SETUP 8 ) 选择通道0 有效数据宽度 Rx_Pw_P0 9)配置 24L01 的基本参数以及切换工作模式 CONFIG。 Rx 模式初始化过程: 初始化步骤 24L01 相关寄存器 1)写 Rx 节点的地址 RX_ADDR_P0 2)使能 AUTO ACK EN_AA 3)使能 PIPE 0 EN_RXADDR 4)选择通信频率 RF_CH 5) 选择通道0 有效数据宽度 Rx_Pw_P0 6)配置发射参数 RF_SETUP 7)配置 24L01 的基本参数以及切换工作模式 CONFIG。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号