2.4G无线模块(NRF24L01)学习(1) 您所在的位置:网站首页 无线模块原理图片 2.4G无线模块(NRF24L01)学习(1)

2.4G无线模块(NRF24L01)学习(1)

2024-07-18 08:22| 来源: 网络整理| 查看: 265

先看模块,如下图:

 

        一个模块的使用,必须先阅读产品文档,我为了学习这个模块,特地将资料文档下载下来,逐一阅读理解,这样以后才能灵活使用其模块。

        NRF24L01+模块的使用还是有一定的复杂度的,复杂度和我之前写的红外通信模块相比,不可相提并论。为什么要使用这个模块,主要还是因为它相对红外通信模块传输距离较远,数据传输较为稳定,这样以后对小车的控制将比较灵活,也是以后转移到物联网上的一个方向。

        话不多说,进入正题吧,NRF24L01模块内部不含单片机,所以需要单片机或者微控制器驱动控制才可以使用该模块,本文章,我是使用的51系列单片机(12C5A60S2)进行对NRF24L01模块进行控制,下面来叙述一下本文所要完成的功能。

功能实现:

使用两个单片机控制两个NRF24L01模块,每个模块都可以接受或发送数据。一个单片机需要通过串口与电脑相连(单片机A),为了显示接受数据,或发送数据;另外一个单片机我们称为单片机B。需要完成:单片机A下发命令控制单片机B上的灯闪烁;按单片机B上的按键触发给单片机A发送数据

如何实现这样的功能呢?其实这个功能实现也是在网上参照别人写的博客学习的,该博客网址:http://www.51hei.com/bbs/dpj-92127-1.html              基于51单片机的nrf24l01无线的接受和发射程序

代码很全,我只是在原有基础上稍作改动。先看一下我的硬件实施,如图:

代码如下:

1.单片机A的代码

主函数文件部分(test.c):

#include"2401.h" #define uint unsigned int #define uchar unsigned char //1//sbit KEY1=P0^0; //发送按键 //1//sbit KEY2=P0^1; //1//sbit KEY3=P0^2; //1//sbit KEY4=P0^3; sbit beep=P2^3; //喇叭 sbit LED6=P1^6; //发送数据时显示灯+接收到数据后的功能实现灯 uchar Tx_Buf1[]={1}; //发送的信息1 uchar Rx_Buf[32]; //接收到的数据暂存器,最多32字节数据 uchar uart_flag,a; //串口接收标志【收到数据就置1】,a为接收到的数据 /*------------------------------------------------ 延时函数 ------------------------------------------------*/ void delay_ms(uint z) //延时函数 { uint y; while(z--) for(y=110;y>0;y--); } /*------------------------------------------------ 定义UART_Init函数 ------------------------------------------------*/ void UART_Init(void) // 波特率9600 { PCON &= 0x7F; //波特率不倍速 SCON = 0x50; //8位数据,可变波特率 AUXR &= 0xFB; //独立波特率发生器时钟为Fosc/12,即12T BRT = 0xFD; //设定独立波特率发生器重装值 AUXR |= 0x01; //串口1选择独立波特率发生器为波特率发生器 AUXR |= 0x10; //启动独立波特率发生器 ES = 1; //允许串口中断 EA = 1; //允许总中断 } /*------------------------------------------------ 定义UART_Send_Byte函数 ------------------------------------------------*/ void UART_Send_Byte(uchar byte) { SBUF=byte; //缓冲区装载要发送的字节数据 while(TI==0); //等待发送完毕,TI标志位会置1 TI=0; //清零发送完成标志位 } /*------------------------------------------------ 串口接收中断服务程序 ------------------------------------------------*/ void UART(void) interrupt 4 { if(RI) //检测接收完成标志位置1 { RI=0; //清零接收完成标志位 a=SBUF; //读取接收到的数据 uart_flag = 1; //中断标志位置1 } } /*------------------------------------------------ main函数 ------------------------------------------------*/ void main() { LED6=1; //初始灯6熄灭 uart_flag=0; //串口标志初始为0 init_NRF24L01(); //初始化24L01 UART_Init(); //初始化串口 while(NRF24L01_Check()) //检查不到24l01则报警 { beep=0; delay_ms(200); beep=1; delay_ms(200); } while(1) { RX_Mode(); //接收模式 while(!nRF24L01_RxPacket(Rx_Buf)) //等待接收数据,返回1则接收到数据,在等待接收数据期间,可以随时变成发送模式 { if(uart_flag==1) //当串口接受标志为1表示有数据过来 { ES=0; //关串口中断 TX_Mode(); //发送模式 Tx_Buf1[0]=a-'0'; // wantin modify 2018.11.16 //将串口数据给发送缓冲区 nRF24L01_TxPacket(Tx_Buf1); //发送命令数据24L01 UART_Send_Byte('O'); //向串口发送已经传送 UART_Send_Byte('K'); UART_Send_Byte(':'); UART_Send_Byte(a); UART_Send_Byte('\n'); LED6=0; delay_ms(300); LED6=1; delay_ms(300); //发送后LED1闪一下 ES=1; //允许串口中断 uart_flag=0; //中断标志位置0 break; //退出最近的循环,从而变回接收模式,这句关键 } } if(Rx_Buf[1]==1) //若接收到对应的数据则实现对应功能 { Rx_Buf[1]=0; //清空数据 LED6=0; delay_ms(300); LED6=1; delay_ms(300); //接收到数据 后闪烁 UART_Send_Byte('W'); //向串口发送已经传送 UART_Send_Byte('A'); UART_Send_Byte('N'); //向串口发送已经传送 UART_Send_Byte('T'); UART_Send_Byte('I'); //向串口发送已经传送 UART_Send_Byte('N'); UART_Send_Byte('\n'); } if(Rx_Buf[0]==2) //若接收到对应的数据则实现对应功能 { Rx_Buf[0]=0; //清空数据 LED6=0; delay_ms(300); LED6=1; delay_ms(300); //接收到数据 后闪烁 UART_Send_Byte('O'); //向串口发送已经传送 UART_Send_Byte('K'); UART_Send_Byte('\n'); } } }

因为想使用NRF24L01模块就需要访问模块内的地址,进行控制数据的收发等,因此还需要NRF24L01模块代码,这个代码是拷贝别人的,亲测可用,代码如下(2401.h):

#ifndef __NRF24L01_H__ #define __NRF24L01_H__ #include #define uchar unsigned char #define uint unsigned int sbit CE =P1^0; sbit CSN =P1^1; sbit SCK =P1^2; sbit MOSI =P1^3; sbit MISO =P1^4; sbit IRQ =P1^5; //uchar TxBuf[20]={"1234567890abcdefghij"}; #define TX_ADR_WIDTH 5 // 5 uints TX address width #define RX_ADR_WIDTH 5 // 5 uints RX address width #define TX_PLOAD_WIDTH 32 // 32 uints TX payload #define RX_PLOAD_WIDTH 32 // 32 uints TX payload uchar TX_ADDRESS[TX_ADR_WIDTH]= {0xE7,0xE7,0xE7,0xE7,0xE7}; //本地地址 uchar RX_ADDRESS[RX_ADR_WIDTH]= {0xE7,0xE7,0xE7,0xE7,0xE7}; //接收地址 ///***************************************NRF24L01寄存器指令******************************************************* #define READ_REG 0x00 // 读寄存器指令 #define WRITE_REG 0x20 // 写寄存器指令 #define RD_RX_PLOAD 0x61 // 读取接收数据指令 #define WR_TX_PLOAD 0xA0 // 写待发数据指令 #define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令 #define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令 #define REUSE_TX_PL 0xE3 // 定义重复装载数据指令 #define NOP 0xFF // 保留 ///*************************************SPI(nRF24L01)寄存器地址**************************************************** #define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式 #define EN_AA 0x01 // 自动应答功能设置 #define EN_RXADDR 0x02 // 可用信道设置 #define SETUP_AW 0x03 // 收发地址宽度设置 #define SETUP_RETR 0x04 // 自动重发功能设置 #define RF_CH 0x05 // 工作频率设置 #define RF_SETUP 0x06 // 发射速率、功耗功能设置 #define NRFRegSTATUS 0x07 // 状态寄存器 #define OBSERVE_TX 0x08 // 发送监测功能 #define CD 0x09 // 地址检测 #define RX_ADDR_P0 0x0A // 频道0接收数据地址 #define RX_ADDR_P1 0x0B // 频道1接收数据地址 #define RX_ADDR_P2 0x0C // 频道2接收数据地址 #define RX_ADDR_P3 0x0D // 频道3接收数据地址 #define 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 // 接收频道5接收数据长度 #define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置 ///*****************************子函数集********************************************************* uchar NRF24SPI_Send_Byte(uchar dat); uchar SPI_WR_Reg(uchar reg, uchar value); uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar Len); uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar Len); uchar nRF24L01_RxPacket(unsigned char* rx_buf); void nRF24L01_TxPacket(unsigned char * tx_buf); uchar SPI_RD_Reg(uchar reg); void init_NRF24L01(void); void TX_Mode(void); void RX_Mode(void); void NRF_Send(void); uchar NRF24L01_Check(void); //---------------------------------------------- //发送一字节[MOSI和MISO数据传递] //---------------------------------------------- uchar NRF24SPI_Send_Byte(uchar dat) { uchar i; for (i = 0; i < 8; i++) //output 8-bit { //写入1位数据 MOSI=(dat & 0x80); //output 'uchar', MSB to MOSI dat0;b--) for(a=2;a>0;a--); } } //---------------------------------------------- //NRF24L01检测是否存在 //---------------------------------------------- uchar NRF24L01_Check(void) { uchar bu[5]={0XA5,0XA5,0XA5,0XA5,0XA5}; uchar bu1[5]; uchar i; SPI_Write_Buf(WRITE_REG+TX_ADDR,bu,5); //写入5个字节的地址. SPI_Read_Buf(TX_ADDR,bu1,5); //读出写入的地址 for(i=0;i


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有