NRF24L01无线模块收发程序(实测成功 多图)

合集下载

NRF24L01无线模块收发程序例程

NRF24L01无线模块收发程序例程

//下面是接收的NRF24L01的程序。

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#include<reg52.h>#include "nrf24l01.h"#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit IRQ =P1^2;//输入sbit MISO =P1^3; //输入sbit MOSI =P1^1;//输出sbit SCLK =P1^4;//输出sbit CE =P1^5;//输出sbit CSN =P1^0;//输出uchar RevTempDate[5];//最后一位用来存放结束标志uchar code TxAddr[]={0x34,0x43,0x10,0x10,0x01};//发送地址/*****************状态标志*****************************************/uchar bdata sta; //状态标志sbit RX_DR=sta^6;sbit TX_DS=sta^5;sbit MAX_RT=sta^4;/*****************SPI时序函数******************************************/ uchar NRFSPI(uchar date){uchar i;for(i=0;i<8;i++) // 循环8次{if(date&0x80)MOSI=1;elseMOSI=0; // byte最高位输出到MOSIdate<<=1; // 低一位移位到最高位SCLK=1;if(MISO) // 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据date|=0x01; // 读MISO到byte最低位SCLK=0; // SCK置低}return(date); // 返回读出的一字节}/**********************NRF24L01初始化函数*******************************/ void NRF24L01Int(){NRFDelay(2);//让系统什么都不干CE=0;CSN=1;SCLK=0;IRQ=1;}/*****************SPI读寄存器一字节函数*********************************/ uchar NRFReadReg(uchar RegAddr){uchar BackDate;CSN=0;//启动时序NRFSPI(RegAddr);//写寄存器地址BackDate=NRFSPI(0x00);//写入读寄存器指令CSN=1;return(BackDate); //返回状态}/*****************SPI写寄存器一字节函数*********************************/ uchar NRFWriteReg(uchar RegAddr,uchar date){uchar BackDate;CSN=0;//启动时序BackDate=NRFSPI(RegAddr);//写入地址NRFSPI(date);//写入值CSN=1;return(BackDate);}/*****************SPI读取RXFIFO寄存器的值********************************/ uchar NRFReadRxDate(uchar RegAddr,uchar *RxDate,uchar DateLen){ //寄存器地址//读取数据存放变量//读取数据长度//用于接收uchar BackDate,i;CSN=0;//启动时序BackDate=NRFSPI(RegAddr);//写入要读取的寄存器地址for(i=0;i<DateLen;i++) //读取数据{RxDate[i]=NRFSPI(0);}CSN=1;return(BackDate);}/*****************SPI写入TXFIFO寄存器的值**********************************/ uchar NRFWriteTxDate(uchar RegAddr,uchar *TxDate,uchar DateLen){ //寄存器地址//写入数据存放变量//读取数据长度//用于发送uchar BackDate,i;CSN=0;BackDate=NRFSPI(RegAddr);//写入要写入寄存器的地址for(i=0;i<DateLen;i++)//写入数据{NRFSPI(*TxDate++);}CSN=1;return(BackDate);}/*****************NRF设置为发送模式并发送数据******************************/ void NRFSetTxMode(uchar *TxDate){ //发送模式CE=0;NRFWriteTxDate(W_REGISTER+TX_ADDR,TxAddr,TX_ADDR_WITDH);//写寄存器指令+P0地址使能指令+发送地址+地址宽度NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH);//为了应答接收设备,接收通道0地址和发送地址相同NRFWriteTxDate(W_TX_PAYLOAD,TxDate,TX_DA TA_WITDH);//写入数据/******下面有关寄存器配置**************/NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0NRFWriteReg(W_REGISTER+SETUP_RETR,0x0a); // 自动重发延时等待250us+86us,自动重发10次NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益NRFWriteReg(W_REGISTER+CONFIG,0x0e); // CRC使能,16位CRC校验,上电CE=1;NRFDelay(5);//保持10us秒以上}/*****************NRF设置为接收模式并接收数据******************************/ //接收模式void NRFSetRXMode(){CE=0;NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH); // 接收设备接收通道0使用和发送设备相同的发送地址NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40NRFWriteReg(W_REGISTER+RX_PW_P0,TX_DATA_WITDH); // 接收通道0选择和发送通道相同有效数据宽度NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益NRFWriteReg(W_REGISTER+CONFIG,0x0f); // CRC使能,16位CRC校验,上电,接收模式CE = 1;NRFDelay(5);}/****************************检测是否有接收到数据******************************/void CheckACK(){ //用于发射模式接收应答信号sta=NRFReadReg(R_REGISTER+STATUS); // 返回状态寄存器if(TX_DS)NRFWriteReg(W_REGISTER+STATUS,0xff); // 清除TX_DS或MAX_RT中断标志}/*************************接收数据*********************************************/void GetDate(){sta=NRFReadReg(R_REGISTER+STATUS);//发送数据后读取状态寄存器if(RX_DR) // 判断是否接收到数据{CE=0;//待机NRFReadRxDate(R_RX_PAYLOAD,RevTempDate,RX_DATA_WITDH);// 从RXFIFO读取数据接收4位即可,后一位位结束位NRFWriteReg(W_REGISTER+STATUS,0xff); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标CSN=0;NRFSPI(FLUSH_RX);//用于清空FIFO !!关键!!不然会出现意想不到的后果!!!大家记住!!CSN=1;}//NRFWriteReg(W_REGISTER+STA TUS,0xff); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标}void NRFDelay(uint t){uint x,y;for(x=t;x>0;x--)for(y=110;y>0;y--);}。

nRF24L01无线模块讲解解读

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发送接收一体程序(以调通,解决了接收端只能接收一次的问题)/**************************************************基于单片机无线报警系统主机(机载设别)系统程序/**************************************************/#include#include#define uchar unsigned char/***************************************************/#define TX_ADR_WIDTH 5 // 5字节宽度的发送/接收地址#define TX_PLOAD_WIDTH 4 // 数据通道有效数据宽度uchar code TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01}; // 定义一个静态发送地址uchar RX_BUF[4]={0,0,0,0};uchar TX_BUF[4]={0x20,0x20,0x20,0x20};uchar flag; //无线模块接受数据标志uchar DATA = 0x01;uchar bdata sta;unsigned int a,k; //定时器延时参数uchar mark; //传感器响应标志位uchar mark1; // 延时标志位sbit RX_DR = sta^6; //接受数据成功标志位sbit TX_DS = sta^5; // 发送成功标志位sbit MAX_RT = sta^4; //最大重发上限标志位sbit HW=P2^0; //红外感应模块输入端sbit ZD=P1^7; //震动传感器输入端sbit LED=P2^1; //LED报警器输出端sbit SDA=P2^4; //语音模块数据控制端sbit ONN=P2^3; //语音芯片电源控制端口sbit FM =P2^5; //蜂鸣器/************************************************** 函数:delayus()描述:延迟x微秒/**************************************************/void delayus(unsigned int t){while(t--);}/************************************************** 函数:delayms()描述:延迟x毫秒/**************************************************/void delayms(unsigned int h){unsigned int j;while(h--)for(j=85;j>0;j--);}/************************************************** 函数:delays()描述:延迟x.xx秒/**************************************************/void delays( float h){unsigned int i,j;h*=100;while(h--){for(i=0;i<235;i++)for(j=0;j<3;j++);}}/************************************************** 函数:sendadd()描述:语音模块发送地址信号/**************************************************/ void sendadd(unsigned char addr){uchar i;delayms(5); /* 数据信号置于低电平5ms */for(i=0;i<8;i++){ SDA=1;if(addr & 1){delayus(60); /* 高电平比低电平为600us:200us,表示发送数据1 */SDA=0;delayus(20);}else{delayus(20);SDA=0; /* 高电平比低电平为200us:600us,表示发送数据0 */ delayus(60);}addr>>=1;}SDA=1;}/**************************************************函数:SPI_RW()描述:根据SPI协议,写一字节数据到nRF24L01,同时从nRF24L01 读出一字节/**************************************************/uchar SPI_RW(uchar byte){for(i=0; i<8; i++) // 循环8次{MOSI = (byte & 0x80); // byte最高位输出到MOSIbyte <<= 1; // 低一位移位到最高位SCK = 1; // 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据byte |= MISO; // 读MISO到byte最低位SCK = 0; // SCK置低}return(byte); // 返回读出的一字节}/**************************************************//**************************************************函数:SPI_RW_Reg()描述:写数据value到reg寄存器/**************************************************/uchar SPI_RW_Reg(uchar reg, uchar value){uchar status;CSN = 0; // CSN置低,开始传输数据status = SPI_RW(reg); // 选择寄存器,同时返回状态字SPI_RW(value); // 然后写数据到该寄存器CSN = 1; // CSN拉高,结束数据传输return(status); // 返回状态寄存器}/************************************************** 函数:clear()描述:清TX_FIFO寄存器/**************************************************/void clear(){CSN=0;SPI_RW(FLUSH_TX);CSN=1;}/************************************************** 函数:SPI_Read()描述:从reg寄存器读一字节/**************************************************/ uchar SPI_Read(uchar reg){uchar reg_val;CSN = 0; // CSN置低,开始传输数据SPI_RW(reg); // 选择寄存器reg_val = SPI_RW(0); // 然后从该寄存器读数据CSN = 1; // CSN拉高,结束数据传输return(reg_val); // 返回寄存器数据}/**************************************************//**************************************************函数:SPI_Read_Buf()描述:从reg寄存器读出bytes个字节,通常用来读取接收通道数据或接收/发送地址/**************************************************/ uchar SPI_Read_Buf(uchar reg, uchar * pBuf, uchar bytes) {uchar status, i;CSN = 0; // CSN置低,开始传输数据status = SPI_RW(reg); // 选择寄存器,同时返回状态字for(i=0; ipBuf[i] = SPI_RW(0); // 逐个字节从nRF24L01读出CSN = 1; // CSN拉高,结束数据传输return(status); // 返回状态寄存器}/**************************************************//**************************************************函数:SPI_Write_Buf()描述:把pBuf缓存中的数据写入到nRF24L01,通常用来写入发射通道数据或接收/发送地址/**************************************************/ uchar SPI_Write_Buf(uchar reg, uchar * pBuf, uchar bytes) {uchar status, i;CSN = 0; // CSN置低,开始传输数据status = SPI_RW(reg); // 选择寄存器,同时返回状态字for(i=0; iSPI_RW(pBuf[i]); // 逐个字节写入nRF24L01CSN = 1; // CSN拉高,结束数据传输return(status); // 返回状态寄存器}/**************************************************函数:RX_Mode()描述:这个函数设置nRF24L01为接收模式,等待接收发送设备的数据包/**************************************************/void RX_Mode(void){CE = 0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0F); // CRC使能,16位CRC校验,上电,接收模式CE = 1;delayus(200); // 拉高CE启动接收设备}/**************************************************函数:TX_Mode()描述:这个函数设置nRF24L01为发送模式,(CE=1持续至少10us),130us后启动发射,数据发送结束后,发送模块自动转入接收模式等待应答信号。

NRF24L01全双工调试程序 自动切换收发模式 可用于实现对讲机

NRF24L01全双工调试程序 自动切换收发模式 可用于实现对讲机
sbit P21 = P2^1;
sbit P22 = P2^2;
sbit P23 = P2^3;
sbit P24 = P2^4;
sbit P25 = P2^5;
sbit P26 = P2^6;
sbit P27 = P2^7;
sbit P30 = P3^0;
sbit P31 = P3^1;
sbit P32 = P3^2;
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0f);//设置发射速率为2MHZ,发射功率为最大值0dB
SPI_RW_Reg(WRITE_REG + CONFIG, 0x7c);//IRQ引脚不显示中断掉电模式1~16CRC校验
ucharbdata sta;
sbitRX_DR=sta^6;
sbitTX_DS=sta^5;
sbitMAX_RT=sta^4;
//********************************NRF24L01初始化******************************************//
void init_NRF24L01()
{
delayus(100);
CE=0; //片选使能
CSN=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); //写接收端地址

NRF24L01收发程序

NRF24L01收发程序

/******* ******** ******** ******** ******** ******** ******** ******** ******** ******* ******** ******** ******/ uchar SPI_Read (uchar reg) { uchar reg_val; CSN = 0; // CSN low, initiali ze SPI communic ation... SPI_RW(r eg); // Select register to read from.. reg_val = SPI_RW(0 ); // ..then read register value
/*NRF24L 01 初始 化 //****** ******** ******** ******** ******** ******** ******** ******** */ void init_NRF 24L01(vo id) { inerDela y_us(100 ); CE=0; // chip enable CSN=1; // Spi disable SCK=0; // SPI_Writ e_Buf(WR ITE_REG + TX_ADDR, TX_ADDRE SS, TX_ASCK high.. uchar |= MISO; // capture current MISO bit SCK = 0; // ..then set SCK low again } return(u char); // return read uchar } /******* ******** ******** ******** ******** ******** ******** ******** ******** ******* ******** ******** ****** /*函数: uchar SPI_Read (uchar reg) /*功能: NRF24L01 的SPI 时 序

无线收发24L01程序

无线收发24L01程序
#define CE_HIGH P3OUT|=BIT2//P3.2控制芯片发射使能
#define CE_LOW P3OUT&=~BIT2
#define IRQ P3IN&BIT3//读取P3.3的值*/
/***********模拟SPI方式***********/
标签: 24L01 程序
无线收发 24L01程序
最近项目基本都做完了,闲着没事了,过来整理下博客,分享下自己的程序!这是几个月前调通的程序,24L01无线收发芯片,mcu用的是msp430f2274!该程序花费了我大量心血!算是我学起单片机来攻克的第一块芯片吧!注释相当详细!
#include<msp430x22x4.h>
CE_HIGH;
delay_us(130);
sta="SPI"_Read(READ_REG+STATUS);
while(sta&0x40)
{
CE_LOW;//进入闲置模式
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);/*数据宽度未定义*/
//SPI命令字
#define READ_REG 0X00//读寄存器命令
#define WRITE_REG 0X20//写寄存器命令
#define RD_RX_PLOAD 0X61//读有效数据命令
#define WR_TX_PLOAD 0XA0//写有效数据命令
#define FLUSH_TX 0XE1//清除TX_FIFO应用于发射模式
#define MOSI_HIGH P3OUT|=BIT4
#define MOSI_LOW P3OUT&=~BIT4

nrf24l01使用与调试经验总结(包括一收多发)

nrf24l01使用与调试经验总结(包括一收多发)

nrf24l01使用与调试经验总结(包括一收多发--1主机最多6从机)----------------------------------------------------------------------------------------------------------------------------主要特性工作在2.4GHz ISM 频段调制方式:GFSK/FSK数据速率:2Mbps/1Mbps/250Kbps超低关断功耗:<0.7uA超低待机功耗:<15uA快速启动时间:<130uS内部集成高PSRR LDO宽电源电压范围:1.9-3.6V数字IO 电压: 3.3V/5V低成本晶振:16MHz±60ppm接收灵敏度:<-83dBm @2MHz最高发射功率:7dBm接收电流(2Mbps):<15mA发射电流(2Mbps):<12mA(0dBm)10MHz 四线SPI 模块内部集成智能ARQ 基带协议引擎收发数据硬件中断输出支持1bit RSSI 输出极少外围器件,降低系统应用成本QFN20 封装或COB 封装注意:C代表了命令,S表示寄存器值,D表示数据写数据:SPI写命令+寄存器地址----->SPI写入数据读数据:SPI写寄存器地址(可以使用读命令+寄存器地址)----->SPI读取数据不论是读取或者写入数据,甚至是读/写len长度的数据都要先写寄存器地址;总的来说时候就三个模式:1.待机模式(待机模式+掉电省电模式)2.发送模式3.接受模式具体各个模式介绍参考数据手册。

----------------------------------------------------------------------------------------------------------------nrf发送数据是以包来发送。

nRF24L01无线通信模块使用手册

nRF24L01无线通信模块使用手册

nRF24L01无线通信模块使用手册一、模块简介该射频模块集成了NORDIC公司生产的无线射频芯片nRF24L01:1.支持2.4GHz的全球开放ISM频段,最大发射功率为0dBm2.2Mbps,传输速率高3.功耗低,等待模式时电流消耗仅22uA4.多频点(125个),满足多点通信及跳频通信需求5.在空旷场地,有效通信距离:25m(外置天线)、10m(PCB天线)6.工作原理简介:发射数据时,首先将nRF24L01配置为发射模式,接着把地址TX_ADDR和数据TX_PLD 按照时序由SPI口写入nRF24L01缓存区,TX_PLD必须在CSN为低时连续写入,而TX_ADDR在发射时写入一次即可,然后CE置为高电平并保持至少10μs,延迟130μs后发射数据;若自动应答开启,那么nRF24L01在发射数据后立即进入接收模式,接收应答信号。

如果收到应答,则认为此次通信成功,TX_DS置高,同时TX_PLD从发送堆栈中清除;若未收到应答,则自动重新发射该数据(自动重发已开启),若重发次数(ARC_CNT)达到上限,MAX_RT置高,TX_PLD不会被清除;MAX_RT或TX_DS置高时,使IRQ变低,以便通知MCU。

最后发射成功时,若CE为低,则nRF24L01进入待机模式1;若发送堆栈中有数据且CE为高,则进入下一次发射;若发送堆栈中无数据且CE为高,则进入待机模式2。

接收数据时,首先将nRF24L01配置为接收模式,接着延迟130μs进入接收状态等待数据的到来。

当接收方检测到有效的地址和CRC时,就将数据包存储在接收堆栈中,同时中断标志位RX_DR置高,IRQ变低,以便通知MCU去取数据。

若此时自动应答开启,接收方则同时进入发射状态回传应答信号。

最后接收成功时,若CE变低,则nRF24L01进入空闲模式1。

三、模块引脚说明1 / 197 NC 空 8 CSN 芯片片选信号 I 9 CE 工作模式选择I 10+5V电源四、模块与AT89S52单片机接口电路注:上图为示意连接,可根据自己实际需求进行更改;使用AT89S52MCU 模块时,请将Nrf24L01通讯模块每个端口(MOSI 、SCK 、CSN 和CE )接4.7K 的排阻上拉到VCC 增强其驱动能力(如下图:)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

NRF24L01无线模块收发程序(实测成功多图)本模块是NRF24L01无线传输模块,用于无线传输数据,距离不远,一般只是能够满足小距离的传输,目测是4-5m,价格一般是4元左右,可以方便的买到。

51最小系统学习板就可以,当时是用了两块学习板,一块用于发送,一块用于接收。

小车也是比较容易购到的,四个端口控制两个电机,两个控制一个电机,当两个端口高低电平不同时电机就会转动,即为赋值1和0是电机转动,赋值可以用单片机作用,当然这是小车启动部分,前进后退左转右转就是你赋值0和1的顺序问题了。

整体思路是用发射端的按键控制小车,即为按键按下就前进,再按其他按键实现其他功能,本次程序是在用NRF24L01发射数据在接收端用1602显示的基础上改变。

下面是程序源码(有好几个文件,分别创建)////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////#include#include#include'1602.h'#include'delay.h'#include 'nrf24l01.h'#define uint unsigned int#define uchar unsigned charuint Weight_Shiwu=1234;unsigned char KeyScan(void);//键盘扫描// unsigned char KeyScan(void);//键盘扫描//#define KeyPort P0sbit KEY1 = P0^0;sbit KEY2 = P0^1;sbit KEY3 = P0^2;sbit KEY4 = P0^3;sbit KEY5 = P0^4;void main(){// char TxDate[4];// LCD_Init(); //初始化液晶屏// LCD_Clear(); //清屏// NRF24L01Int(); //初始化LCD1602// LCD_Write_String(4,0,'welcome');while(1){KeyScan();}}unsigned char KeyScan(void){/********************************************************/ char TxDate[4];{if(!KEY1) //如果检测到低电平,说明按键按下{DelayMs(10); //延时去抖,一般10-20msif(!KEY1) //再次确认按键是否按下,没有按下则退出{while(!KEY1);//如果确认按下按键等待按键释放,没有则退出{TxDate[0] = 1;//向左转TxDate[1] = 0;TxDate[2] = 1;TxDate[3] = 1;NRFSetTxMode(TxDate);//发送数据·while(CheckACK()); //检测是否发送完毕}}}/********************************************************/ else if(!KEY2) //如果检测到低电平,说明按键按下{DelayMs(10); //延时去抖,一般10-20msif(!KEY2) //再次确认按键是否按下,没有按下则退出{while(!KEY2);//如果确认按下按键等待按键释放,没有则退出{TxDate[0] = 1;//向右转TxDate[1] = 1;TxDate[2] = 1;TxDate[3] = 0;NRFSetTxMode(TxDate);//发送数据while(CheckACK()); //检测是否发送完毕}}}/********************************************************/ else if(!KEY3) //如果检测到低电平,说明按键按下{DelayMs(10); //延时去抖,一般10-20msif(!KEY3) //再次确认按键是否按下,没有按下则退出{while(!KEY3);//如果确认按下按键等待按键释放,没有则退出{TxDate[0] = 1;//前进TxDate[1] = 0;TxDate[2] = 1;TxDate[3] = 0;NRFSetTxMode(TxDate);//发送数据while(CheckACK()); //检测是否发送完毕}}}/********************************************************/ else if(!KEY4) //如果检测到低电平,说明按键按下{DelayMs(10); //延时去抖,一般10-20msif(!KEY4) //再次确认按键是否按下,没有按下则退出{while(!KEY4);//如果确认按下按键等待按键释放,没有则退出{TxDate[0] = 0;//后退TxDate[1] = 1;TxDate[2] = 0;TxDate[3] = 1;NRFSetTxMode(TxDate);//发送数据while(CheckACK()); //检测是否发送完毕}}}else if(!KEY5){DelayMs(10);if(!KEY5){while(!KEY5){TxDate[0] = 1;TxDate[1] = 1;TxDate[2] = 1;TxDate[3] = 1;NRFSetTxMode(TxDate);while(CheckACK());}}}}}////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////#include#include#include'1602.h'#include'delay.h'#include 'nrf24l01.h'#define uint unsigned int#define uchar unsigned charuint Weight;sbit a = P2^0;sbit b = P2^1;sbit c = P2^2;sbit d = P2^3;void main(){LCD_Init(); //初始化液晶屏LCD_Clear(); //清屏*(RevTempDate+4)=*\0*;NRF24L01Int();while(1){NRFSetRXMode();//设置为接收模式GetDate();//开始接受数;//Weight=RevTempDate[0]*1000+RevTempDate[1]*100+RevTempDate[2]* 10+RevTempDate[3];LCD_Write_Char(7,0,RevTempDate[0]+0x30);LCD_Write_Char(8,0,RevTempDate[1]+0x30);LCD_Write_Char(9,0,RevTempDate[2]+0x30);LCD_Write_Char(10,0,RevTempDate[3]+0x30);a = RevTempDate[0];//根据接受数据来设置高低电平(目测仅限传输1.0两种数值)b = RevTempDate[1];c = RevTempDate[2];d = RevTempDate[3];}}////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////#include#include 'nrf24l01.h'#define uchar unsigned char#define uint unsigned intsbit IRQ =P1^2;//输入sbit MISO =P1^3; //输入sbit MOSI =P1^1;//输出sbit SCLK =P1^4;//输出sbit CE =P1^5;//输出sbit CSN =P1^0;//输出uchar code TxAddr[]={0x34,0x43,0x10,0x10,0x01};//发送地址/*****************状态标志*****************************************/uchar bdata sta; //状态标志sbit RX_DR=sta^6;sbit TX_DS=sta^5;sbit MAX_RT=sta^4;/*****************SPI时序函数******************************************/uchar NRFSPI(uchar date){uchar i;for(i=0;i{if(date&0x80)MOSI=1;elseMOSI=0; // byte最高位输出到MOSIdateSCLK=1;if(MISO) // 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO 输出1位数据date|=0x01; // 读MISO到byte最低位SCLK=0; // SCK置低}return(date); // 返回读出的一字节}/**********************NRF24L01初始化函数*******************************/void NRF24L01Int(){DDelay(2);//让系统什么都不干CE=0; //待机模式1CSN=1;SCLK=0;IRQ=1;}/*****************SPI读寄存器一字节函数*********************************/uchar NRFReadReg(uchar RegAddr){uchar BackDate;CSN=0;//启动时序NRFSPI(RegAddr);//写寄存器地址BackDate=NRFSPI(0x00);//写入读寄存器指令CSN=1;return(BackDate); //返回状态}/*****************SPI写寄存器一字节函数*********************************/uchar NRFWriteReg(uchar RegAddr,uchar date){uchar BackDate;CSN=0;//启动时序BackDate=NRFSPI(RegAddr);//写入地址NRFSPI(date);//写入值return(BackDate);}/*****************SPI读取RXFIFO寄存器的值********************************/uchar NRFReadRxDate(uchar RegAddr,uchar *RxDate,uchar DateLen) { //寄存器地址//读取数据存放变量//读取数据长度//用于接收uchar BackDate,i;CSN=0;//启动时序BackDate=NRFSPI(RegAddr);//写入要读取的寄存器地址for(i=0;i{RxDate[i]=NRFSPI(0);}CSN=1;return(BackDate);}/*****************SPI写入TXFIFO寄存器的值**********************************/uchar NRFWriteTxDate(uchar RegAddr,uchar *TxDate,uchar DateLen) { //寄存器地址//写入数据存放变量//读取数据长度//用于发送uchar BackDate,i;CSN=0;BackDate=NRFSPI(RegAddr);//写入要写入寄存器的地址for(i=0;i{NRFSPI(*TxDate++);}CSN=1;return(BackDate);}/*****************NRF设置为发送模式并发送数据******************************/void NRFSetTxMode(uchar *TxDate){//发送模式NRFWriteTxDate(W_REGISTER+TX_ADDR,TxAddr,TX_ADDR_WITD H);//写寄存器指令+接收地址使能指令+接收地址+地址宽度NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WI TDH);//为了应答接收设备,接收通道0地址和发送地址相同NRFWriteTxDate(W_TX_PAYLOAD,TxDate,TX_DATA_WITDH);//写入数据/******下面有关寄存器配置**************/NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0 NRFWriteReg(W_REGISTER+SETUP_RETR,0x0a); // 自动重发延时等待250us+86us,自动重发10次NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40 NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益NRFWriteReg(W_REGISTER+CONFIG,0x0e); // CRC使能,16位CRC 校验,上电CE=1;DDelay(5);//保持10us秒以上}/*****************NRF设置为接收模式并接收数据******************************///主要接收模式void NRFSetRXMode(){CE=0;NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WI TDH); // 接收设备接收通道0使用和发送设备相同的发送地址NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0 NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40 NRFWriteReg(W_REGISTER+RX_PW_P0,TX_DATA_WITDH); // 接收通道0选择和发送通道相同有效数据宽度NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益*/NRFWriteReg(W_REGISTER+CONFIG,0x0f); // CRC使能,16位CRC 校验,上电,接收模式CE = 1;DDelay(5);//保持10us秒以上}/****************************检测应答信号******************************/uchar CheckACK(){ //用于发射sta=NRFReadReg(R_REGISTER+STATUS); // 返回状态寄存器if(TX_DS||MAX_RT) //发送完毕中断{NRFWriteReg(W_REGISTER+STATUS,0xff); // 清除TX_DS或MAX_RT中断标志CSN=0;NRFSPI(FLUSH_TX);//用于清空FIFO !!关键!!不然会出现意想不到的后果!!!大家记住!!CSN=1;return(0);}elsereturn(1);}/******************判断是否接收收到数据,接到就从RX取出*********************///用于接收模式uchar NRFRevDate(uchar *RevDate){uchar RevFlags=0;sta=NRFReadReg(R_REGISTER+STATUS);//发送数据后读取状态寄存器if(RX_DR) // 判断是否接收到数据{CE=0; //SPI使能NRFReadRxDate(R_RX_PAYLOAD,RevDate,RX_DATA_WITDH);// 从RXFIFO读取数据RevFlags=1; //读取数据完成标志}NRFWriteReg(W_REGISTER+STATUS,0xff); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标return(RevFlags);}void DDelay(uint t){uint x,y;for(x=t;x>0;x--)for(y=110;y>0;y--);}//////////////////////////////////////////////////////////////////////////////////////////////////////// #include 'delay.h'/*------------------------------------------------uS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编,大致延时长度如下T=tx2+5 uS------------------------------------------------*/void DelayUs2x(unsigned char t){while(--t);}/*------------------------------------------------mS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编------------------------------------------------*/void DelayMs(unsigned char t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}///////////////////////////////////////////////////////////////////////////////////////////下面是接收的NRF24L01的程序。

相关文档
最新文档