main.c

 #include<reg51.h>
#include"2401.h" #define uint unsigned int
#define uchar unsigned char sbit KEY8=P3^; //发送按键
sbit beep=P2^;//喇叭
sbit LED6=P1^; ////接收到数据后的功能实现灯 void delay_ms(uint z) //延时函数
{
uint x,y;
for(x=z;x>;x--)
for(y=;y>;y--);
}
void delayms(unsigned int x)
{
unsigned int i;
while(x--)
for(i=;i>;i--);
}
void main()
{
uchar Tx_Buf1[]={};//发送的信息1
uchar Rx_Buf[]; //接收到的数据暂存器,最多32字节数据
init_NRF24L01();
LED6=;//初始灯6熄灭 while(NRF24L01_Check()) //检查不到24l01则报警
{
beep=;
delayms();
beep=;
delayms();
}
while()
{
RX_Mode();//接收模式
while(!nRF24L01_RxPacket(Rx_Buf)) //等待接收数据 ,返回1则接收到数据 ,在等待接收数据期间,可以随时变成发送模式
{
if(KEY8==) //按了按键8 则变成发送模式,发送对应数据,发送完后变成接收模式
{
delay_ms();//消抖动
if(KEY8==)
{
while(!KEY8);
TX_Mode(); //发送模式
nRF24L01_TxPacket(Tx_Buf1); // 发送命令数据
LED6=;
delay_ms();
LED6=;
delay_ms(); //发送后LED6闪一下
break; //退出最近的循环,从而变回接收模式,这句关键
} }
}
if(Rx_Buf[]==) //若接收到对应的数据则实现对应功能
{
Rx_Buf[]=;//清空数据
LED6=;
delay_ms();
LED6=;
delay_ms();//接收到数据 后闪烁
}
}
}
 #ifndef __NRF24L01_H__
#define __NRF24L01_H__
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int sbit CE =P1^;
sbit CSN =P1^;
sbit SCK =P1^;
sbit MOSI =P1^;
sbit MISO =P1^;
sbit IRQ =P1^; //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);
///*************************************************************************************
uchar NRF24SPI_Send_Byte(uchar dat)
{
uchar i;
for (i = ; i < ; i++) // output 8-bit
{
//发送1位数据
if (dat & 0x80) // output 'uchar', MSB to MOSI
{
MOSI = ;
}
else
{
MOSI = ;
} dat <<= ; // shift next bit into MSB.. //读取1位数据
SCK = ; // Set SCK high.. if (MISO)
{
dat |= ;
} // capture current MISO bit
else
{
dat &= 0xFE;
}
SCK = ; // ..then set SCK low again
} return(dat); // return read uchar
} void Delay_n10us(uint n) //延时n个10us
{
for(;n>;n--)
{
unsigned char a,b;
for(b=;b>;b--)
for(a=;a>;a--);
}
}
///****************************************************************************************
///*NRF24L01检测是否存在
///***************************************************************************************/
uchar NRF24L01_Check(void)
{
uchar bu[]={0XA5,0XA5,0XA5,0XA5,0XA5};
uchar bu1[];
uchar i;
SPI_Write_Buf(WRITE_REG+TX_ADDR,bu,);//写入5个字节的地址.
SPI_Read_Buf(TX_ADDR,bu1,); //读出写入的地址
for(i=;i<;i++)if(bu1[i]!=0XA5)break;
if(i!=)return ; //NRF24L01不在位
return ; //NRF24L01在位
}
///****************************************************************************************
///*NRF24L01初始化
///***************************************************************************************/
void init_NRF24L01(void)
{
uchar buf[]={};
Delay_n10us();
CE = ; // chip enable
CSN= ; // Spi disable SPI_Read_Buf(TX_ADDR, buf, TX_ADR_WIDTH);//debug 测试原来的本地地址:复位值是:0xE7 0xE7 0xE7 0xE7 0xE7 // 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_WR_Reg(WRITE_REG + EN_AA, 0x01); // 频道0自动 ACK应答允许
// SPI_WR_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Page21
// SPI_WR_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 设置自动重发时间和次数:500us + 86us, 10 retrans...
// SPI_WR_Reg(WRITE_REG + RF_CH, 22); // 设置信道工作为2.4GHZ,收发必须一致
// SPI_WR_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
// SPI_WR_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1MHZ,发射功率为最大值0dB
//
// SPI_RD_Reg(WRITE_REG + EN_AA);
// SPI_RD_Reg(WRITE_REG + EN_RXADDR);
// SPI_RD_Reg(WRITE_REG + RF_CH);
// SPI_RD_Reg(WRITE_REG + RX_PW_P0);
// SPI_RD_Reg(WRITE_REG + RF_SETUP);
}
///****************************************************************************************************
///*函数:uchar SPI_Read(uchar reg)
///*功能:NRF24L01的SPI时序
///****************************************************************************************************/
uchar SPI_RD_Reg(uchar reg)
{
uchar reg_val; CSN = ; // CSN low, initialize SPI communication...
NRF24SPI_Send_Byte(reg); // Select register to read from..
reg_val = NRF24SPI_Send_Byte(); // ..then read registervalue
CSN = ; // CSN high, terminate SPI communication return(reg_val); // return register value
}
//****************************************************************************************************/
//*功能:NRF24L01读写寄存器函数
//****************************************************************************************************/
uchar SPI_WR_Reg(uchar reg, uchar value)
{
uchar status; CSN = ; // CSN low, init SPI transaction
status = NRF24SPI_Send_Byte(reg);// select register
NRF24SPI_Send_Byte(value); // ..and write value to it..
CSN = ; // CSN high again return(status); // return nRF24L01 status uchar
}
///****************************************************************************************************/
//*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar Len)
//*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
//****************************************************************************************************/
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar Len)
{
uint status,i; CSN = ; // Set CSN low, init SPI tranaction
status = NRF24SPI_Send_Byte(reg); // Select register to write to and read status uchar for(i=;i<Len;i++)
{
pBuf[i] = NRF24SPI_Send_Byte();
} CSN = ; return(status); // return nRF24L01 status uchar
}
//*********************************************************************************************************
//*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar Len)
//*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
//*********************************************************************************************************/
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar Len)
{
uint status,i; CSN = ; //SPI使能
status = NRF24SPI_Send_Byte(reg);
for(i=; i<Len; i++) //
{
NRF24SPI_Send_Byte(*pBuf);
pBuf ++;
}
CSN = ; //关闭SPI
return(status); //
} //****************************************************************************************************/
//*函数:void SetRX_Mode(void)
//*功能:数据接收配置
//****************************************************************************************************/
void RX_Mode(void)
{
uchar buf[]={};
CE = ; SPI_Read_Buf(TX_ADDR, buf, TX_ADR_WIDTH);//debug 测试原来的本地地址:复位值是:0xE7 0xE7 0xE7 0xE7 0xE7
//SPI_WR_Reg(WRITE_REG + CONFIG, 0x03);//SPI_WR_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收 //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_WR_Reg(WRITE_REG + EN_AA, );//0x01); // 频道0自动 ACK应答允许
SPI_WR_Reg(WRITE_REG + EN_RXADDR,0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Page21
SPI_WR_Reg(WRITE_REG + SETUP_RETR,0x1a); // 设置自动重发时间和次数:500us + 86us, 10 retrans...
SPI_WR_Reg(WRITE_REG + RF_CH, ); // 设置信道工作为2.4GHZ,收发必须一致
SPI_WR_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
SPI_WR_Reg(WRITE_REG + RF_SETUP, 0x0F); //设置发射速率为2MHZ,发射功率为最大值0dB SPI_WR_Reg(WRITE_REG + CONFIG, 0x0F);//0x0F);
CE = ;
Delay_n10us(); //200us
}
//******************************************************************************************************/
//*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
//*功能:数据读取后放如rx_buf接收缓冲区中
//******************************************************************************************************/
uchar nRF24L01_RxPacket(unsigned char* rx_buf)
{
uchar flag=;
uchar status; status=SPI_RD_Reg(NRFRegSTATUS); // 读取状态寄存其来判断数据接收状况 if(status & 0x40) // 判断是否接收到数据
{
CE = ; //SPI使能
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
flag =; //读取数据完成标志
}
SPI_WR_Reg(WRITE_REG+NRFRegSTATUS, status); //接收到数据后RX_DR,TX_DS,MAX_RT都置高为1,通过写1来清楚中断标志
return flag;
}
void TX_Mode(void)
{
CE = ;
//SPI_WR_Reg(WRITE_REG + CONFIG, 0x02); //0x0E // IRQ收发完成中断响应,16位CRC,主发送 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_WR_Reg(WRITE_REG + EN_AA, );//0x01); // 频道0自动 ACK应答允许
SPI_WR_Reg(WRITE_REG + EN_RXADDR,);// 0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Page21
SPI_WR_Reg(WRITE_REG + SETUP_RETR, );//0x1a); // 设置自动重发时间和次数:500us + 86us, 10 retrans...
SPI_WR_Reg(WRITE_REG + RF_CH, ); // 设置信道工作为2.4GHZ,收发必须一致
SPI_WR_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
SPI_WR_Reg(WRITE_REG + RF_SETUP, 0x0F); //设置发射速率为2MHZ,发射功率为最大值0dB SPI_WR_Reg(WRITE_REG + CONFIG, 0x0E);
CE = ;
}
//***********************************************************************************************************
//*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
//*功能:发送 tx_buf中数据
//**********************************************************************************************************/
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
CE = ; //StandBy I模式
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据
// SPI_WR_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
CE = ; //置高CE,激发数据发送
} ///************************************主函数************************************************************
//void NRF_Send(void)
//{
// //static uint counter=0;
// static uchar flag=0;
//
// //TX_Mode();
//
// //IntervalTimems(100);
// if(flag==0)
// {
// flag=1;
// //memcpy(TxBuf, "1234567890abcdefghij", 20);
// nRF24L01_TxPacket(TxBuf);
// }
// else
// {
// flag=0;
// //memcpy(TxBuf, "abcdefghij1234567890", 20);
// nRF24L01_TxPacket(TxBuf);
// }
//
//} #endif /*__NRF24L01_H__ */

2401.h

[51单片机] SPI nRF24L01无线 [可以放在2个单片机里实现通信]的更多相关文章

  1. [51单片机] SPI nRF24L01 无线简单程序 1

    main.c #include <reg51.h> #include <api.h> #define uchar unsigned char /**************** ...

  2. STC8H开发(五): SPI驱动nRF24L01无线模块

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...

  3. nRF24L01无线模块笔记

    nRF24L01模块 官网链接: https://www.nordicsemi.com/Products/nRF24-series 常见的无线收发模块, 工作在2.4GHz频段, 适合近距离遥控和数据 ...

  4. NRF24L01无线通讯模块驱动

    NRF24L01 无线模块,采用的芯片是 NRF24L01,该芯片的主要特点如下: )2.4G 全球开放的 ISM 频段,免许可证使用. )最高工作速率 2Mbps,高校的 GFSK 调制,抗干扰能力 ...

  5. nRF2401A/nRF24L01/nRF24L01+无线模块最常见问题汇集(转)

    俗话说:每个人一生下来什么都会的,都是通过自己努力和探索出来的,NRF系列芯片,刚开始都好奇心加兴趣才来捣鼓它的,刚开始做硬件和软件,没有收发数据弄得整个人头都快炸开了,所以在此和大家分享一下前辈的经 ...

  6. 【Espruino】NO.15 nRF24L01+无线收发器

    http://blog.csdn.net/qwert1213131/article/details/35853747 本文属于个人理解,能力有限,纰漏在所难免,还望指正! [小鱼有点电] [Espru ...

  7. STM32+NRF24L01无线(转)

    源:STM32+NRF24L01无线 硬件SPI和模拟SPI源码: nrf24发送(模拟SPI)BHS-STM32.rar nrf24接收(模拟SPI)BHS-STM32.rar nrf24发送(硬件 ...

  8. NRF24L01无线模块的使用

    NRF2401芯片pin定义 NRF24L01模块pin定义 VCC 脚接电压范围为 1.9V~3.6V 之间, 不能在这个区间之外, 超过 3.6V 将会烧毁模块, 推荐电压 3.3V 左右 除电源 ...

  9. [Micropython]TPYBoard v10x NRF24L01无线通讯模块使用教程

    1.实验目的: •       学习使用NRF24L01无线通讯模块 2.所需原器件: •       TPYBoard v10X开发板两块 •       NRF24L01无线通讯模块两个 •    ...

随机推荐

  1. 种类并查集(POJ 1703)

    1703 -- Find them, Catch them http://poj.org/problem?id=1703 题目大意:有2个敌对帮派,输入D a b表示a,b在不同帮派,输入A a b表 ...

  2. XGBoost参数调优完全指南(附Python代码)

    XGBoost参数调优完全指南(附Python代码):http://www.2cto.com/kf/201607/528771.html https://www.zhihu.com/question/ ...

  3. 安卓中adapter的应用

    个人菜鸟总结,期待大神指点,悉心倾看! Adapter是ListView界面与数据之间的桥梁,Adapter提供对数据的访问,也负责为每一项数据产生一个对应的View(白话通俗点:先写adapter为 ...

  4. Pig Latin

    function translate(str) { //return str; var list = ['a','e','i','o','u']; if(list.indexOf(str[0]) &g ...

  5. 技术英文单词贴--R

    R redirect 重定向,改变方向 reference 参考,提及,引用 register 注册,登记,挂号 render 渲染 represent 代表,象征 route 路线,路由,通道 ro ...

  6. Unicode explorer

    It can be cumbersome to work out some of the details of this by hand, so you can use the little Java ...

  7. 将Discuz.net 集成到asp.net

    1,将bbs文件夹拷贝到网站的根目录下: 2,将bbs里面的bin目录,config目录,cache目录,DNT.config文件拷贝到网站根目录下: 3,修改网站web.config文件,在http ...

  8. 多媒体技术基础之---Come on!来点儿音乐吧

    其实要说在Linux系统下播放音乐,确实是一件让人非常抓狂的事情,抛开各种音频格式的商业授权不说,即使提供给你相应的解码库,能玩儿得转的人那又是少之又少.可能有些盆友说ubuntu这方面确实做得不错, ...

  9. XE3随笔3:访问

    测试数据提前加入 Memo1 中: { "name": "张三", /* 注释 */ "age": 33, "sex": ...

  10. JS手机端去除默认自带的选择复制菜单

    在需要的div上添加以下控制-webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: ...