2.4G应用
发射端:
/*********************************************************************
巫妖王V3.0开发板例程
朱有鹏物联网大讲堂出品(www.zhulaoshi.org)
技术支持和学习讨论请加朱有鹏单片机学习1群 214959925获取
**********************************************************************
模块名称:nRF24L01
模块功能: 2401无线收发模块
硬件接线:
注意事项:(1)
版 本:V1.00
作 者:朱有鹏(AstonZhu)
时 间:2018.10.30
**********************************************************************/
/*
**********************************************************************
* 头文件包含
**********************************************************************
*/
#include "2401.h"
/*
**********************************************************************
* 本地全局变量
**********************************************************************
*/
sbit CE = P1^0;
sbit CSN = P1^1;
sbit SCK = P1^2;
sbit MOSI = P1^3;
sbit MISO = P1^4;
sbit IRQ = P1^5;
u8 TX_ADDRESS[TX_ADR_WIDTH]= {0xE7,0xE7,0xE7,0xE7,0xE7}; //本地地址
u8 RX_ADDRESS[RX_ADR_WIDTH]= {0xE7,0xE7,0xE7,0xE7,0xE7}; //接收地址
/*
**********************************************************************
* 内部函数原型声明
**********************************************************************
*/
/********************底层驱动函数源码******************************/
//----------------------------------------------
//发送一字节[MOSI和MISO数据传递]
//----------------------------------------------
u8 NRF24L01SpiSendByte(u8 dat)
{
u8 i;
for (i=0; i<8; i++) //output 8-bit
{
//写入1位数据
MOSI = (dat & 0x80); //output 'uchar', MSB to MOSI
dat <<= 1; // shift next bit into MSB..
//读取1位数据
SCK = 1; // Set SCK high..
if (MISO)
{
dat |= 1;
}
else
{ // capture current MISO bit
dat &= 0xFE;
}
SCK = 0; // ..then set SCK low again
}
return (dat); // return read uchar
}
//----------------------------------------------
//延时n个10us
//----------------------------------------------
void DelayN10us(u16 n)
{
for (; n>0; n--)
{
u8 a,b;
for (b=1; b>0; b--)
for (a=2; a>0; a--);
}
}
//----------------------------------------------
//NRF24L01检测是否存在
//----------------------------------------------
u8 NRF24L01Check(void)
{
u8 bu[5] = {0XA5, 0XA5, 0XA5, 0XA5, 0XA5};
u8 bu1[5];
u8 i;
SpiWriteBuf(WRITE_REG+TX_ADDR, bu, 5); //写入5个字节的地址.
SpiReadBuf(TX_ADDR, bu1, 5); //读出写入的地址
for (i=0; i<5; i++)
if (bu1[i] != 0XA5)
break;
if (i != 5)
return 1; //NRF24L01不在位
return 0; //NRF24L01在位
}
//----------------------------------------------
//NRF24L01初始化
//----------------------------------------------
void InitNRF24L01(void)
{
u8 buf[5] = {0};
DelayN10us(10);
CE = 0; // chip enable
CSN= 0; // Spi disable
SpiReadBuf(TX_ADDR, buf, TX_ADR_WIDTH);//debug 测试原来的本地地址:复位值是:0xE7 0xE7 0xE7 0xE7 0xE7
}
//----------------------------------------------
//函数:uchar SPI_Read(uchar reg)
//功能:NRF24L01的SPI时序,读取指定寄存器的内容
//----------------------------------------------
u8 SpiReadReg(u8 reg)
{
u8 reg_val;
CSN = 0; // CSN low, initialize SPI communication...
NRF24L01SpiSendByte(reg); // Select register to read from..
reg_val = NRF24L01SpiSendByte(0); // ..then read registervalue
CSN = 1; // CSN high, terminate SPI communication
return (reg_val); // return register value
}
//----------------------------------------------
//函数:uchar SPI_Write(uchar reg)
//功能:NRF24L01的SPI时序,写入指定寄存器的内容
//----------------------------------------------
u8 SpiWriteReg(u8 reg, u8 value)
{
u8 status = 0;
CSN = 0; // CSN low, init SPI transaction
status = NRF24L01SpiSendByte(reg); // select register
NRF24L01SpiSendByte(value); // ..and write value to it..
CSN = 1; // CSN high again
return (status); // return nRF24L01 status uchar
}
//----------------------------------------------
//函数:uint SpiReadBuf
//功能: 用于读数据
//参数:reg:为寄存器地址
// pBuf:为待读出数据地址
// uchars:读出数据的个数
//----------------------------------------------
u8 SpiReadBuf(u8 reg, u8 *pBuf, u8 Len)
{
u16 status, i;
CSN = 0; // Set CSN low, init SPI tranaction
status = NRF24L01SpiSendByte(reg); // Select register to write to and read status uchar
for (i=0; i
#ifndef __NRF24L01_H__
#define __NRF24L01_H__
/*
**********************************************************************
* 头文件包含
**********************************************************************
*/
#include "common.h"
/*
**********************************************************************
* 本地宏定义
**********************************************************************
*/
#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
///***************************************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栈入栈出状态寄存器设置
/*
**********************************************************************
* 外部函数原型声明
**********************************************************************
*/
u8 NRF24L01SpiSendByte(u8 dat);
void DelayN10us(u16 n);
u8 NRF24L01Check(void);
void InitNRF24L01(void);
u8 SpiReadReg(u8 reg);
u8 SpiWriteReg(u8 reg, u8 value);
u8 SpiReadBuf(u8 reg, u8 *pBuf, u8 Len);
u8 SpiWriteBuf(u8 reg, u8 *pBuf, u8 Len);
void RxMode(void);
u8 NRF24L01RxPacket(u8 *rx_buf);
void TxMode(void);
void NRF24L01TxPacket(u8 *tx_buf);
#endif /*__NRF24L01_H__ */
/*********************************************************************
巫妖王V3.0开发板例程
朱有鹏物联网大讲堂出品(www.zhulaoshi.org)
技术支持和学习讨论请加朱有鹏单片机学习1群 214959925获取
**********************************************************************
实验序列:24
实验任务:
实现现象:
硬件接线:插入2401模块,注意方向是朝外的。
注意事项:(1)
(2)
(3)
版 本:V1.00
作 者:朱有鹏(AstonZhu)
时 间:2018.10.30
**********************************************************************/
/*
**********************************************************************
* 头文件包含
**********************************************************************
*/
#include "2401.h"
/*
**********************************************************************
* 本地宏定义
**********************************************************************
*/
/*
**********************************************************************
* 本地全局变量
**********************************************************************
*/
sbit KEY1 = P3^1; //发送按键
sbit KEY2 = P3^0;
sbit KEY3 = P3^2;
sbit KEY4 = P3^3;
sbit LED1 = P2^0; //
sbit LED2 = P2^1; //发送数据时显示灯+接收到数据后的功能实现灯
void delay_ms(u16 z);
/*********************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 参数列表 : 无
* 函数输出 : 无
*********************************************************************/
void main(void)
{
u8 Tx_Buf1[] = {1}; // 发送的信息1
u8 Rx_Buf[32]; // 接收到的数据暂存器,最多32字节数据
InitNRF24L01();
LED2 = 1; //初始灯6熄灭
while (NRF24L01Check()) //检查不到24l01则报警
{
LED2 = 0;
delay_ms(200);
LED2 = 1;
delay_ms(200);
}
while (1)
{
RxMode(); //接收模式
while (!NRF24L01RxPacket(Rx_Buf)) //等待接收数据,返回1则接收到数据,在等待接收数据期间,可以随时变成发送模式
{
if (KEY1 == 0) //按了按键1,则变成发送模式,发送对应数据,发送完后变成接收模式
{
delay_ms(5); //消抖动
if (KEY1 == 0)
{
while (!KEY1);
TxMode(); //发送模式
Tx_Buf1[0] = 1; //将1发送过去
NRF24L01TxPacket(Tx_Buf1); //发送命令数据
LED1 = 0;
delay_ms(300);
LED1 = 1;
delay_ms(300); //发送后LED1闪一下
break; //退出最近的循环,从而变回接收模式,这句关键
}
}
else if (KEY2 == 0)
{
delay_ms(5);//消抖动
if (KEY2 == 0)
{
while (!KEY2);
TxMode(); //发送模式
Tx_Buf1[0] = 2; //将2发送过去
NRF24L01TxPacket(Tx_Buf1); //发送命令数据
LED1 = 0;
delay_ms(300);
LED1 = 1;
delay_ms(300);
break; //退出最近的循环,从而变回接收模式,这句关键
}
}
else if (KEY3 == 0)
{
delay_ms(5);//消抖动
if (KEY3 == 0)
{
while (!KEY3);
TxMode(); //发送模式
Tx_Buf1[0] = 3; //将3发送过去
NRF24L01TxPacket(Tx_Buf1); //发送命令数据
LED1 = 0;
delay_ms(300);
LED1 = 1;
delay_ms(300);
break; //退出最近的循环,从而变回接收模式,这句关键
}
}
else if (KEY4 == 0) //按了按键8,则变成发送模式,发送对应数据,发送完后变成接收模式
{
delay_ms(5);//消抖动
if (KEY4 == 0)
{
while (!KEY4);
TxMode(); //发送模式
Tx_Buf1[0] = 4; //将4发送过去
NRF24L01TxPacket(Tx_Buf1); //发送命令数据
LED1 = 0;
delay_ms(300);
LED1 = 1;
delay_ms(300);
break; //退出最近的循环,从而变回接收模式,这句关键
}
}
}
if (Rx_Buf[0] == 1) //若接收到对应的数据则实现对应功能
{
Rx_Buf[0] = 0; //清空数据
LED2 = 0;
delay_ms(300);
LED2 = 1;
delay_ms(300); //接收到数据后LED2闪烁1次
}
}
}
/*********************************************************************
* 函 数 名 : delay_ms
* 函数功能 : 延时z毫秒
* 参数列表 : 无
* 函数输出 : 无
*********************************************************************/
void delay_ms(u16 z) //延时函数
{
u16 y;
while (z--)
for(y=110; y>0; y--);
}
接收端:
/*********************************************************************
巫妖王V3.0开发板例程
朱有鹏物联网大讲堂出品(www.zhulaoshi.org)
技术支持和学习讨论请加朱有鹏单片机学习1群 214959925获取
**********************************************************************
模块名称:nRF24L01
模块功能: 2401无线收发模块
硬件接线:
注意事项:(1)
版 本:V1.00
作 者:朱有鹏(AstonZhu)
时 间:2018.10.30
**********************************************************************/
/*
**********************************************************************
* 头文件包含
**********************************************************************
*/
#include "2401.h"
/*
**********************************************************************
* 本地全局变量
**********************************************************************
*/
sbit CE = P1^0;
sbit CSN = P1^1;
sbit SCK = P1^2;
sbit MOSI = P1^3;
sbit MISO = P1^4;
sbit IRQ = P1^5;
u8 TX_ADDRESS[TX_ADR_WIDTH]= {0xE7,0xE7,0xE7,0xE7,0xE7}; //本地地址
u8 RX_ADDRESS[RX_ADR_WIDTH]= {0xE7,0xE7,0xE7,0xE7,0xE7}; //接收地址
/*
**********************************************************************
* 内部函数原型声明
**********************************************************************
*/
/********************底层驱动函数源码******************************/
//----------------------------------------------
//发送一字节[MOSI和MISO数据传递]
//----------------------------------------------
u8 NRF24L01SpiSendByte(u8 dat)
{
u8 i;
for (i=0; i<8; i++) //output 8-bit
{
//写入1位数据
MOSI = (dat & 0x80); //output 'uchar', MSB to MOSI
dat <<= 1; // shift next bit into MSB..
//读取1位数据
SCK = 1; // Set SCK high..
if (MISO)
{
dat |= 1;
}
else
{ // capture current MISO bit
dat &= 0xFE;
}
SCK = 0; // ..then set SCK low again
}
return (dat); // return read uchar
}
//----------------------------------------------
//延时n个10us
//----------------------------------------------
void DelayN10us(u16 n)
{
for (; n>0; n--)
{
u8 a,b;
for (b=1; b>0; b--)
for (a=2; a>0; a--);
}
}
//----------------------------------------------
//NRF24L01检测是否存在
//----------------------------------------------
u8 NRF24L01Check(void)
{
u8 bu[5] = {0XA5, 0XA5, 0XA5, 0XA5, 0XA5};
u8 bu1[5];
u8 i;
SpiWriteBuf(WRITE_REG+TX_ADDR, bu, 5); //写入5个字节的地址.
SpiReadBuf(TX_ADDR, bu1, 5); //读出写入的地址
for (i=0; i<5; i++)
if (bu1[i] != 0XA5)
break;
if (i != 5)
return 1; //NRF24L01不在位
return 0; //NRF24L01在位
}
//----------------------------------------------
//NRF24L01初始化
//----------------------------------------------
void InitNRF24L01(void)
{
u8 buf[5] = {0};
DelayN10us(10);
CE = 0; // chip enable
CSN= 0; // Spi disable
SpiReadBuf(TX_ADDR, buf, TX_ADR_WIDTH);//debug 测试原来的本地地址:复位值是:0xE7 0xE7 0xE7 0xE7 0xE7
}
//----------------------------------------------
//函数:uchar SPI_Read(uchar reg)
//功能:NRF24L01的SPI时序,读取指定寄存器的内容
//----------------------------------------------
u8 SpiReadReg(u8 reg)
{
u8 reg_val;
CSN = 0; // CSN low, initialize SPI communication...
NRF24L01SpiSendByte(reg); // Select register to read from..
reg_val = NRF24L01SpiSendByte(0); // ..then read registervalue
CSN = 1; // CSN high, terminate SPI communication
return (reg_val); // return register value
}
//----------------------------------------------
//函数:uchar SPI_Write(uchar reg)
//功能:NRF24L01的SPI时序,写入指定寄存器的内容
//----------------------------------------------
u8 SpiWriteReg(u8 reg, u8 value)
{
u8 status = 0;
CSN = 0; // CSN low, init SPI transaction
status = NRF24L01SpiSendByte(reg); // select register
NRF24L01SpiSendByte(value); // ..and write value to it..
CSN = 1; // CSN high again
return (status); // return nRF24L01 status uchar
}
//----------------------------------------------
//函数:uint SpiReadBuf
//功能: 用于读数据
//参数:reg:为寄存器地址
// pBuf:为待读出数据地址
// uchars:读出数据的个数
//----------------------------------------------
u8 SpiReadBuf(u8 reg, u8 *pBuf, u8 Len)
{
u16 status, i;
CSN = 0; // Set CSN low, init SPI tranaction
status = NRF24L01SpiSendByte(reg); // Select register to write to and read status uchar
for (i=0; i
#ifndef __NRF24L01_H__
#define __NRF24L01_H__
/*
**********************************************************************
* 头文件包含
**********************************************************************
*/
#include "common.h"
/*
**********************************************************************
* 本地宏定义
**********************************************************************
*/
#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
///***************************************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栈入栈出状态寄存器设置
/*
**********************************************************************
* 外部函数原型声明
**********************************************************************
*/
u8 NRF24L01SpiSendByte(u8 dat);
void DelayN10us(u16 n);
u8 NRF24L01Check(void);
void InitNRF24L01(void);
u8 SpiReadReg(u8 reg);
u8 SpiWriteReg(u8 reg, u8 value);
u8 SpiReadBuf(u8 reg, u8 *pBuf, u8 Len);
u8 SpiWriteBuf(u8 reg, u8 *pBuf, u8 Len);
void RxMode(void);
u8 NRF24L01RxPacket(u8 *rx_buf);
void TxMode(void);
void NRF24L01TxPacket(u8 *tx_buf);
#endif /*__NRF24L01_H__ */
/*********************************************************************
巫妖王V3.0开发板例程
朱有鹏物联网大讲堂出品(www.zhulaoshi.org)
技术支持和学习讨论请加朱有鹏单片机学习1群 214959925获取
**********************************************************************
实验序列:24
实验任务:
实现现象:
硬件接线:插入2401模块,注意方向是朝外的。
注意事项:(1)
(2)
(3)
版 本:V1.00
作 者:朱有鹏(AstonZhu)
时 间:2018.10.30
**********************************************************************/
/*
**********************************************************************
* 头文件包含
**********************************************************************
*/
#include "2401.h"
/*
**********************************************************************
* 本地宏定义
**********************************************************************
*/
/*
**********************************************************************
* 本地全局变量
**********************************************************************
*/
sbit KEY4 = P3^3; //发送按键
sbit LED1 = P2^0; //小灯闪烁提示报警
sbit LED2 = P2^1; //发送数据时显示灯
sbit LED3 = P2^2; //接收到数据后的功能实现灯
sbit LED4 = P2^3;
sbit LED5 = P2^4;
sbit LED6 = P2^5;
void delay_ms(u16 z);
/*********************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 参数列表 : 无
* 函数输出 : 无
*********************************************************************/
void main(void)
{
u8 Tx_Buf[] = {1}; //发送的信息1
u8 Rx_Buf[32]; //接收到的数据暂存器,最多32字节数据
InitNRF24L01();
LED2 = 1; //初始灯2熄灭
while (NRF24L01Check()) //检查不到24l01则小灯闪烁提示报警
{
LED1 = 0;
delay_ms(200);
LED1 = 1;
delay_ms(200);
}
while (1)
{
RxMode(); //接收模式
while (!NRF24L01RxPacket(Rx_Buf)) //等待接收数据,返回1则接收到数据,在等待接收数据期间,可以随时变成发送模式
{
if (KEY4 == 0) //按了按键4,则变成发送模式,发送对应数据,发送完后变成接收模式
{
delay_ms(5);//消抖动
if (KEY4 == 0)
{
while (!KEY4);
TxMode(); //发送模式
NRF24L01TxPacket(Tx_Buf); //发送命令数据
LED2 = 0;
delay_ms(300);
LED2 = 1;
delay_ms(300); //发送后LED2闪一下
break; //退出最近的循环,从而变回接收模式,这句关键
}
}
}
switch (Rx_Buf[0])
{//对数据进行分析来控制灯亮
case 0:
break;
case 1:
Rx_Buf[0] = 0; //清空数据
LED3 = 0;
delay_ms(300);
LED3 = 1;
delay_ms(300);
break;
case 2:
Rx_Buf[0] = 0; //清空数据
LED4 = 0;
delay_ms(300);
LED4 = 1;
delay_ms(300);
break;
case 3:
Rx_Buf[0] = 0; //清空数据
LED5 = 0;
delay_ms(300);
LED5 = 1;
delay_ms(300);
break;
default:
Rx_Buf[0] = 0; //清空数据
LED6 = 0;
delay_ms(300);
LED6 = 1;
delay_ms(300);
break;
}
}
}
/*********************************************************************
* 函 数 名 : delay_ms
* 函数功能 : 延时z毫秒
* 参数列表 : 无
* 函数输出 : 无
*********************************************************************/
void delay_ms(u16 z) //延时函数
{
u16 y;
while (z--)
for (y=110; y>0; y--);
}