无线_24l01_发送C语言程序

合集下载

NRF24L01测试发送程序

NRF24L01测试发送程序

NRF24L01测试发送程序/*对该程序做一下几点说明一、该程序仅用于测试是否发送成功,所以有两处的设置做出了调整1、SPI_RW_Reg(WRITE_REG + EN_AA, 0x00);//频道0自动ACK应答允许(此处禁止用于测试)2、SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00);//允许接收地址只有频道0(此处禁止用于测试)二、其中P3口连接的是无线模块的引脚,P2口连接的是LED 是为了显示发送数据后STA TUS的状态若使用的开发板不同,需将P2口连接到其他口观察状态寄存器的状态三、P3口一定不要接其他外部设备,如使用的开发板有其他外接设备一定要断掉。

或侧换成最小系统板进行试验四、若发送仍不成功,可以用示波器观察发送数据时的MISO口的波形判断是否为硬件问题*///***************************************************发送程序*********************************//#include#includetypedef unsigned char uchar;//****************************************NRF24L01 IO端口定义*********************************//sbit CE =P3^2;sbit CSN =P3^3;sbit SCK =P3^4;sbit M OSI =P3^5;sbit M ISO =P3^6;sbit IRQ =P3^7;//***********************************发送缓冲区***********************************************//uchar TxBuf[3]={1,2,3};//发送的数据用数字存储//*****************************NRF24L01的接收和发送地址***************************************//#define TX_ADR_WIDTH 5 // 5个字节的TX地址长度#define RX_ADR_WIDTH 5 // 5个字节的TX地址长度#define TX_PLOAD_WIDTH 3 // 20个字节的TX数据长度#define RX_PLOAD_WIDTH 3 // 20个字节的TX数据长度uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址//***************************************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 STATUS 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 // 接收频道0接收数据长度#define RX_PW_P2 0x13 // 接收频道0接收数据长度#define RX_PW_P3 0x14 // 接收频道0接收数据长度#define RX_PW_P4 0x15 // 接收频道0接收数据长度#define RX_PW_P5 0x16 // 接收频道0接收数据长度#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置//*******************************函数声明**************************************************//void Delay(unsigned int s);void inerDelay_us(unsigned char n);void init_NRF24L01(void);uchar SPI_RW(uchar num);uchar SPI_Read(uchar reg);void SetRX_Mode(void);uchar SPI_RW_Reg(uchar reg, uchar value);uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);void nRF24L01_TxPacket(unsigned char * tx_buf);//*****************************************延时函数***************************************//void inerDelay_us(unsigned char n){for(;n>0;n--)_nop_();}//*****************************************长延时*****************************************//void Delay(unsigned int s){unsigned int i;for(i=0; i<="" p="">for(i=0; i<="" p="">}//****************************************状态标志****************************************//uchar bdata sta;sbit RX_DR =sta^6;sbit TX_DS =sta^5;sbit MAX_RT =sta^4;//********************************NRF24L01初始化******************************************//void init_NRF24L01(void){inerDelay_us(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); //写接收端地址SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 频道0自动ACK 应答允许(此处禁止用于测试)SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); //允许接收地址只有频道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,发射功率为最大值0dBSPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送}/************************************************************** **************** **********************/*函数:uint SPI_RW(uint uchar)/*功能:NRF24L01的SPI写时序/************************************************************** **************** **********************/uchar SPI_RW(uchar num){uchar bit_ctr;for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit{MOSI = (num & 0x80); // output 'uchar', MSB to MOSInum = (num << 1); // shift next bit into MSB..SCK = 1; // Set SCK high..num |= MISO; // capture current MISO bitSCK = 0; // ..then set SCK low again}return(num); // return read uchar}/************************************************************** **************** **********************函数:uchar SPI_Read(uchar reg)功能:NRF24L01的SPI时序*************************************************************** **************** *********************/uchar SPI_Read(uchar reg){uchar reg_val;CSN = 0; // CSN low, initialize SPI communication...SPI_RW(reg); // Select register to read from..reg_val = SPI_RW(0); // ..then read registervalueCSN = 1; // CSN high, terminate SPI communicationreturn(reg_val); // return register value}/************************************************************** **************** **********************//*功能:NRF24L01读写寄存器函数/************************************************************** **************** **********************/uchar SPI_RW_Reg(uchar reg, uchar value){uchar status;CSN = 0; // CSN low, init SPI transactionstatus = SPI_RW(reg); // select registerSPI_RW(value); // ..and write value to it..CSN = 1; // CSN high againreturn(status); // return nRF24L01 status uchar}/************************************************************** **************** ***************************/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数/****************************************************************** ************ ***************************/uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars){uchar status,uchar_ctr;CSN = 0; //SPI使能status = SPI_RW(reg);for(uchar_ctr=0; uchar_ctr<="" bdsfid="224" p="" uchar_ctr++)="">SPI_RW(*pBuf++);CSN = 1; //关闭SPIreturn(status); //}/************************************************************** **************** *****************************/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)/*功能:发送tx_buf中数据/************************************************************** **************** ****************************/void nRF24L01_TxPacket(unsigned char *tx_buf){CE=0; //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); // 装载数据CE=1; //置高CE激发数据发送inerDelay_us(10);}/************************************主函数************************************************************/ void main(void){init_NRF24L01() ;Delay(6000);while(1){nRF24L01_TxPacket(TxBuf); // 发送Tx buffer的数据Delay(15000); //可变P2=SPI_Read(STA TUS);Delay(10000); //可变}}。

NRF24L01数据通信C程序

NRF24L01数据通信C程序
Function: delay100();
Description:
delay 100ms
/**************************************************
void delay(uchar )
{
uchar x;
uchar y;
for(x=0;x<100;x++)
/**************************************************/
void Inituart(void)
{
TMOD = 0x20; //timer1 working mode 1
TL1 = 0xfd; //f7=9600 for 16mhz Fosc,and ...
{
for(y=0;y<100;y++)
_nop_();
}
}
/**************************************************/
void delay_ms(unsigned int x)
{
unsigned int i,j;
i=0;
//管脚定义
sbit CE = P1^0;
sbit CSN= P1^1;
sbit SCK= P1^2;
sbit MOSI= P1^3;
sbit MISO= P1^4;
sbit IRQ = P1^5;
/**************************************************/
return(reg_val); // return register value

基于51的无线芯片NFR24L01通信主机程序

基于51的无线芯片NFR24L01通信主机程序

#include<reg52.h>#include<nfr2401.h>#define uchar unsigned char#define TX_ADR_WIDTH 5 // 5 bytes TX(RX) address width#define TX_PLOAD_WIDTH 2 // 20 bytes TX payloaduchar const TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01}; // Define a static TX addressuchar rx_buf[TX_PLOAD_WIDTH];uchar tx_buf[TX_PLOAD_WIDTH]={0x12};uchar flag;sbit CE =P0^0 ;sbit CSN =P0^1 ;sbit SCK =P0^2 ;sbit MOSI =P0^3 ;sbit MISO =P0^4 ;sbit IRQ =P0^5 ;uchar spi_rw(uchar dat);uchar write_reg(uchar reg,uchar dat);uchar read_reg(uchar reg);uchar write_reg_bytes(uchar reg,uchar *pbuf,uchar x);uchar read_reg_bytes(uchar reg,uchar *pbuf,uchar x);void rx_mode();void tx_mode();void into_nfr();void delay(uchar m);//uchar cheeckRT();uchar cheeckAT();void send(uchar m);uchar spi_rw(uchar dat){uchar byt;for(byt=0;byt<8;byt++){MOSI=dat&0x80;dat=dat<<1;SCK=1;dat|=MISO;SCK=0;}return dat ; //用spi写入一个字节的时序}uchar write_reg(uchar reg,uchar dat){uchar byt;CSN=0;byt=spi_rw(reg);spi_rw(dat);return byt; //向某一个寄存器写入一个字节}uchar read_reg(uchar reg){uchar byt;CSN=0;spi_rw(reg);byt=spi_rw(0);return byt; //读某一个寄存器的内容}uchar write_reg_bytes(uchar reg,uchar *pbuf,uchar x){uchar byt,sta;CSN=0;sta=spi_rw(reg);for(byt=0;byt<x;byt++)spi_rw(*pbuf++);CSN=1;return sta; //向某一个寄存器写入x个字节}uchar read_reg_bytes(uchar reg,uchar *pbuf,uchar x){uchar byt,sta;CSN=0;sta=spi_rw(reg);for(byt=0;byt<x;byt++)pbuf[byt]=spi_rw(0);CSN=1;return sta; //从某一个寄存器读出x个字节}/**************************************************************** ***void rx_mode(){CE=0;write_reg_bytes(WRITE_REG+RX_ADDR_P0,TX_ADDR,TX_ADR_WID TH);write_reg(WRITE_REG+EN_AA,0x01);write_reg(WRITE_REG+EN_RXADDR,0x01);write_reg(WRITE_REG+RF_CH,0x40);write_reg(WRITE_REG+RX_ADDR_P0,TX_ADR_WIDTH);write_reg(WRITE_REG+RF_SETUP,0x07);write_reg(WRITE_REG+CONFIG,0x0f); //设置接收模式的寄存器CE=1;}***************************************************************** ****/void tx_mode(uchar *tx_buf){CE=0;write_reg_bytes(WRITE_REG+TX_ADDR,TX_ADDR,TX_ADR_WIDTH) ;write_reg_bytes(WRITE_REG+RX_ADDR_P0,TX_ADDR,TX_ADR_WID TH);write_reg_bytes(W_TX_PAYLAD,tx_buf,TX_PLOAD_WIDTH);write_reg(WRITE_REG+EN_AA,0x01);write_reg(WRITE_REG+EN_RXADDR,0x01);write_reg(WRITE_REG+RF_CH,0x40);write_reg(WRITE_REG+RX_ADDR_P0,TX_ADR_WIDTH);write_reg(WRITE_REG+SETUP_RETR,0x0a);write_reg(WRITE_REG+RF_SETUP,0x07);write_reg(WRITE_REG+CONFIG,0x0e);CE=1;delay(0x02);}void into_nfr(){CE=0;CSN=1;SCK=0;}uchar cheeckAT(){uchar sta;sta=spi_rw(READ_REG+STATUS);if(sta&0x30){write_reg(WRITE_REG+STATUS,0xff);CSN=0;spi_rw(FLUSH_TX);CSN=1;return (0);}elsereturn (1);}/**************************************************************** *uchar cheeckRT(){uchar sta;sta=spi_rw(READ_REG+STATUS);if(sta&0x20){CE=0 ;read_reg_bytes(R_RX_PAYLAD,rx_buf,TX_PLOAD_WIDTH);return 1;}write_reg(WRITE_REG+STATUS,0xff);return 0;}//**************************************************************** **void send(uchar m){SBUF=m;while(!TI);TI=0;}***************************************************************** ***/void allow() interrupt 4{if(RI){RI=0;tx_buf[0]=SBUF;flag=1;P1=tx_buf[0];}}void delay(uchar m){uchar i;while(m--){for(i=104;i>0;i--);}}void main(){into_nfr();TMOD=0x20;SCON=0x50;TH1=0xfd;// TR1=1;ES=1;// EA=1;// tx_mode();while(1){// if(flag==1)// {flag=0;//CE=0;//write_reg_bytes(W_TX_PAYLAD,tx_buf,TX_PLOAD_WIDTH);//CE=1;tx_mode(tx_buf);while(cheeckAT()); P2=0xf0;// }}}。

基于nrf24l01的无线发电路的设计

基于nrf24l01的无线发电路的设计

基于nrf24l01的无线发电路的设计1.简介本文档旨在介绍基于n rf24l01的无线发电路的设计。

n rf24l01是一种低功耗、高性能的射频通信模块,它被广泛应用于无线通信领域。

本文将介绍无线发电路设计的基本原理、硬件连接、代码编写以及测试验证等内容。

2.设计原理2.1n r f24l01概述n r f24l01是一款2.4G Hz无线射频通信模块,采用G FS K调制解调方式,具备16个通道和自动频率跳变功能。

该模块工作在低功耗模式下,能够实现远距离的无线数据传输,适用于各种物联网应用场景。

2.2无线发电路设计原理无线发电路设计的目标是实现两个或多个无线设备之间的数据传输。

基于nr f24l01的无线发电路设计主要包括以下几个方面:硬件连接 1.:连接n r f24l01模块与控制单元,确保数据的稳定传输。

代码编写2.:编写适合的代码,配置nr f24l01模块的寄存器以及实现数据的发送和接收。

电源管理3.:合理设计电源电路,确保n rf24l01模块的稳定工作。

通信协议 4.:选择合适的通信协议,确保数据传输的可靠性和安全性。

3.硬件连接为了实现无线发电路的设计,需要先完成n rf24l01模块与控制单元的正确连接。

具体连接方法如下:1.将n rf24l01模块的V CC引脚连接至控制单元的3.3V电源引脚。

2.将n rf24l01模块的G ND引脚连接至控制单元的地引脚。

3.将n rf24l01模块的C E引脚连接至控制单元的某一可用G PI O引脚。

4.将n rf24l01模块的C SN引脚连接至控制单元的某一可用G PI O引脚。

5.将n rf24l01模块的S CK引脚连接至控制单元的S PI时钟引脚。

6.将n rf24l01模块的M OS I引脚连接至控制单元的S PI数据输出引脚。

7.将n rf24l01模块的M IS O引脚连接至控制单元的S PI数据输入引脚。

4.代码编写无线发电路的设计需要编写适合的代码,以实现n rf24l01模块的数据传输功能。

NRF24L01无线发射简易教程

NRF24L01无线发射简易教程

NRF24L01 简易教程先来看接口电路,使用的IO 口不是唯一的哦,可随意定义接口,当然是在使用IO 口模拟SPI 且IRQ 中断引脚不使用的使用查询方法判断接收状态的情况下了。

作为初探我们就是用简单的IO 模拟SPI 的方法了,中断使用查询的方式。

那么该教程讲解的接口与单片机的连接如下:首先您需要了解NRF24L01,请参阅“NRF24L01 芯片中文资料”或者“NRF24L01 芯片英文资料”。

我们的教程是以一个简单的小项目为大家展示NRF24L01 的使用方法与乐趣。

我们所写的教程均是以这种方式的呢,让您在学习的时候明白它能做什么,使您学起来不至于枯燥无味。

作为简易的教程,我们只需要知道它是怎么使用的就够了,我们本教程的目的是用NRF24L01 发送数据和接收数据,且接收方会对比发送的数据与接收的数据,若完全相同则控制LED 闪烁一次,并且把接收到的数据通过串口发送到PC 端,通过串口工具查看接收到的数据。

具体的要求如下:1、具备发送和接收的能力。

2、发送32 个字节的数据,接收方接收到正确数据之后给予提示,通过LED 闪烁灯形式。

3、把接收到的数据传送到PC 进行查看。

4、发送端每隔大约1.5 秒发送一次数据,永久循环。

以上是程序的要求,若您想自行设计出硬件接口,您也是可以添加一条呢:使用DIY 方式设计NRF24L01 的接口板,且包含含单片机平台,使用PCB 方式或者万用板方式均可。

如果您想让自己学的很扎实,那么推荐您自行做出接口板子呢。

当然若您的能力不足,那么我们不推荐自行做板呢,因为这样会增加您学习的难度,反而起到了反效果呢。

我们使用的方式是画PCB 的方式呢,若您自己做了接口板子,那么您可以对比下一呢,O(∩_∩)O!我们知道NRF24L01 的供电电压是1.9V~3.6V 不能超过这个范围,低了不工作,高了可能烧毁NRF24L01 芯片。

我们常用的STC89C52 的单片机的供电电压是5V,我们不能直接给24L01 这个模块供电,我们需要使用AMS1117-3.3V 稳压芯片把5V 转成3.3V 的电压为24L01 模块供电。

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收发程序

/******* ******** ******** ******** ******** ******** ******** ******** ******** ******* ******** ******** ******/ 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 时 序

NRF24L01动态字节长度接受和发送

NRF24L01动态字节长度接受和发送

在STM32战舰开发板上测试,接受采用IRQ引脚产生外部中断。

发送数据字节长度可以动态改变,接收端也可以读取到发送方实际发送字节长度。

战舰开发板为接收端。

然后将接受数据通过USART1发送至电脑,使用DMA传输方式,波。

STM32F103ZET6与NRF24L01 SPI 通信速率为9MHz。

24L01.c文件代码#include "24l01.h"#include "lcd.h"#include "delay.h"#include "spi.h"const uint8_t TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //发送地址const uint8_t RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //发送地址//初始化24L01的IO口void NRF24L01_Init(void){GPIO_InitTypeDefGPIO_InitStructure;SPI_InitTypeDefSPI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;EXTI_InitTypeDef EXTI_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOD|RCC_APB2Pe riph_GPIOG |RCC_APB2Periph_AFIO, ENABLE); //使能PB,D,G端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //PB12上拉防止W25X的干扰GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化指定IOGPIO_SetBits(GPIOB,GPIO_Pin_12);//上拉GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PD2推挽输出上拉禁止SD卡的干扰GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_SetBits(GPIOD,GPIO_Pin_2);//初始化指定IOGPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //PG6 7 推挽GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化指定IORCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOG, &GPIO_InitStructure);GPIO_EXTILineConfig(GPIO_PortSourceGPIOG,GPIO_PinSource8);EXTI_InitStructure.EXTI_Line = EXTI_Line8;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);NRF24L01_CE=0; //使能24L01NRF24L01_CSN=1; //SPI片选取消SPI2_Init(); //初始化SPISPI_Cmd(SPI2, DISABLE); // SPI外设不使能SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //SPI设置为双线双向全双工SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //SPI主机SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //发送接收8位帧结构SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //时钟悬空低SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //数据捕获于第1个时钟沿SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件控制SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; //定义波特率预分频的值:波特率预分频值为16SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从MSB位开始SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式SPI_Init(SPI2, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器SPI_Cmd(SPI2, ENABLE); //使能SPI外设SPI2_SetSpeed(SPI_BaudRatePrescaler_4);//9MHz}//检测24L01是否存在//返回值:0,成功;1,失败u8 NRF24L01_Check(void){u8buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};u8i;NRF24L01_Write_Buf(WRITE_REG_NRF+TX_ADDR,buf,5);//写入5个字节的地址.NRF24L01_Read_Buf(TX_ADDR,buf,5); //读出写入的地址for(i=0;i<5;i++)if(buf[i]!=0XA5)break;if(i!=5)return 1;//检测24L01错误return 0; //检测到24L01}//SPI写寄存器//reg:指定寄存器地址//value:写入的值u8 NRF24L01_Write_Reg(u8 reg,u8 value){u8 status;NRF24L01_CSN=0; //使能SPI传输status =SPI2_ReadWriteByte(reg);//发送寄存器号SPI2_ReadWriteByte(value); //写入寄存器的值NRF24L01_CSN=1; //禁止SPI传输return(status); //返回状态值}//读取SPI寄存器值//reg:要读的寄存器u8 NRF24L01_Read_Reg(u8 reg){u8 reg_val;NRF24L01_CSN = 0; //使能SPI传输SPI2_ReadWriteByte(reg); //发送寄存器号reg_val=SPI2_ReadWriteByte(0XFF);//读取寄存器内容NRF24L01_CSN = 1; //禁止SPI传输return(reg_val); //返回状态值}//在指定位置读出指定长度的数据//reg:寄存器(位置)//*pBuf:数据指针//len:数据长度//返回值,此次读到的状态寄存器值u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len){u8 status,u8_ctr;NRF24L01_CSN = 0; //使能SPI传输status=SPI2_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值for(u8_ctr=0;u8_ctr<len;u8_ctr++)pBuf[u8_ctr]=SPI2_ReadWriteByte(0XFF);//读出数据NRF24L01_CSN=1; //关闭SPI传输return status; //返回读到的状态值}//在指定位置写指定长度的数据//reg:寄存器(位置)//*pBuf:数据指针//len:数据长度//返回值,此次读到的状态寄存器值u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len){u8 status,u8_ctr;NRF24L01_CSN = 0; //使能SPI传输status = SPI2_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值for(u8_ctr=0; u8_ctr<len; u8_ctr++)SPI2_ReadWriteByte(*pBuf++); //写入数据NRF24L01_CSN = 1; //关闭SPI传输return status; //返回读到的状态值}//启动NRF24L01发送一次数据//txbuf:待发送数据首地址//返回值:发送完成状况u8 NRF24L01_TxPacket(u8 *txbuf,u8 length){u8sta;NRF24L01_CE=0;if(length>=32)return 0;else{NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,length);//写数据到TX BUF32个字节}NRF24L01_CE=1;//启动发送while(NRF24L01_IRQ!=0);//等待发送完成sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值NRF24L01_Write_Reg(WRITE_REG_NRF+STATUS,sta); //清除TX_DS或MAX_RT中断标志if(sta&MAX_TX)//达到最大重发次数{NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器return MAX_TX;}if(sta&TX_OK)//发送完成{return TX_OK;}return 0xff;//其他原因发送失败}//启动NRF24L01发送一次数据//txbuf:待发送数据首地址//返回值:0,接收完成;其他,错误代码u8 NRF24L01_RxPacket(u8 *rxbuf){u8sta;sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值NRF24L01_Write_Reg(WRITE_REG_NRF+STATUS,sta); //清除TX_DS或MAX_RT中断标志if(sta&RX_OK)//接收到数据{NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器return 0;}return 1;//没收到任何数据}//该函数初始化NRF24L01到RX模式//设置RX地址,写RX数据宽度,选择RF频道,波特率和LNA HCURR//当CE变高后,即进入RX模式,并可以接收数据了void NRF24L01_RX_Mode(void){NRF24L01_CE=0;NRF24L01_Write_Buf(WRITE_REG_NRF+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);/ /写RX节点地址NRF24L01_Write_Reg(WRITE_REG_NRF+EN_AA,EN_P0); //使能通道0的自动应答NRF24L01_Write_Reg(WRITE_REG_NRF+EN_RXADDR,EN_P0);//使能通道0的接收地址NRF24L01_Write_Reg(WRITE_REG_NRF+RF_CH,40); //设置RF通信频率NRF24L01_Write_Reg(WRITE_REG_NRF+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度NRF24L01_Write_Reg(WRITE_REG_NRF+RF_SETUP,0x0f);//设置TX发射参数,0db增益,2Mbps,低噪声增益开启NRF24L01_Write_Reg(WRITE_REG_NRF+CONFIG, 0x0f);//配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式#if EN_DYNAMIC_DATA_LENGTH //使能动态数据长度NRF24L01_Write_Reg(WRITE_REG_NRF+FEATURE,EN_DPL);NRF24L01_Write_Reg(WRITE_REG_NRF+DYNPD,EN_P0);#endifNRF24L01_CE = 1; //CE为高,130us进入接收模式delay_us(500);}//该函数初始化NRF24L01到TX模式//设置TX地址,写TX数据宽度,设置RX自动应答的地址,填充TX发送数据,选择RF频道,波特率和LNA HCURR//PWR_UP,CRC使能//当CE变高后,即进入RX模式,并可以接收数据了//CE为高大于10us,则启动发送.void NRF24L01_TX_Mode(void){NRF24L01_CE=0;NRF24L01_Write_Buf(WRITE_REG_NRF+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址NRF24L01_Write_Buf(WRITE_REG_NRF+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACKNRF24L01_Write_Reg(WRITE_REG_NRF+EN_AA,EN_P0); //使能通道0的自动应答NRF24L01_Write_Reg(WRITE_REG_NRF+EN_RXADDR,EN_P0); //使能通道0的接收地址NRF24L01_Write_Reg(WRITE_REG_NRF+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次#if EN_DYNAMIC_DATA_LENGTH //动态数据长度发送NRF24L01_Write_Reg(WRITE_REG_NRF+FEATURE,EN_DPL);NRF24L01_Write_Reg(WRITE_REG_NRF+DYNPD,EN_P0);#endifNRF24L01_Write_Reg(WRITE_REG_NRF+RF_CH,40); //设置RF通道为40NRF24L01_Write_Reg(WRITE_REG_NRF+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启NRF24L01_Write_Reg(WRITE_REG_NRF+CONFIG,0x0e); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,发射模式,开启所有中断NRF24L01_CE=1;//CE为高,10us后启动发送delay_us(20);}24L01.h文件#ifndef __24L01_H#define __24L01_H#include "sys.h"#include <stdint.h>/* Enable dynamic length, not need send or receive packet data of a fixed length */#define EN_DYNAMIC_DATA_LENGTH 1 //使能动态数据长度/*NRF24L01 type */#define _NRF24L01//#define _NRF24L01P//#define _NRF24L01N#if defined(_NRF24L01) && defined(_NRF24L01P)#error "You can only select one of NRF24L01x,not two or more!!!!!!"#endif#if defined(_NRF24L01) && defined(_NRF24L01N)#error "You can only select one of NRF24L01x,not two or more!!!!!!"#endif#if defined(_NRF24L01P) && defined(_NRF24L01N)#error "You can only select one of NRF24L01x,not two or more!!!!!!"#endif#define RESERVED 0x00#define EN_P5 0x20#define EN_P4 0x10#define EN_P3 0x08#define EN_P2 0x04#define EN_P1 0x02#define EN_P0 0x01//NRF24L01寄存器操作命令#define READ_REG_NRF 0x00 //读配置寄存器,低5位为寄存器地址#define WRITE_REG_NRF 0x20 //写配置寄存器,低5位为寄存器地址#define RD_RX_PLOAD 0x61 //读RX有效数据,1~32字节#define WR_TX_PLOAD 0xA0 //写TX有效数据,1~32字节#define FLUSH_TX 0xE1 //清除TX FIFO寄存器.发射模式下用#define FLUSH_RX 0xE2 //清除RX FIFO寄存器.接收模式下用#define REUSE_TX_PL 0xE3 //重新使用上一包数据,CE为高,数据包被不断发送.#define R_RX_PL_WID 0x60 //读取动态数据长度接受时读取接受到有效数据的数目#define NOP 0xFF //空操作,可以用来读状态寄存器//SPI(NRF24L01)寄存器地址#define CONFIG 0x00 //配置寄存器地址;bit0:1接收模式,0发射模式;bit1:电选择;bit2:CRC模式;bit3:CRC使能;//bit4:中断MAX_RT(达到最大重发次数中断)使能;bit5:中断TX_DS使能;bit6:中断RX_DR使能#define EN_AA 0x01 //使能自动应答功能bit0~5,对应通道0~5#define EN_RXADDR 0x02 //接收地址允许,bit0~5,对应通道0~5#define SETUP_AW 0x03 //设置地址宽度(所有数据通道):bit1,0:00,3字节;01,4字节;02,5字节;#define SETUP_RETR 0x04 //建立自动重发;bit3:0,自动重发计数器;bit7:4,自动重发延时250*x+86us#define RF_CH 0x05 //RF通道,bit6:0,工作通道频率;#define RF_SETUP 0x06 //RF寄存器;bit3:传输速率(0:1Mbps,1:2Mbps);bit2:1,发射功率;bit0:低噪声放大器增益#if defined(_NRF24L01P)#define CONT_WAVE (1<<7)#define RF_DR_RATE_1Mbps 0#define RF_DR_RATE_2Mbps (1<<0)#define RF_DR_RATE_250kbps (1<<1)#define RF_DR_RATE_Reserved ((1<<0) | (1<<1))#endif#define STATUS 0x07 //状态寄存器;bit0:TX FIFO满标志;bit3:1,接收数据通道号(最大:6);bit4,达到最多次重发//bit5:数据发送完成中断;bit6:接收数据中断;#define MAX_TX 0x10 //达到最大发送次数中断#define TX_OK 0x20 //TX发送完成中断#define RX_OK 0x40 //接收到数据中断#define OBSERVE_TX 0x08 //发送检测寄存器,bit7:4,数据包丢失计数器;bit3:0,重发计数器#define CD 0x09 //载波检测寄存器,bit0,载波检测;#define RX_ADDR_P0 0x0A //数据通道0接收地址,最大长度5个字节,低字节在前#define RX_ADDR_P1 0x0B //数据通道1接收地址,最大长度5个字节,低字节在前#define RX_ADDR_P2 0x0C //数据通道2接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;#define RX_ADDR_P3 0x0D //数据通道3接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;#define RX_ADDR_P4 0x0E //数据通道4接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;#define RX_ADDR_P5 0x0F //数据通道5接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;#define TX_ADDR 0x10 //发送地址(低字节在前),ShockBurstTM模式下,RX_ADDR_P0与此地址相等#define RX_PW_P0 0x11 //接收数据通道0有效数据宽度(1~32字节),设置为0则非法#define RX_PW_P1 0x12 //接收数据通道1有效数据宽度(1~32字节),设置为0则非法#define RX_PW_P2 0x13 //接收数据通道2有效数据宽度(1~32字节),设置为0则非法#define RX_PW_P3 0x14 //接收数据通道3有效数据宽度(1~32字节),设置为0则非法#define RX_PW_P4 0x15 //接收数据通道4有效数据宽度(1~32字节),设置为0则非法#define RX_PW_P5 0x16 //接收数据通道5有效数据宽度(1~32字节),设置为0则非法#define NRF_FIFO_STATUS 0x17 //FIFO状态寄存器;bit0,RX FIFO寄存器空标志;bit1,RX FIFO满标志;bit2,3,保留//bit4,TX FIFO空标志;bit5,TX FIFO满标志;bit6,1,循环发送上一数据包.0,不循环;#define DYNPD 0x1C //使能动态载荷长度寄存器#define FEATURE 0x1D //特性寄存器#define EN_DPL 0x04#define EN_ACK_PAY 0x02#define EN_DYN_ACK 0x01////////////////////////////////////////////////////////////////////////////////////////////////////// //////24L01操作线#define NRF24L01_CE PGout(6) //24L01片选信号#define NRF24L01_CSN PGout(7) //SPI片选信号#define NRF24L01_IRQ PGin(8) //IRQ主机数据输入//24L01发送接收数据宽度定义#define TX_ADR_WIDTH 5 //5字节的地址宽度#define RX_ADR_WIDTH 5 //5字节的地址宽度#define TX_PLOAD_WIDTH 16 //32字节的用户数据宽度#define RX_PLOAD_WIDTH 16 //32字节的用户数据宽度typedef struct{u8 Recv_Buf1[RX_PLOAD_WIDTH];//接受缓冲区1u8 Recv_Buf2[RX_PLOAD_WIDTH];//接受缓冲区2u8 Recv_ValidData_Length;//接受到合法数据长度u8 *pRecv_Buf_Point;//指向接受缓冲区的首地址u8 Recv_Data_Flag;//接受到数据标志位}NRF24L01_RECV_DATA_TYPE;extern NRF24L01_RECV_DATA_TYPE nrf24l01_Recv_Data_Param;void NRF24L01_Init(void);//初始化void NRF24L01_RX_Mode(void);//配置为接收模式void NRF24L01_TX_Mode(void);//配置为发送模式u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 u8s);//写数据区u8 NRF24L01_Read_Buf(u8 reg, u8 *pBuf, u8 u8s);//读数据区u8 NRF24L01_Read_Reg(u8 reg); //读寄存器u8 NRF24L01_Write_Reg(u8 reg, u8 value);//写寄存器u8 NRF24L01_Check(void);//检查24L01是否存在u8 NRF24L01_RxPacket(u8 *rxbuf);//接收一个包的数据u8 NRF24L01_TxPacket(u8 *txbuf,u8 length);#endifMain.c文件#include "led.h"#include "delay.h"#include "sys.h"#include "24l01.h"#include "usart.h"#include <string.h>NRF24L01_RECV_DATA_TYPE nrf24l01_Recv_Data_Param;u8 U8_USART3_TX_BUF[100];void NRF24L01_IRQHandler(void);voidError_Handler(void);int main(void){delay_init();NVIC_Configuration();LED_Init();USART_Config();delay_ms(1500); //战舰版USB-232接口通电,程序会短暂复位,避免影响后面接收delay_ms(1500);NRF24L01_Init();/* Check the existance of NRF24L01 or the SPI communication between MCU and NRF24L01 is working normally or not */while(NRF24L01_Check()){Error_Handler();}/* Set the pRecv_Buf_Point point to the buf1 */nrf24l01_Recv_Data_Param.pRecv_Buf_Point = nrf24l01_Recv_Data_Param.Recv_Buf1;/* Set PRX mode */NRF24L01_RX_Mode();/* Clear NRF24L01 IRQ bits of the register */NRF24L01_Write_Reg(WRITE_REG_NRF+STATUS,0x7f);while(1){if(nrf24l01_Recv_Data_Param.Recv_Data_Flag == 1){nrf24l01_Recv_Data_Param.Recv_Data_Flag = 0;/* Indicating LED */LED0 = 0;/* Read out the received data and data length from the FIFO of the NRF24L01 */NRF24L01_Write_Reg(WRITE_REG_NRF+STATUS,0x7f); //清除TX_DS或MAX_RT 中断标志NRF24L01_Read_Buf(R_RX_PL_WID,&nrf24l01_Recv_Data_Param.Recv_ValidData_Length,1 );//读取有效数据长度NRF24L01_Read_Buf(RD_RX_PLOAD,nrf24l01_Recv_Data_Param.pRecv_Buf_Point,nrf24l01_Recv_Data_Param.Recv_ValidData_Length);//读取数据NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器/* Copy data read to the memory using DMA channel */memcpy((void *)U8_USART3_TX_BUF,(const void *)nrf24l01_Recv_Data_Param.pRecv_Buf_Point,nrf24l01_Recv_Data_Param.Recv_ValidData_Length);/* Start sending data packet by USART DMA */USART1_DMA_Send_Hex_Data(nrf24l01_Recv_Data_Param.Recv_ValidData_Length);}else{LED0 = 1;}}}void EXTI9_5_IRQHandler(void){if(EXTI_GetITStatus(EXTI_Line8) != RESET){NRF24L01_IRQHandler();EXTI_ClearITPendingBit(EXTI_Line8);}}void NRF24L01_IRQHandler(void){nrf24l01_Recv_Data_Param.Recv_Data_Flag = 1; }voidError_Handler(void){LED1 = 0;delay_ms(200);LED1 = 1;delay_ms(200);}。

无线收发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基于C51单片机双向通讯C语言程序(中文详解)

无线模块NRF24L01基于C51单片机双向通讯C语言程序(中文详解)

#include <reg52.h>#include <intrins.h>/********************************************************** *****************************//* 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;/************************************NRF24L01端口定义***********************************/sbit NC =P2^0; //没用,不接也可sbit MISO =P2^5; //数字输出(从 SPI 数据输出脚)sbit MOSI =P2^4; //数字输入(从 SPI 数据输入脚)sbit SCK =P1^7; //数字输入(SPI 时钟)sbit CE =P2^1; //数字输入(RX 或 TX 模式选择)sbit CSN =P2^2; //数字输入(SPI片选信号)sbit IRQ =P2^6; //数字输入(可屏蔽中断)/************************************按键***********************************************/sbit KEY1=P3^3;//按键S1sbit KEY2=P3^2;//按键S2/************************************数码管位选******************************************/sbit led1=P1^0; //LED0sbit led2=P1^1; //LED1sbit led3 =P1^2; //LED2sbit led4 =P1^3; //LED3sbit led5 =P1^4; //LED4/*********************************************NRF24L01***********************************/#define TX_ADR_WIDTH 5 // 5 uints TX address 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 payloaduint const TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //本地地址uint const RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //接收地址/***************************************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 STATUS 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 // 接收频道0接收数据长度#define RX_PW_P2 0x13 // 接收频道0接收数据长度#define RX_PW_P3 0x14 // 接收频道0接收数据长度#define RX_PW_P4 0x15 // 接收频道0接收数据长度#define RX_PW_P5 0x16 // 接收频道0接收数据长度#define FIFO_STATUS 0x17 // 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 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 char 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; i<s; i++);for(i=0; i<s; i++);}/********************************************************** ********************************/uint bdata sta; //状态标志sbit RX_DR =sta^6; //RX_DR 为 sta 地第六位sbit TX_DS =sta^5; //TX_DS 为 sta 地第五位sbit MAX_RT =sta^4; //MAX_RT 为 sta 地第四位/********************************************************** ********************************//*延时函数/********************************************************** ********************************/void inerDelay_us(unsigned char n) //延时,us 级{for(;n>0;n--)_nop_();}/********************************************************** ******************************//*NRF24L01初始化/********************************************************** *****************************/void init_NRF24L01(void){inerDelay_us(100);CE=0; // 芯片使能CSN=1; // 禁止 SPISCK=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); // 允许接收地址只有频道0,如果需要多频道可以参考Page21SPI_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,同时从nRF24L01 读出一字节/********************************************************** ******************************************/uint SPI_RW(uint dat){uint i;for(i=0;i<8;i++) // 循环8次{MOSI = (dat & 0x80); // dat地最高位输出到MOSI MSB to MOSIdat = (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 bitSCK = 0; // SCK置低..then set SCK low again}return(dat); //返回读出地一字节 return read dat}/********************************************************** ******************************************/*函数:uchar SPI_Read(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 to read from..reg_val = SPI_RW(0); //然后从该寄存器读数据 ..then read registervalueCSN = 1; //CSN拉高,结束数据传输CSN high, terminate SPI communicationreturn(reg_val); //返回寄存器数据 return register value}/********************************************************** ******************************************//*功能:NRF24L01读写寄存器函数/*描述:写数据value到reg寄存器/********************************************************** ******************************************/uint SPI_RW_Reg(uchar reg, uchar value){uchar status;CSN = 0; // CSN置低,开始传输数据CSN low, init SPI transactionstatus = SPI_RW(reg); // 选择寄存器,同时返回状态字select registerSPI_RW(value); // 然后写数据到该寄存器 ..and write value to it..CSN = 1; // CSN拉高,结束数据传输CSN high againreturn(status); // 返回状态寄存器 return nRF24L01 status uchar}/********************************************************** ******************************************//*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, 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 tranactionstatus = SPI_RW(reg); //选择寄存器,同时返回状态字Select register to write to and read status uchar for(i=0;i<uchars;i++)pBuf[i] = 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缓存中地数据写入到nRF24L01,通常用来写入发射通道数据或接收/发送地址/********************************************************** ***********************************************/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; i<uchars; i++)SPI_RW(*pBuf++); //逐个字节写入nRF24L01CSN = 1; //CSN拉高,结束数据传输return(status); //返回状态寄存器}/********************************************************** ******************************************//*函数:void SetRX_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 char* rx_buf){unsigned char revale=0;sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况if(RX_DR) // 判断是否接收到数据{CE = 0; //SPI使能SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO bufferrevale =1; //读取数据完成标志}SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志return revale;}/********************************************************** *************************************************/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)/*功能:发送 tx_buf中数据/********************************************************** ************************************************/void nRF24L01_TxPacket(unsigned char * tx_buf){CE=0; //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_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ 收发完成中断响应,16位CRC,主发送CE=1; //置高CE,激发数据发送}/************************************主函数*********************************************************** */void main(void){unsigned char tf =0;unsigned char TxBuf[20]={0}; // 要发送地数组unsigned char RxBuf[20]={0}; // 接收地数据数组init_NRF24L01() ; //模块初始化led1=1;led2=1;led3 =1;led4 =1; //led 灯关闭Delay(1000);while(1){if(KEY1 ==0 ) //按键 1 按下{TxBuf[1] = 1 ; //赋值tf = 1 ;led1=0; //本地led 灯闪烁led1=1;Delay(200);}if(KEY2 ==0 ) //按键 2 按下{TxBuf[2] =1 ; //赋值tf = 1 ;led2=0; //本地led 灯闪烁Delay(200);led2=1;Delay(200);}if (tf==1) //有键按下{nRF24L01_TxPacket(TxBuf); //发送数据 Transmit Tx buffer dataTxBuf[1] = 0x00; //清零TxBuf[2] = 0x00;tf=0;Delay(1000);}SetRX_Mode(); //设置成接受模式RxBuf[1] = 0x00; //接收地数组相应位清零RxBuf[2] = 0x00;Delay(1000);nRF24L01_RxPacket(RxBuf); //接收数据if(RxBuf[1]|RxBuf[2]){if( RxBuf[1]==1){led3=RxBuf[0];}if( RxBuf[2]==1){led4=RxBuf[4];}Delay(3000); //old is '1000'}RxBuf[1] = 0x00; //清零RxBuf[2] = 0x00;led3=1; //关灯led4=1;}}本程序存在地问题:反应不够灵敏,当在按键1和按键2之间切换地时候,对方地灯闪烁会有一定地延时,另外本程序没有消除按键地抖动.对部分函数地解释:uint SPI_RW(uint dat)最基本地函数,完成 GPIO模拟 SPI 地功能.将输出字节(MOSI)从 MSB 循环输出,同时将输入字节(MISO)从 LSB 循环移入.上升沿读入,下降沿输出. (从 SCK被初始化为低电平可以判断出)uchar SPI_Read(uchar reg); //从reg寄存器读一字节读取寄存器值地函数:基本思路就是通过 READ_REG命令(也就是 0x00+寄存器地址) ,把寄存器中地值读出来.对于函数来说也就是把 reg 寄存器地值读到reg_val 中去.uint SPI_RW_Reg(uchar reg, uchar value); //写数据value到reg寄存器寄存器访问函数:用来设置 24L01 地寄存器地值.基本思路就是通过 WRITE_REG命令(也就是 0x20+寄存器地址)把要设定地值写到相应地寄存器地址里面去,并读取返回值.对于函数来说也就是把 value值写到 reg 寄存器中.需要注意地是,访问 NRF24L01 之前首先要 enable 芯片(CSN=0;) ,访问完了以后再 disable芯片(CSN=1;).uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars); //从reg寄存器读出bytes个字节,通常用来//读取接收通道数据或接收/发送地址接收缓冲区访问函数:主要用来在接收时读取 FIFO 缓冲区中地值.基本思路就是通过READ_REG命令把数据从接收 FIFO(RD_RX_PLOAD)中读出并存到数组里面去.uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars); //把pBuf缓存中地数据写入到nRF24L01,通常//用来写入发发射缓冲区访问函数:主要用来把数组里地数放到发射 FIFO缓冲区中.基本思路就是通过WRITE_REG命令把数据存到发射 FIFO(WR_TX_PLOAD)中去.Tx 模式初始化过程1)写 Tx 节点地地址 TX_ADDR2)写 Rx 节点地地址(主要是为了使能 Auto Ack) RX_ADDR_P0 3)使能 AUTO ACK EN_AA4)使能 PIPE 0 EN_RXADDR5)配置自动重发次数 SETUP_RETR6)选择通信频率 RF_CH7)配置发射参数(低噪放大器增益.发射功率.无线速率) RF_SETUP 8 ) 选择通道0 有效数据宽度 Rx_Pw_P09)配置 24L01 地基本参数以及切换工作模式 CONFIG.Rx 模式初始化过程:初始化步骤 24L01 相关寄存器1)写 Rx 节点地地址 RX_ADDR_P02)使能 AUTO ACK EN_AA3)使能 PIPE 0 EN_RXADDR4)选择通信频率 RF_CH5) 选择通道0 有效数据宽度 Rx_Pw_P06)配置发射参数(低噪放大器增益.发射功率.无线速率) RF_SETUP 7)配置 24L01 地基本参数以及切换工作模式 CONFIG.。

2.4G单片机24L01 C程序实例

2.4G单片机24L01 C程序实例
第1页
24L01test.c
void init_OSC() {
OSCCON = (OSCCON & 0xCF) + 0x30; }
void init_RA() {
PORTA = (PORTA & 0x00) + 0x00; TRISA = (TRISA & 0x00) + 0xBF; RA6: output RA7:input ANSELA = (ANSELA & 0xC0) + 0x00; digital I/O }
24L01test.c
void delay(unsigned int t) {
unsigned int a, b; for(a = 0; a < 10; a ++) for(b = 0; b < t; b ++); }
unsigned char SPI_RW(unsigned char REG) {
void TX_mode(void) {
CE = 0; NOP();
SPI_WRITE(FLUSH_TX, 0); FIFO for the mode change
SPI_WRITE(FLUSH_RX, 0); SPI_WRITE(W_REGISTER + STATUS, 0x70);
//clear //clear the INT flag
RX_BUF[0] = 0x25; RX_BUF[1] = 0x25; RX_BUF[2] = 0x25; RX_BUF[3] = 0x25; RX_BUF[4] = 0x25;
TR_WIDTH = 5; TX_WIDTH = 5;
24L01test.c 第3页

无线通信24L01操作总结

无线通信24L01操作总结

24L01操作总结初始化一个芯片,如果用一个IO口来模拟协议,那么片选CS = 1;CE = 1; SCK = 0;(时钟线闲时是低电平还是高电平,这个也有讲究,特别是SPI)。

初始化时,先不使能芯片,所以片选拉高,并且使能端也拉高。

初始化函数截图:SPI_Write_Buf函数说明:先传递写操作指令+发送寄存器的地址+用户指定的发送地址+数据个数。

先传递写操作指令+接收寄存器的地址+用户指定的接收地址+数据个数。

SPI_RW_Reg函数说明:主要设置频道,例如接收频道,芯片工作频率,接收的数据宽度,发送速率的频率,以及发射功率等。

24L01常见的指令主函数:SetTX_Mode函数:主要是清除相应的中断位,然后选择校验CRC模式,有8位模式,还有16位模式,并且设置为发送,并设置芯片上电。

nRF24L01_TxPacket函数:主要是设置接收端通道0接收地址,接收地址是TX_ADDRESS。

第二步就开始写入发送命令,并且传递发送数据tx_buff数组的首地址。

发送的数据宽度是20个字节.第三步操作设置寄存器,为什么是0x0e呢,这个需要参照设置寄存器的内容来讨论,设置寄存器的内容如下:从最低位为0可以知道,选择为发射模式。

最后发送了数据,从主函数可以得知,又调用了这个函数。

SPI_RW_Reg(WRITE_REG+STATUS,0XFF);接收模式的主函数如下:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)函数说明重点是写了一个接收的指令,这个必须有。

巧妙就是接收到数据就返回1,否则返回0;并且sta这个变量读出状态寄存器的内容,然后在接收完数据后,又清理状态寄出器对应的位,这个效果是,读数据保存数据和清除状态寄出器的相应位都互不影响。

从接收的主函数可以知道,程序比较简单。

NRF24L01 MSP430发送接收程序(word文档良心出品)

NRF24L01 MSP430发送接收程序(word文档良心出品)

NRF24L01 MSP430发送接收程序作者:codebaby 文章来源:codebaby 点击数: 1351 更新时间:2011-8-18最近弄了几天的无线模块,玩的是NRF2L01,因为这款无线模块价格便宜,网上也就卖10多块钱!刚开始用51写,“百度一下”发现网上的程序真是百篇一律,你抄我,我抄你。

对比了几个程序之后,发现他们的程序注释也是自相矛盾,看了的唯一收获就是,结合技术资料,对NRF24L01的工作模式和通信过程有了个总体的把握。

用51调了几次没成功,改而用430板子来写。

在网上查了一些相关的程序,终于成功了。

现在发现其实要写对NRF24L01的基本通信程序并不难,当然要玩转它又是另外一回事了。

我也刚刚才玩会单通道接收发送这个工作模式,其他的工作模式还没玩!还是附上相应的程序供大家学习交流,当然程序可能难免还有疏漏和错误,还望比拼指出!这是NRF24L01的头文件配置程序:#include <msp430x14x.h>//=======================NRF24L01_CE 端口========================================= #define RF24L01_CE_0 P3OUT &=~BIT1#define RF24L01_CE_1 P3OUT |= BIT1//=============================RF24L01_CSN 端口================================== #define RF24L01_CSN_0 P3OUT &=~BIT3#define RF24L01_CSN_1 P3OUT |= BIT3//=============================RF24L01_SCK 端口====================================== #define RF24L01_SCK_0 P3OUT &=~BIT2#define RF24L01_SCK_1 P3OUT |= BIT2//=============================RF24L01_MISO 端口=========================================#define RF24L01_MISO_0 P3OUT &=~BIT0#define RF24L01_MISO_1 P3OUT |= BIT0//============================= RF24L01_MOSI 端口================================ #define RF24L01_MOSI_0 P2OUT &=~BIT6#define RF24L01_MOSI_1 P2OUT |= BIT6//==========================IRQ 状态============================================ #define RF24L01_IRQ_0 P2OUT &=~BIT7#define RF24L01_IRQ_1 P2OUT |= BIT7//==========================NRF24L01地址,接收发送数据长度=============================== =============#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 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 NOP1 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 STATUS 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 // 接收频道0接收数据长度#define RX_PW_P2 0x13 // 接收频道0接收数据长度#define RX_PW_P3 0x14 // 接收频道0接收数据长度#define RX_PW_P4 0x15 // 接收频道0接收数据长度#define RX_PW_P5 0x16 // 接收频道0接收数据长度#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置//=============================RF24l01状态=====================================char TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址//我刚开始学的时候对这个发送和接收地址不是很明白,为什么他要设置成这样,后来才知道这个地址是用户自己定的,也就是说不是每个芯片只有唯一的地址,只要发送和接收端的地址一致就行char RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址char sta;char TxBuf[32]={0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,}; //这个程序要发送的数据void RF24L01_IO_set(void);void ms_delay(void);void InitSys();void Delay(int s);char SPI_RW(char data);char SPI_Read(char reg);char SPI_RW_Reg(char reg, char value);char SPI_Read_Buf(char reg, char *pBuf, char uchars);char SPI_Write_Buf(char reg, char *pBuf, char uchars);void SetRX_Mode(void);char nRF24L01_RxPacket(char* rx_buf);void nRF24L01_TxPacket(char * tx_buf);void init_NRF24L01(void);//===========================RF24L01端口设置========================================== void RF24L01_IO_set(void){P2DIR &= 0x7f; P2DIR |= 0x40; P2SEL&=0x3F; P2IE=P2IE&0x3f;P3DIR &= 0xFE; P3DIR |= 0x0E; P3SEL&=0xF0;}//******************************************************************************//系统初始化打开430XT2晶振//******************************************************************************void InitSys(){unsigned int iq0;_DINT();BCSCTL1 &=~XT2OFF;do{IFG1 &= ~OFIFG; // 清除振荡器失效标志for (iq0 = 0xFF; iq0 > 0; iq0--); // 延时,等待XT2起振}while ((IFG1 & OFIFG) != 0); // 判断XT2是否起振BCSCTL2 =SELM1+SELS; // MCLK,SMCLK时钟为XT2}//========================延时约5ms============================================= void ms_delay(void){unsigned int i=40000;while (i != 0){i--;}}//========================================长延时================================ void Delay(int s){unsigned int i,j;for(i=0; i<s; i++);for(j=0; j<s; j++);}//****************************************************************************************** //延时函数//****************************************************************************************** void inerDelay_us(char n){for(;n>0;n--);}//============================================================================== //函数:uint SPI_RW(uint uchar)//功能:NRF24L01的SPI写时序//******************************************************************************char SPI_RW(char data){char i,temp=0;for(i=0;i<8;i++) // output 8-bit{if((data & 0x80)==0x80){RF24L01_MOSI_1; // output 'uchar', MSB to MOSI}else{RF24L01_MOSI_0;}data = (data << 1); // shift next bit into MSB..temp<<=1;RF24L01_SCK_1; // Set SCK high..if((P3IN&0x01)==0x01)temp++; // capture current MISO bitRF24L01_SCK_0; // ..then set SCK low again}return(temp); // return read uchar}//*********************************************************************************************** *****//函数:uchar SPI_Read(uchar reg)//功能:NRF24L01的SPI时序//*********************************************************************************************** *****char SPI_Read(char reg){char reg_val;RF24L01_CSN_0; // CSN low, initialize SPI communication...SPI_RW(reg); // Select register to read from..reg_val = SPI_RW(0); // ..then read registervalueRF24L01_CSN_1; // CSN high, terminate SPI communicationreturn(reg_val); // return register value}//*********************************************************************************************** *****///功能:NRF24L01读写寄存器函数//*********************************************************************************************** *****/char SPI_RW_Reg(char reg, char value){char status1;RF24L01_CSN_0; // CSN low, init SPI transactionstatus1 = SPI_RW(reg); // select registerSPI_RW(value); // ..and write value to it..RF24L01_CSN_1; // CSN high againreturn(status1); // return nRF24L01 status uchar}//*********************************************************************************************** *****///函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)//功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数//****************************************************************************************************/char SPI_Read_Buf(char reg, char *pBuf, char chars){char status2,uchar_ctr;RF24L01_CSN_0; // Set CSN low, init SPI tranactionstatus2 = SPI_RW(reg); // Select register to write to and read status ucharfor(uchar_ctr=0;uchar_ctr<chars;uchar_ctr++){pBuf[uchar_ctr] = SPI_RW(0);}RF24L01_CSN_1;return(status2); // return nRF24L01 status uchar}//*********************************************************************************************** **********//函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)//功能: 用于写数据reg:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数//*********************************************************************************************** **********/char SPI_Write_Buf(char reg, char *pBuf, char chars){char status1,uchar_ctr;RF24L01_CSN_0; //SPI使能status1 = SPI_RW(reg);for(uchar_ctr=0; uchar_ctr<chars; uchar_ctr++){SPI_RW(*pBuf++);}RF24L01_CSN_1; //关闭SPIreturn(status1);}//*********************************************************************************************** *****///函数:void SetRX_Mode(void)//功能:数据接收配置//*********************************************************************************************** *****/void SetRX_Mode(void){RF24L01_CE_0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC,主接收RF24L01_CE_1;inerDelay_us(130); //注意不能太小}//*********************************************************************************************** *******///函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)//功能:数据读取后放如rx_buf接收缓冲区中//*********************************************************************************************** *******/char nRF24L01_RxPacket(char* rx_buf){char revale=0;sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况if(sta&0x40) // 判断是否接收到数据{RF24L01_CE_0 ; //SPI使能SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH); // read receive payload from RX_FIFO buffer revale =1; //读取数据完成标志}SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志return revale;}//*********************************************************************************************** ************//函数:void nRF24L01_TxPacket(char * tx_buf)//功能:发送tx_buf中数据//*********************************************************************************************** ***********/void nRF24L01_TxPacket(char * tx_buf){RF24L01_CE_0 ; //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_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送RF24L01_CE_1; //置高CE,激发数据发送inerDelay_us(10);}//****************************************************************************************//NRF24L01初始化//***************************************************************************************/void init_NRF24L01(void){inerDelay_us(100);RF24L01_CE_0 ; // chip enableRF24L01_CSN_1; // Spi disableRF24L01_SCK_0; // Spi clock line init highSPI_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); // 允许接收地址只有频道0,如果需要多频道可以参考Pa ge21SPI_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,发射功率为最大值0dBSPI_RW_Reg(WRITE_REG + CONFIG, 0x0E); // IRQ收发完成中断响应,16位CRC ,主接收}}//=============================================================================下面是发送主程序:#include <msp430x14x.h>#include "NRF24L01.h"void main(){WDTCTL = WDTPW + WDTHOLD; //禁止看门狗RF24L01_IO_set();InitSys();init_NRF24L01() ;nRF24L01_TxPacket(TxBuf); // 将要发送的数据转移到发送缓冲区while(1){nRF24L01_TxPacket(TxBuf);SPI_RW_Reg(WRITE_REG+STATUS,0XFF); //清状态寄存器ms_delay();ms_delay();LED1_1;ms_delay();ms_delay();LED1_0;}}下面是接收主程序:将接收到的数据发送到PC 可以通过串口助手来查看接收到数据是否正确#include <msp430x14x.h>#include "NRF24L01.h"char RxBuf[32]={0};//===============================串口初始化=====================================void init_uart0(void){//====================串口工作模式设置========================================U0CTL=0x00; // U0CTL包含串口0通信协议、通信模式、校验位等设置,允许UART0U0CTL +=CHAR; //(CHAR=0x10)当CHAR=0时位7位数据,当CHAR=1时为8位数据//不需要校验,数据位为8位,无反馈,异步UART通信,UART被允许//====================串口发送操作设置========================================U0TCTL=0x00; //U0TCTL包含串口0发送功能操作U0TCTL +=SSEL0; //波特率发生器选择ACLK//#define SSEL1 (0x20) #define SSEL0 (0x10)//====================串口拨特率设置9600====================================//===================拨特率计算公式:拨特率=BRCLK/(UBR+(M7+M6+。

NORDIC NRF24LE1 发送程序

NORDIC NRF24LE1 发送程序
sbit S2 = P1^3; // 1/0=未按/按下
sbit S1 = P1^2; // 1/0=未按/按下
sbit LED3 = P0^1; // 1/0=灭/亮
sbit LED3 = P0^2; // 1/0=灭/亮
sbit LED2 = P0^1; // 1/0=灭/亮
sbit LED1 = P0^0; // 1/0=灭/亮
status = SPI_RW(reg); // 选择RF寄存器
for(byte_ctr=0; byte_ctr SPI_RW(*pBuf++);
RFCSN = 1;
return(status); // 返回RF状态值
uint8_t bdata sta;
sbit RX_DR =sta^6;
sbit TX_DS =sta^5;
sbit MAX_RT =sta^4;
/**************************************************
功能:延时
**************************************************/
**************************************************/
uint8_t SPI_Write_Buf(uint8_t reg, uint8_t *pBuf, uint8_t bytes)
{
uint8_t status,byte_ctr;
RFCSN = 0;
sbit LED1 = P0^0; // 1/0=灭/亮
#define p0dir 0xd8
#define p1dir 0xff

nrf24l01无线温度传输—51单片机

nrf24l01无线温度传输—51单片机

无线温度传输系统学校:安徽工业大学学院:电气信息学院由于最近要毕业设计了,老师让我做无线通信,然后我上网找了很多资料,决定用24L01做,经过一段时间的摸索,终于实现了24L01的无线温度传输。

以下是我的程序,可供大家参考(当中在贴吧中学到了很多关于24l01的知识)。

发射端程序:#include <reg52.h>#include <intrins.h>//#include "api.h"#define uchar unsigned char#define TX_ADR_WIDTH 5 // 发射地址的字节个数#define TX_PLOAD_WIDTH 2 //发射字节uchar const TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x55,0x10,0x10,0x01};uchar rx_buf[TX_PLOAD_WIDTH];uchar tx_buf[TX_PLOAD_WIDTH];uchar distance_data[2];uchar flag;//标志sbit CE=P1^1; //发射高电平大于10MS 接收高电平sbit CSN=P1^2; //低电平ISP使能sbit SCK=P1^3; //下降沿sbit MOSI=P1^4; //MCU出sbit MISO=P1^5; //MCU入sbit IRQ=P1^6; //中断uchar bdata sta;sbit RX_DR =sta^6; //接收数据准备就绪sbit TX_DS =sta^5; //已发送数据sbit MAX_RT =sta^4;sbit DQ=P3^3;unsigned char time; //设置全局变量,专门用于严格延时//*********************************************NRF24L01*********************** **************//***************************************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 STATUS 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 // 接收频道0接收数据长度#define RX_PW_P2 0x13 // 接收频道0接收数据长度#define RX_PW_P3 0x14 // 接收频道0接收数据长度#define RX_PW_P4 0x15 // 接收频道0接收数据长度#define RX_PW_P5 0x16 // 接收频道0接收数据长度#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置//***************************************************************************** *********void init_io(void){CE=0;CSN=1;SCK=0;}void delay_ms(unsigned int x){unsigned int i,j;for(i=0;i<x;i++){j=108;while(j--);}}uchar SPI_RW(uchar byte)//发送指令,接受状态,返回值为状态值{uchar bit_ctr;for(bit_ctr=0;bit_ctr<8;bit_ctr++){MOSI = (byte&0x80);byte = (byte<<1);SCK = 1;byte|=MISO;SCK=0;}return(byte);}uchar SPI_RW_Reg(uchar reg, uchar value){uchar status;CSN = 0;status = SPI_RW(reg);SPI_RW(value);CSN = 1;return(status);}uchar SPI_Read(uchar reg){uchar reg_val;CSN = 0;SPI_RW(reg); //写指令reg_val = SPI_RW(0); //读reg的内容CSN = 1;return(reg_val);}uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes){uchar status,byte_ctr;CSN = 0;status = SPI_RW(reg);for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)pBuf[byte_ctr] = SPI_RW(0);CSN = 1;return(status);}uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes){uchar status,byte_ctr;CSN = 0;status = SPI_RW(reg);for(byte_ctr=0; byte_ctr<bytes; byte_ctr++)SPI_RW(*pBuf++);CSN = 1;return(status);}void TX_Mode(void){CE=0;SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS/*接收模块的地址*/, TX_ADR_WIDTH/*地址宽度5*/);SPI_Write_Buf(WRITE_REG + RX_ADDR_P0/*通道0 接收数据地址*/, TX_ADDRESS, TX_ADR_WIDTH);SPI_Write_Buf(WR_TX_PLOAD,/*写待发数据指令a0*/ tx_buf, TX_PLOAD_WIDTH/*20*/);SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); //数据通道0应答允许SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); //接收数据通道0允许SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a);//等待500+86us 自动重发10次SPI_RW_Reg(WRITE_REG + RF_CH,40);SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //数据传输率1Mbps ,发射功率0dBm SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); //配置寄存器CE=1;}void checkflag(){ sta=SPI_Read(STA TUS);//读状态寄存器// if(RX_DR)// {// SPI_Read_Buf(RD_RX_PLOAD/*读取接收数据指令*/,rx_buf/*数组[20]*/,TX_PLOAD_WIDTH/*20*/);// flag=1;// }if(MAX_RT){SPI_RW_Reg(FLUSH_TX/*冲洗发送FIFO指令*/,0);}SPI_RW_Reg(WRITE_REG+STATUS,sta);//清除中断}//以下是DS18B20的操作程序//************************************************************************/ void delay1ms(){unsigned char i,j;for(i=0;i<4;i++)for(j=0;j<33;j++);}/*****************************************************函数功能:延时若干毫秒入口参数:n***************************************************/void delaynms(unsigned char n){unsigned char i;for(i=0;i<n;i++)delay1ms();}/*****************************************************函数功能:将DS18B20传感器初始化,读取应答信号出口参数:flag***************************************************/bit Init_DS18B20(void){bit flag; //储存DS18B20是否存在的标志,flag=0,表示存在;flag=1,表示不存在DQ = 1; //先将数据线拉高for(time=0;time<2;time++) //略微延时约6微秒;DQ = 0; //再将数据线从高拉低,要求保持480~960usfor(time=0;time<200;time++) //略微延时约600微秒; //以向DS18B20发出一持续480~960us的低电平复位脉冲DQ = 1; //释放数据线(将数据线拉高)for(time=0;time<10;time++); //延时约30us(释放总线后需等待15~60us让DS18B20输出存在脉冲)flag=DQ; //让单片机检测是否输出了存在脉冲(DQ=0表示存在)for(time=0;time<200;time++) //延时足够长时间,等待存在脉冲输出完毕;return (flag); //返回检测成功标志}/*****************************************************函数功能:从DS18B20读取一个字节数据出口参数:dat***************************************************/unsigned char ReadOneChar(void){unsigned char i=0;unsigned char dat; //储存读出的一个字节数据for (i=0;i<8;i++){DQ =1; // 先将数据线拉高_nop_(); //等待一个机器周期DQ = 0; //单片机从DS18B20读书据时,将数据线从高拉低即启动读时序_nop_(); //等待一个机器周期DQ = 1; //将数据线"人为"拉高,为单片机检测DS18B20的输出电平作准备for(time=0;time<2;time++); //延时约6us,使主机在15us内采样dat>>=1;if(DQ==1)dat|=0x80; //如果读到的数据是1,则将1存入datelsedat|=0x00;//如果读到的数据是0,则将0存入dat//将单片机检测到的电平信号DQ存入r[i]for(time=0;time<8;time++); //延时3us,两个读时序之间必须有大于1us的恢复期}return(dat); //返回读出的十六进制数据}/*****************************************************函数功能:向DS18B20写入一个字节数据入口参数:dat***************************************************/WriteOneChar(unsigned char dat){unsigned char i=0;for (i=0; i<8; i++){DQ =1; // 先将数据线拉高_nop_(); //等待一个机器周期DQ=0; //将数据线从高拉低时即启动写时序DQ=dat&0x01; //利用与运算取出要写的某位二进制数据,//并将其送到数据线上等待DS18B20采样for(time=0;time<10;time++);//延时约30us,DS18B20在拉低后的约15~60us期间从数据线上采样DQ=1; //释放数据线for(time=0;time<1;time++);//延时3us,两个写时序间至少需要1us的恢复期dat>>=1; //将dat中的各二进制位数据右移1位}for(time=0;time<4;time++); //稍作延时,给硬件一点反应时间}/*****************************************************函数功能:做好读温度的准备***************************************************/void ReadyReadTemp(void){Init_DS18B20(); //将DS18B20初始化WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换delaynms(150); //转换一次需要延时一段时间Init_DS18B20(); //将DS18B20初始化WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器,前两个分别是温度的低位和高位}void dwend(void){ uchar TL; //储存暂存器的温度低位uchar TH; //储存暂存器的温度高位TL=ReadOneChar(); //先读的是温度值低位TH=ReadOneChar(); //接着读的是温度值高位distance_data[0]=TH ; //测量结果的高8位distance_data[1]=TL; //放入16位的高8位}void main(void){uchar xx;init_io();while(1){ReadyReadTemp() ;dwend();checkflag();for(xx=0;xx<2;xx++){tx_buf[xx]= distance_data[xx];//发数据之前必须把要发送的数据装入它}TX_Mode(); //必须启动发送模块delay_ms(5);}}接收端程序:#include <reg52.h>#include <intrins.h>#define uchar unsigned charuchar code digit[11]={"0123456789-"}; //定义字符数组显示数字uchar code Str[]={"RICHMCU DS18B20"}; //说明显示的是温度//unsigned char code Error[]={" DS18B20 ERROR"}; //说明没有检测到DS18B20 //unsigned char code Error1[]={" PLEASE CHECK"}; //说明没有检测到DS18B20 uchar code Temp[]={"WENDU:"}; //说明显示的是温度uchar code Cent[]={"Cent"}; //温度单位uchar tm[2];uchar flg=0; //负温度标志和临时暂存变量uchar tltemp;#define TX_ADR_WIDTH 5#define TX_PLOAD_WIDTH 2uchar const TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x55,0x10,0x10,0x01};uchar rx_buf[TX_PLOAD_WIDTH];uchar tx_buf[TX_PLOAD_WIDTH];uchar flag;//标志int cout;sbit CE=P1^1; //发射高电平大于10MS 接收高电平sbit CSN=P1^2; //低电平ISP使能sbit SCK=P1^3; //下降沿sbit MOSI=P1^4; //MCU出sbit MISO=P1^5; //MCU入sbit IRQ=P1^6; //中断uchar bdata sta;sbit RX_DR =sta^6; //接收数据准备就绪sbit TX_DS =sta^5; //已发送数据sbit MAX_RT =sta^4;sbit RS=P2^0; //寄存器选择位,将RS位定义为P2.0引脚sbit RW=P2^1; //读写选择位,将RW位定义为P2.1引脚sbit E=P2^2; //使能信号位,将E位定义为P2.2引脚sbit BF=P0^7; //忙碌标志位,,将BF位定义为P0.7引脚//***************************************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 STATUS 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 // 接收频道0接收数据长度#define RX_PW_P2 0x13 // 接收频道0接收数据长度#define RX_PW_P3 0x14 // 接收频道0接收数据长度#define RX_PW_P4 0x15 // 接收频道0接收数据长度#define RX_PW_P5 0x16 // 接收频道0接收数据长度#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置//***************************************************************************** *********void delay1ms(){unsigned char i,j;for(i=0;i<4;i++)for(j=0;j<33;j++);}/*****************************************************函数功能:延时若干毫秒入口参数:n***************************************************/void delaynms(unsigned char n){unsigned char i;for(i=0;i<n;i++)delay1ms();}bit BusyTest(void){bit result;RS=0; //根据规定,RS为低电平,RW为高电平时,可以读状态RW=1;E=1; //E=1,才允许读写_nop_(); //空操作_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间result=BF; //将忙碌标志电平赋给resultE=0; //将E恢复低电平return result;}/*****************************************************函数功能:将模式设置指令或显示地址写入液晶模块入口参数:dictate***************************************************/void WriteInstruction (unsigned char dictate){while(BusyTest()==1); //如果忙就等待RS=0; //根据规定,RS和R/W同时为低电平时,可以写入指令RW=0;E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲,// 就是让E从0到1发生正跳变,所以应先置"0"_nop_();_nop_(); //空操作两个机器周期,给硬件反应时间P0=dictate; //将数据送入P0口,即写入指令或地址_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=1; //E置高电平_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令}/*****************************************************函数功能:指定字符显示的实际地址入口参数:x***************************************************/void WriteAddress(unsigned char x){WriteInstruction(x|0x80); //显示位置的确定方法规定为"80H+地址码x"}/*****************************************************函数功能:将数据(字符的标准ASCII码)写入液晶模块入口参数:y(为字符常量)***************************************************/void WriteData(unsigned char y){while(BusyTest()==1);RS=1; //RS为高电平,RW为低电平时,可以写入数据RW=0;E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲,// 就是让E从0到1发生正跳变,所以应先置"0"P0=y; //将数据送入P0口,即将数据写入液晶模块_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=1; //E置高电平_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令}/*****************************************************函数功能:对LCD的显示模式进行初始化设置***************************************************/void LcdInitiate(void){delaynms(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间WriteInstruction(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口delaynms(5); //延时5ms,给硬件一点反应时间WriteInstruction(0x38);delaynms(5); //延时5ms,给硬件一点反应时间WriteInstruction(0x38); //连续三次,确保初始化成功delaynms(5); //延时5ms,给硬件一点反应时间WriteInstruction(0x0c); //显示模式设置:显示开,无光标,光标不闪烁delaynms(5); //延时5ms,给硬件一点反应时间WriteInstruction(0x06); //显示模式设置:光标右移,字符不移delaynms(5); //延时5ms,给硬件一点反应时间WriteInstruction(0x01); //清屏幕指令,将以前的显示内容清除delaynms(5); //延时5ms,给硬件一点反应时间}/*****************************************************函数功能:显示说明信息***************************************************/void display_explain(void){unsigned char i;WriteAddress(0x00); //写显示地址,将在第1行第1列开始显示i = 0; //从第一个字符开始显示while(Str[i] != '\0') //只要没有写到结束标志,就继续写{WriteData(Str[i]); //将字符常量写入LCDi++; //指向下一个字符delaynms(100); //延时100ms较长时间,以看清关于显示的说明}}/*****************************************************函数功能:显示温度符号***************************************************/void display_symbol(void){unsigned char i;WriteAddress(0x40); //写显示地址,将在第2行第1列开始显示i = 0; //从第一个字符开始显示while(Temp[i] != '\0') //只要没有写到结束标志,就继续写{WriteData(Temp[i]); //将字符常量写入LCDi++; //指向下一个字符delaynms(50); //延时1ms给硬件一点反应时间}}/*****************************************************函数功能:显示温度的小数点***************************************************/void display_dot(void){WriteAddress(0x49); //写显示地址,将在第2行第10列开始显示WriteData('.'); //将小数点的字符常量写入LCDdelaynms(50); //延时1ms给硬件一点反应时间}/*****************************************************函数功能:显示温度的单位(Cent)***************************************************/void display_cent(void){unsigned char i;WriteAddress(0x4c); //写显示地址,将在第2行第13列开始显示i = 0; //从第一个字符开始显示while(Cent[i] != '\0') //只要没有写到结束标志,就继续写{WriteData(Cent[i]); //将字符常量写入LCDi++; //指向下一个字符delaynms(50); //延时1ms给硬件一点反应时间}}/*****************************************************函数功能:显示温度的整数部分入口参数:x***************************************************/void display_temp1(uchar x){uchar j,k,l; //j,k,l分别储存温度的百位、十位和个位j=x/100; //取百位k=(x%100)/10; //取十位l=x%10; //取个位WriteAddress(0x46); //写显示地址,将在第2行第7列开始显示if(flg==1) //负温度时显示“—”{WriteData(digit[10]); //将百位数字的字符常量写入LCD}else{WriteData(digit[j]); //将十位数字的字符常量写入LCD}WriteData(digit[k]); //将十位数字的字符常量写入LCDWriteData(digit[l]); //将个位数字的字符常量写入LCDdelaynms(5); //延时1ms给硬件一点反应时间}/*****************************************************函数功能:显示温度的小数数部分入口参数:x***************************************************/void display_temp2(uchar x){WriteAddress(0x4a); //写显示地址,将在第2行第11列开始显示WriteData(digit[x]); //将小数部分的第一位数字字符常量写入LCD delaynms(5); //延时1ms给硬件一点反应时间}void init_io(void){CE=0;CSN=1;SCK=0;}void delay_ms(unsigned int x){unsigned int i,j;for(i=0;i<x;i++){j=108;while(j--);}}uchar SPI_RW(uchar byte){uchar bit_ctr;for(bit_ctr=0;bit_ctr<8;bit_ctr++){MOSI = (byte&0x80);byte = (byte<<1);SCK = 1;byte|=MISO;SCK=0;}return(byte);}uchar SPI_RW_Reg(uchar reg, uchar value){uchar status;CSN = 0;status = SPI_RW(reg);SPI_RW(value);CSN = 1;return(status);}uchar SPI_Read(uchar reg){uchar reg_val;CSN = 0;SPI_RW(reg);reg_val = SPI_RW(0);CSN = 1;return(reg_val);}uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes) {uchar status,byte_ctr;CSN = 0;status = SPI_RW(reg);for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)pBuf[byte_ctr] = SPI_RW(0);CSN = 1;return(status);}uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes) {uchar status,byte_ctr;CSN = 0;status = SPI_RW(reg);for(byte_ctr=0; byte_ctr<bytes; byte_ctr++)SPI_RW(*pBuf++);CSN = 1;return(status);}void RX_Mode(void){CE=0;SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); //数据通道0应答允许SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);//接收数据通道0允许SPI_RW_Reg(WRITE_REG + RF_CH, 40);SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);// 接收频道0 接收数据长度设置SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //数据传输率1Mbps ,发射功率0dBm SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); //配置寄存器CE = 1;}void checkflag(){sta=SPI_Read(STA TUS);if(RX_DR){SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);flag=1;}if(MAX_RT){SPI_RW_Reg(FLUSH_TX,0);}SPI_RW_Reg(WRITE_REG+STATUS,sta);}void yejinchu(void){LcdInitiate(); //将液晶初始化delaynms(5); //延时5ms给硬件一点反应时间display_explain();display_symbol(); //显示温度说明display_dot(); //显示温度的小数点display_cent(); //显示温度的单位}void xianshi(void){uchar TL; //储存暂存器的温度低位uchar TH; //储存暂存器的温度高位uchar TN; //储存温度的整数部分uchar TD; //储存温度的小数部分TH=tm[0] ;TL=tm[1];if((TH&0xf8)!=0x00)//判断高五位得到温度正负标志{flg=1;TL=~TL; //取反TH=~TH; //取反tltemp=TL+1; //低位加1TL=tltemp;if(tltemp>255) TH++; //如果低8位大于255,向高8位进1TN=TH*16+TL/16; //实际温度值=(TH*256+TL)/16,即:TH*16+TL/16//这样得出的是温度的整数部分,小数部分被丢弃了TD=(TL%16)*10/16; //计算温度的小数部分,将余数乘以10再除以16取整,}TN=TH*16+TL/16; //实际温度值=(TH*256+TL)/16,即:TH*16+TL/16//这样得出的是温度的整数部分,小数部分被丢弃了TD=(TL%16)*10/16; //计算温度的小数部分,将余数乘以10再除以16取整,//这样得到的是温度小数部分的第一位数字(保留1位小数)display_temp1(TN); //显示温度的整数部分display_temp2(TD); //显示温度的小数部分delaynms(5);}void main(void){uchar xx;yejinchu();init_io();RX_Mode();while(1){checkflag();if(flag){flag=0;for(xx=0;xx<2;xx++){tm[xx]=rx_buf[xx];delay_ms(1);}xianshi();}}}。

NRF24L01的发送与接收程序

NRF24L01的发送与接收程序

#include <> #include <>typedef unsigned char uchar;typedef unsigned char uint;SCK = 1;uchar |= MISO; then set SCK low again}return(uchar); .SPI_RW(reg);reg_val = SPI_RW(0); then read registervalueCSN = 1; and write value to it..CSN = 1;SCK = 1;uchar |= MISO; then set SCK low again}return(uchar); .SPI_RW(reg);reg_val = SPI_RW(0); then read registervalueCSN = 1; and write value to it..CSN = 1; // CSN high again/* 函数: uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars) /* 功能 : 用于读数据,reg :为寄存器地址,pBuf :为待读出数据地址, uchars :读出数据的个数******************* uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars){uint status,uchar_ctr;CSN = 0; // Set CSN low, init SPI tranaction return(status); }// return nRF24L01 status ucharstatus = SPI_RW(reg); // Select register to write to and read status ucharfor(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)pBuf[uchar_ctr] = SPI_RW(0); //CSN = 1;return(status); // return nRF24L01 status uchar}/**************************/* 函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)/* 功能: 用于写数据:为寄存器地址,pBuf :为待写入数据地址,uchars :写入数据的个数/**************************/uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars){uint status,uchar_ctr;CSN = 0; //SPI 使能status = SPI_RW(reg);for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //SPI_RW(*pBuf++);CSN = 1; // 关闭SPIreturn(status); ///********************//* 函数:void SetRX_Mode(void)/* 功能:数据接收配置/**********************/void SetRX_Mode(void){CE=0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); 接收CE = 1;inerDelay_us(130); // 延时不能太短}/**********************//* 函数: unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)/* 功能:数据读取后放如 rx_buf 接收缓冲区中/***********************/unsigned char nRF24L01_RxPacket(unsigned char* rx_buf){unsigned char revale=0;sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况if(RX_DR) // 判断是否接收到数据{CE = 0; //SPI 使能SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload frombuffer// IRQ 收发完成中断响应, 16 位 CRC,主 FIFOSPI_RW_Reg(WRITE_REG+STATUS,sta); // 接收到数据后RX_DR,TX_DS,MAX_P都置高为1 通过写1 来清楚中断标志return revale;}/****************************/* 函数:void nRF24L01_TxPacket(unsigned char * tx_buf)/* 功能:发送tx_buf 中数据/****************************/void nRF24L01_TxPacket(unsigned char * tx_buf){CE=0; //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_RW_Reg(WRITE_REG + CONFIG, OxOe); // IRQ 收发完成中断响应,16 位CRC 主发送CE=1; //置高CE激发数据发送inerDelay_us(1O);}//************************************ void main(void){uchar temp =O;init_NRF24LO1() ;nRF24LO1_TxPacket(TxBuf);Delay(6OOO);PO=OxBF;主函数// Transmit Tx buffer datawhile(1)nRF24L01_TxPacket(TxBuf); // Transmit Tx buffer dataLED=0;Delay(10000); // 可变SPI_RW_Reg(WRITE_REG+STATUS,0XFF);LED=1;Delay(8000);}。

NRF24L01无线发射简易教程

NRF24L01无线发射简易教程

NRF24L01 简易教程先来看接口电路,使用的IO 口不是唯一的哦,可随意定义接口,当然是在使用IO 口模拟SPI 且IRQ 中断引脚不使用的使用查询方法判断接收状态的情况下了。

作为初探我们就是用简单的IO 模拟SPI 的方法了,中断使用查询的方式。

那么该教程讲解的接口与单片机的连接如下:首先您需要了解NRF24L01,请参阅“NRF24L01 芯片中文资料”或者“NRF24L01 芯片英文资料”。

我们的教程是以一个简单的小项目为大家展示NRF24L01 的使用方法与乐趣。

我们所写的教程均是以这种方式的呢,让您在学习的时候明白它能做什么,使您学起来不至于枯燥无味。

作为简易的教程,我们只需要知道它是怎么使用的就够了,我们本教程的目的是用NRF24L01 发送数据和接收数据,且接收方会对比发送的数据与接收的数据,若完全相同则控制LED 闪烁一次,并且把接收到的数据通过串口发送到PC 端,通过串口工具查看接收到的数据。

具体的要求如下:1、具备发送和接收的能力。

2、发送32 个字节的数据,接收方接收到正确数据之后给予提示,通过LED 闪烁灯形式。

3、把接收到的数据传送到PC 进行查看。

4、发送端每隔大约1.5 秒发送一次数据,永久循环。

以上是程序的要求,若您想自行设计出硬件接口,您也是可以添加一条呢:使用DIY 方式设计NRF24L01 的接口板,且包含含单片机平台,使用PCB 方式或者万用板方式均可。

如果您想让自己学的很扎实,那么推荐您自行做出接口板子呢。

当然若您的能力不足,那么我们不推荐自行做板呢,因为这样会增加您学习的难度,反而起到了反效果呢。

我们使用的方式是画PCB 的方式呢,若您自己做了接口板子,那么您可以对比下一呢,O(∩_∩)O!我们知道NRF24L01 的供电电压是1.9V~3.6V 不能超过这个范围,低了不工作,高了可能烧毁NRF24L01 芯片。

我们常用的STC89C52 的单片机的供电电压是5V,我们不能直接给24L01 这个模块供电,我们需要使用AMS1117-3.3V 稳压芯片把5V 转成3.3V 的电压为24L01 模块供电。

单片机基于2.4G无线收发模块NRF24L01的无线通信(基本测试通过)续

单片机基于2.4G无线收发模块NRF24L01的无线通信(基本测试通过)续

单片机基于2.4G无线收发模块NRF24L01的无线通信(基本测试通过)续二、软件部分1>接收方程序:主函数:#include <reg52.h>#include <stdio.h>#include'NRF24L01.h'#include <intrins.h>void main(){ unsigned char i=0;unsigned char data_RX[32]={1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2, 2,2,3,3,3,3,3,3,3,3,3,3,3,3};//接收到的32字节存放数组设置初值SCON = 0x50; //REN=1允许串行接受状态,串口工作模式1,8位收发,波特率可变TMOD|= 0x20; //定时器工作方式 2 ,自动重载初值PCON&= 0x7f; //波特率不加倍TH1 = 0xFA; //波特率等于4800、数据位8、停止位1。

效验位无,晶振为11.0592MHZTL1 = 0xFA;TR1 = 1; //开启定时器1 ES = 1; //开串口中断EA = 1; // 开总中断NRF24L01_RX();//设置为接收模式while(!((READ_BYTE(READ_REG+STATUS))&0x40)); //判断是否接收好32字节数据READ_BYTES(RD_RX_PLOAD,data_RX,32); //将32字节数据存放在数组中CE=0;CSN=1;_nop_();CSN=0;SPI_WRITE(FLUSH_RX); //清空接收FIFO,否则接收数据不可预知SCK=0;CSN=1;jieshouv=0; //接收成功标志位WRITE_BYTE(WRITE_REG+STATUS,0xFF); //屏蔽中断位for(i=0;i<32;i++){ if(data_RX[i]>=10){SBUF=data_RX[i]/10+48; //将十位转化为ASCII码发送while(!TI);TI=0;SBUF = data_RX[i]%10+48; //将个位转化为ASCII码发送while(!TI); // 等特数据传送(TI发送中断标志)TI = 0; // 清除数据传送标志}else{SBUF = data_RX[i]%10+48; //将无符号数转为ASCII码发送while(!TI); // 等特数据传送(TI发送中断标志)TI = 0; // 清除数据传送标志}}while(1);}*************************************************************** *************************************************详情请咨询: http://shop108408772.taoba /*************************************************************** ***********************************************子函数:#include <reg52.h>#include 'NRF24L01.h'#include <intrins.h>unsigned char ADD_TX[]={0,1,2,3,4}; //通道地址unsigned char data_TX[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; //发送方32字节数据void SPI_WRITE(unsigned char canshu) //写入一个字节{unsigned char i;for(i=0;i<8;i++){SCK=0;MOSI=(canshu&0x80)>>7; //先发高位SCK=1;canshu=canshu<<1;}}unsigned char SPI_READ() //读一个字节{unsigned char canshu=0,i;for(i=0;i<8;i++){canshu=canshu<<1; //先接收的为高位SCK=0;_nop_();SCK=1;canshu=canshu|MISO;}return canshu;}void WRITE_BYTE(unsigned char address,unsigned char value)//写入完整指令,单字节{CSN=1;_nop_();CSN=0;SPI_WRITE(address); //写入寄存器绝对地址_nop_();SPI_WRITE(value); //写入参数SCK=0; //恢复初值CSN=1; //恢复初值}unsigned char READ_BYTE(unsigned char address) //读入完整指令,单字节{unsigned char canshu;CSN=1;_nop_();CSN=0;SPI_WRITE(address); //写入寄存器绝对地址_nop_();canshu=SPI_READ(); //读出数据SCK=0;CSN=1;return canshu;}*************************************************************** *************************************************详情请咨询: http://shop108408772.taoba /*************************************************************** ***********************************************void WRITE_BYTES(unsigned char address,unsigned char *value,unsigned char width)//写入指定字节数据,多字节{unsigned char i;CSN=1;_nop_();CSN=0;SPI_WRITE(address); //写入寄存器绝对地址_nop_();for(i=0;i<width;i++){SPI_WRITE(*value); //将数据依次写入value=value+1;}SCK=0;CSN=1;}void READ_BYTES(unsigned char address,unsigned char *value,unsigned char width)//读入指定字节数据,多字节{unsigned char i;CSN=1;_nop_();CSN=0;SPI_WRITE(address); //写入寄存器绝对地址_nop_();for(i=0;i<width;i++){*value=SPI_READ(); //将数据依次读入value=value+1;}SCK=0;CSN=1;}/************************************************void NRF24L01_TX()//NRF24L01设为发送模式{ //默认NRF24L01为掉电模式unsigned char i;CE=0;WRITE_BYTE(WRITE_REG+SETUP_AW,0x03);//设置地址宽度为5字节WRITE_BYTE(WRITE_REG+RX_PW_P0,0x20);//设置接收通道0数据宽度为32字节WRITE_BYTES(WR_TX_PLOAD,data_TX,32);//写入发送数据WRITE_BYTES(WRITE_REG+TX_ADDR,ADD_TX,5);//设置发送地址WRITE_BYTES(WRITE_REG+RX_ADDR_P0,ADD_TX,5);//设置通道0地址WRITE_BYTE(WRITE_REG+EN_RXADDR,0x01);//使能接收通道0WRITE_BYTE(WRITE_REG+EN_AA,0x01);//使能通道0自动应答WRITE_BYTE(WRITE_REG+SETUP_RETR,0x1a);// 自动重发次数10次WRITE_BYTE(WRITE_REG+RF_CH,0x40); //设置载波频率WRITE_BYTE(WRITE_REG+RF_SETUP,0x0f); //射频参数,如数据传输率,发射功率WRITE_BYTE(WRITE_REG+CONFIG,0x0A);//设置发射,上电,CRC校验8位CE=1;for(i=0;i<10;i++);//延时30us}********************************************************/void NRF24L01_RX()//NRF24L01设为接收模式{unsigned char i; //默认NRF24L01为掉电模式CE=0;WRITE_BYTE(WRITE_REG+SETUP_AW,0x03);//设置地址宽度为5字节WRITE_BYTE(WRITE_REG+RX_PW_P0,0x20);//设置接收通道0数据宽度为32字节WRITE_BYTES(WRITE_REG+RX_ADDR_P0,ADD_TX,5);//设置通道0地址WRITE_BYTE(WRITE_REG+EN_RXADDR,0x01);//使能接收通道0WRITE_BYTE(WRITE_REG+EN_AA,0x01);//使能通道0自动应答WRITE_BYTE(WRITE_REG+RF_CH,0x40); //设置载波频率WRITE_BYTE(WRITE_REG+RF_SETUP,0x0f); //射频参数,如数据传输率,发射功率WRITE_BYTE(WRITE_REG+CONFIG,0x0B);//设置接收,上电,CRC校验8位CE=1;for(i=0;i<20;i++);//延时60us}*************************************************************** *************************************************详情请咨询: http://shop108408772.taoba /*************************************************************** ***********************************************1>发送方程序:主程序://#include <reg52.h>#include 'stc12.h'#include'NRF24L01.h'#include <intrins.h>void main(){CLK_DIV=0x03;NRF24L01_TX(); //发送模式开启while(!((READ_BYTE(READ_REG+STATUS))&0x30));//等待发送完成CE=0;CSN=1;_nop_();CSN=0;SPI_WRITE(FLUSH_RX); //清空接收FIFO,否则数据不可预料SCK=0;CSN=1;if((READ_BYTE(READ_REG+STATUS))&0x20)fasong=0; // 发送成功标志位WRITE_BYTE(WRITE_REG+STATUS,0xFF); //屏蔽中断标志位while(1);}子程序:和接收子程序大部分一致,改动部分:void NRF24L01_TX()//NRF24L01设为发送模式{ //默认NRF24L01为掉电模式unsigned char i;CE=0;WRITE_BYTE(WRITE_REG+SETUP_AW,0x03);//设置地址宽度为5字节WRITE_BYTE(WRITE_REG+RX_PW_P0,0x20);//设置接收通道0数据宽度为32字节WRITE_BYTES(WR_TX_PLOAD,data_TX,32);//写入发送数据WRITE_BYTES(WRITE_REG+TX_ADDR,ADD_TX,5);//设置发送地址WRITE_BYTES(WRITE_REG+RX_ADDR_P0,ADD_TX,5);//设置通道0地址WRITE_BYTE(WRITE_REG+EN_RXADDR,0x01);//使能接收通道0WRITE_BYTE(WRITE_REG+EN_AA,0x01);//使能通道0自动应答WRITE_BYTE(WRITE_REG+SETUP_RETR,0x1a);// 自动重发次数10次WRITE_BYTE(WRITE_REG+RF_CH,0x40); //设置载波频率WRITE_BYTE(WRITE_REG+RF_SETUP,0x0f); //射频参数,如数据传输率,发射功率WRITE_BYTE(WRITE_REG+CONFIG,0x0A);//设置发射,上电,CRC校验8位CE=1;for(i=0;i<30;i++);//延时90us}将接收子程序中接收模式程序屏蔽即可。

NRF24L01无线模块C语言程序

NRF24L01无线模块C语言程序

NRF24L01无线模块C语言程序24MHz晶振#include#include#include#include#include#include#define U8 unsigned char#define U16 unsigned int#define TX_ADDR_WITDH 5 //发送地址宽度设置为5个字节#define RX_ADDR_WITDH 5 //接收地址宽度设置为5个字节#define TX_DATA_WITDH 1//发送数据宽度1个字节#define RX_DATA_WITDH 1//接收数据宽度1个字节#define R_REGISTER 0x00//读取配置寄存器#define W_REGISTER 0x20//写配置寄存器#define R_RX_PAYLOAD 0x61//读取RX有效数据#define W_TX_PAYLOAD 0xa0//写TX有效数据#define FLUSH_TX 0xe1//清除TXFIFO寄存器#define FLUSH_RX 0xe2//清除RXFIFO寄存器#define REUSE_TX_PL 0xe3//重新使用上一包有效数据#define NOP 0xff//空操作#define CONFIG 0x00//配置寄存器#define EN_AA 0x01//使能自动应答#define EN_RXADDR 0x02//接收通道使能0-5个通道#define SETUP_AW 0x03//设置数据通道地址宽度3-5 #define SETUP_RETR 0x04//建立自动重发#define RF_CH 0x05//射频通道设置#define RF_SETUP 0x06//射频寄存器#define STATUS 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//P0通道数据宽度设置#define RX_PW_P1 0x12//P1通道数据宽度设置#define RX_PW_P2 0x13//P2通道数据宽度设置#define RX_PW_P3 0x14//P3通道数据宽度设置#define RX_PW_P4 0x15//P4通道数据宽度设置#define RX_PW_P5 0x16//P5通道数据宽度设置#define FIFO_STATUS 0x17//FIFO状态寄存器//NRF24L01U8 NRFACK();U8 NRFSPI(U8 date);U8 NRFReadReg(U8 RegAddr);U8 NRFWriteReg(U8 RegAddr,U8 date);U8 NRFReadRxDate(U8 RegAddr,U8 *RxDate,U8 DateLen);U8 NRFWriteTxDate(U8 RegAddr,U8 *TxDate,U8 DateLen);U8 NRFRevDate(U8 *RevDate);void NRFSetTxMode(U8 *TxDate);void NRF24L01Int();void NRFSetRXMode();U8 CheckACK();void Delay(U16 t);U8 bdata sta;//mainvoid Delay_10ms(U16 del);bit CE=P1^4; //RX/TX模式选择端sbit IRQ=P1^1; //可屏蔽中断端sbit CSN=P1^6; //SPI片选端//就是SSsbit MOSI=P1^0; //SPI主机输出从机输入端1sbit MISO=P1^2; //SPI主机输入从机输出端sbit SCLK=P1^3; //SPI时钟端U8 code TxAddr[]={0x34,0x43,0x10,0x10,0x01};//发送地址U8 bdata sta; //状态标志sbit RX_DR=sta^6;sbit TX_DS=sta^5;sbit MAX_RT=sta^4;void Delay(U16 t){U16 x,y;for(x=t;x>0;x--)for(y=110;y>0;y--);}U8 NRFSPI(U8 date){U8 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); // 返回读出的一字节}void NRF24L01Int(){Delay(2);//让系统什么都不干CE=0; //待机模式1CSN=1;SCLK=0;IRQ=1;}U8 NRFReadReg(U8 RegAddr){U8 BackDate;CSN=0;//启动时序NRFSPI(RegAddr);//写寄存器地址BackDate=NRFSPI(0x00);//写入读寄存器指令CSN=1;return(BackDate); //返回状态}U8 NRFWriteReg(U8 RegAddr,U8 date){U8 BackDate;CSN=0;//启动时序BackDate=NRFSPI(RegAddr);//写入地址NRFSPI(date);//写入值CSN=1;return(BackDate);}U8 NRFReadRxDate(U8 RegAddr,U8 *RxDate,U8 DateLen){ //寄存器地址//读取数据存放变量//读取数据长度//用于接收 U8 BackDate,i;CSN=0;//启动时序BackDate=NRFSPI(RegAddr);//写入要读取的寄存器地址for(i=0;i{RxDate[i]=NRFSPI(0);}CSN=1;return(BackDate);}U8 NRFWriteTxDate(U8 RegAddr,U8 *TxDate,U8 DateLen){ //寄存器地址//写入数据存放变量//读取数据长度//用于发送 U8 BackDate,i;CSN=0;BackDate=NRFSPI(RegAddr);//写入要写入寄存器的地址for(i=0;i{NRFSPI(*TxDate++);}CSN=1;return(BackDate);}void NRFSetTxMode(U8 *TxDate){//发送模式CE=0;NRFWriteTxDate(W_REGISTER+TX_ADDR,TxAddr,TX_ADDR_WITDH);//写寄存器指令+接收地址使能指令+接收地址+地址宽度NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH);//为了应答接收设备,接收通道0地址和发送地址相同NRFWriteTxDate(W_TX_PAYLOAD,TxDate,TX_DATA_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;Delay(5);//保持10us秒以上}//主要接收模式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;Delay(5);//保持10us秒以上}U8 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);}//用于接收模式U8 NRFRevDate(U8 *RevDate){U8 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 Delay_10ms(U16 del){U16 i,j;for(i=0; i<del; i++)for(j=0; j<1827; j++) //这个是通过软件仿真得出的数;}// 做发射main(){U8 TxDate[1]={0};NRF24L01Int();Delay(6000);while(1){if(KEY==0){if(KEY==0){Delay_10ms(2);TxDate[0]=0x08;//发射按键标识值NRFSetTxMode(TxDate);while(CheckACK());TxDate[0]=0;}}}}//// 做接收:一直处于接受模式查询所得到的值是不是0x08 main(){U8 x;U8 RxBuf[1]={0};NRF24L01Int();Delay(6000);while(1){NRFSetRXMode();NRFRevDate(RxBuf);x=RxBuf[0];if(x==0x08)//0x08为发射部分所发送的按键标识{////加入所要执行的功能函数//当然了这里用到单片机io口的时候需要在之前定义//还有就是发送程序中的KEY也需要之前定义好 RxBuf[0]=0;}}}。

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

/*发送*/#include <reg52.h>#include <intrins.h>typedef unsigned char uchar;typedef unsigned char uint;//****************************************IO端口定义sbit MISO =P1^2;sbit MOSI =P3^2;sbit SCK =P1^6;sbit CE =P1^5;sbit CSN =P1^7;sbit IRQ =P1^3;//***********************************数码管0-9编码uchar seg[10]={0xC0,0xCF,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //0~~9段码uchar TxBuf[32]={0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,}; ////************************************按键**********************************************sbit KEY1=P3^6;sbit KEY2=P3^7;//***********************************数码管位选sbit led1=P2^1;sbit led0=P2^0;sbit led2=P2^2;sbit led3=P2^3;//*********************************************NRF24L01************************ #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 // 20 uints TX payload#define RX_PLOAD_WIDTH 32 // 20 uints TX payloaduint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};//接收地址//***************************************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 STATUS 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 // 接收频道0接收数据长度#define RX_PW_P2 0x13 // 接收频道0接收数据长度#define RX_PW_P3 0x14 // 接收频道0接收数据长度#define RX_PW_P4 0x15 // 接收频道0接收数据长度#define RX_PW_P5 0x16 // 接收频道0接收数据长度#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置//***************************************************************************** *********void Delay(unsigned int s);void inerDelay_us(unsigned char n);void init_NRF24L01(void);uint SPI_RW(uint uchar);uchar SPI_Read(uchar reg);void SetRX_Mode(void);uint SPI_RW_Reg(uchar reg, uchar value);uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);void nRF24L01_TxPacket(unsigned char * tx_buf);//*****************************************长延时void Delay(unsigned int s){unsigned int i;for(i=0; i<s; i++);for(i=0; i<s; i++);}//***************************************************************************** uint bdata sta; //状态标志sbit RX_DR =sta^6;sbit TX_DS =sta^5;sbit MAX_RT =sta^4;/****************************************************************************** /*延时函数void inerDelay_us(unsigned char n){for(;n>0;n--)_nop_();}//***************************************************************************** /*NRF24L01初始化//***************************************************************************** void init_NRF24L01(void){inerDelay_us(100);CE=0; // chip enableCSN=1; // Spi disableSCK=0; // Spi clock line init highSPI_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); // 允许接收地址只有频道0,如果需要多频道可以参考Page21SPI_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,发射功率为最大值0dBSPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送}/****************************************************************************** /*函数:uint SPI_RW(uint uchar)/*功能:NRF24L01的SPI写时序/**************************************************************************/ uint SPI_RW(uint uchar){uint bit_ctr;for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit{MOSI = (uchar & 0x80); // output 'uchar', MSB to MOSIuchar = (uchar << 1); // shift next bit into MSB..SCK = 1; // Set SCK high..uchar |= MISO; // capture current MISO bitSCK = 0; // ..then set SCK low again}return(uchar); // return read uchar}/****************************************************************************** /*函数:uchar SPI_Read(uchar reg)/*功能:NRF24L01的SPI时序/*****************************************************************************/ uchar SPI_Read(uchar reg){uchar reg_val;CSN = 0; // CSN low, initialize SPI communication...SPI_RW(reg); // Select register to read from..reg_val = SPI_RW(0); // ..then read registervalueCSN = 1; // CSN high, terminate SPI communicationreturn(reg_val); // return register value}/*****************************************************************************/ /*功能:NRF24L01读写寄存器函数/*****************************************************************************/ uint SPI_RW_Reg(uchar reg, uchar value){uint status;CSN = 0; // CSN low, init SPI transactionstatus = SPI_RW(reg); // select registerSPI_RW(value); // ..and write value to it..CSN = 1; // CSN high againreturn(status); // return nRF24L01 status uchar}/*****************************************************************************/ /*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数/*****************************************************************************/ uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars){uint status,uchar_ctr;CSN = 0; // Set CSN low, init SPI tranactionstatus = SPI_RW(reg); // Select register to write to and read status ucharfor(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)pBuf[uchar_ctr] = SPI_RW(0); //CSN = 1;return(status); // return nRF24L01 status uchar}/****************************************************************************** /*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数/*****************************************************************************/ uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars){uint status,uchar_ctr;CSN = 0; //SPI使能status = SPI_RW(reg);for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //SPI_RW(*pBuf++);CSN = 1; //关闭SPIreturn(status); //}/*****************************************************************************/ /*函数:void SetRX_Mode(void)/*功能:数据接收配置/*****************************************************************************/ void SetRX_Mode(void){CE=0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收CE = 1;inerDelay_us(130);}/****************************************************************************** //*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)/*功能:数据读取后放如rx_buf接收缓冲区中/*****************************************************************************/ unsigned char nRF24L01_RxPacket(unsigned char* rx_buf){unsigned char revale=0;sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况if(RX_DR) // 判断是否接收到数据{CE = 0; //SPI使能SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO bufferrevale =1; //读取数据完成标志}SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志return revale;}/****************************************************************************** /*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)/*功能:发送tx_buf中数据/*****************************************************************************/ void nRF24L01_TxPacket(unsigned char * tx_buf){CE=0; //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_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送CE=1; //置高CE,激发数据发送inerDelay_us(10);}//************************************主函数void main(void){uchar temp =0;init_NRF24L01() ;led0=0;led1=0;led2=0;led3=0;P0=0x00;nRF24L01_TxPacket(TxBuf); // Transmit Tx buffer dataDelay(6000);P0=0xBF;while(1){if(temp<4){switch(temp){case 1:P0= 0xBF;break;case 2:P0= 0xf7;break;case 3:P0= 0xFE;break;default: break;}}if(temp==3){temp=0;}nRF24L01_TxPacket(TxBuf); // Transmit Tx buffer dataDelay(20000);SPI_RW_Reg(WRITE_REG+STATUS,0XFF);temp++;}}/*接收*/#include <reg52.h>#include <intrins.h>typedef unsigned char uchar;typedef unsigned char uint;//****************************************IO端口定义sbit MISO =P1^2;sbit MOSI =P3^2;sbit SCK =P1^6;sbit CE =P1^5;sbit CSN =P1^7;sbit IRQ =P1^3;//***********************************数码管0-9编码uchar seg[10]={0xC0,0xCF,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //0~~9段码//************************************按键sbit KEY1=P3^6;sbit KEY2=P3^7;//***********************************数码管位选sbit led1=P2^1;sbit led0=P2^0;sbit led2=P2^2;sbit led3=P2^3;//*********************************************NRF24L01*********** #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 // 20 uints TX payload#define RX_PLOAD_WIDTH 32 // 20 uints TX payloaduint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};//接收地址//***************************************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 STATUS 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 // 接收频道0接收数据长度#define RX_PW_P2 0x13 // 接收频道0接收数据长度#define RX_PW_P3 0x14 // 接收频道0接收数据长度#define RX_PW_P4 0x15 // 接收频道0接收数据长度#define RX_PW_P5 0x16 // 接收频道0接收数据长度#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置//***************************************************************************** void Delay(unsigned int s);void inerDelay_us(unsigned char n);void init_NRF24L01(void);uint SPI_RW(uint uchar);uchar SPI_Read(uchar reg);void SetRX_Mode(void);uint SPI_RW_Reg(uchar reg, uchar value);uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);void nRF24L01_TxPacket(unsigned char * tx_buf);//*****************************************长延时void Delay(unsigned int s){unsigned int i;for(i=0; i<s; i++);for(i=0; i<s; i++);}uint bdata sta; //状态标志sbit RX_DR =sta^6;sbit TX_DS =sta^5;sbit MAX_RT =sta^4;/****************************************************************************** /*延时函数/****************************************************************************** void inerDelay_us(unsigned char n){for(;n>0;n--)_nop_();}//***************************************************************************** /*NRF24L01初始化//*****************************************************************************void init_NRF24L01(void){inerDelay_us(100);CE=0; // chip enableCSN=1; // Spi disableSCK=0; // Spi clock line init highSPI_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); // 允许接收地址只有频道0,如果需要多频道可以参考Page21SPI_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,发射功率为最大值0dBSPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收}/****************************************************************************** /*函数:uint SPI_RW(uint uchar)/*功能:NRF24L01的SPI写时序/****************************************************************************** uint SPI_RW(uint uchar){uint bit_ctr;for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit{MOSI = (uchar & 0x80); // output 'uchar', MSB to MOSIuchar = (uchar << 1); // shift next bit into MSB..SCK = 1; // Set SCK high..uchar |= MISO; // capture current MISO bitSCK = 0; // ..then set SCK low again}return(uchar); // return read uchar}/****************************************************************************** /*函数:uchar SPI_Read(uchar reg)/*功能:NRF24L01的SPI时序/****************************************************************************** uchar SPI_Read(uchar reg){uchar reg_val;CSN = 0; // CSN low, initialize SPI communication...SPI_RW(reg); // Select register to read from..reg_val = SPI_RW(0); // ..then read registervalueCSN = 1; // CSN high, terminate SPI communicationreturn(reg_val); // return register value}/****************************************************************************** /*功能:NRF24L01读写寄存器函数/****************************************************************************** uint SPI_RW_Reg(uchar reg, uchar value){uint status;CSN = 0; // CSN low, init SPI transactionstatus = SPI_RW(reg); // select registerSPI_RW(value); // ..and write value to it..CSN = 1; // CSN high againreturn(status); // return nRF24L01 status uchar}/****************************************************************************** /*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数/****************************************************************************** uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars){uint status,uchar_ctr;CSN = 0; // Set CSN low, init SPI tranactionstatus = SPI_RW(reg); // Select register to write to and read status ucharfor(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)pBuf[uchar_ctr] = SPI_RW(0); //CSN = 1;return(status); // return nRF24L01 status uchar}/******************************************************************************/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数/****************************************************************************** ***************************/uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars){uint status,uchar_ctr;CSN = 0; //SPI使能status = SPI_RW(reg);for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //SPI_RW(*pBuf++);CSN = 1; //关闭SPIreturn(status); //}/****************************************************************************** /*函数:void SetRX_Mode(void)/*功能:数据接收配置/****************************************************************************** void SetRX_Mode(void){CE=0;// SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收CE = 1;inerDelay_us(130);}/****************************************************************************** /*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)/*功能:数据读取后放如rx_buf接收缓冲区中/****************************************************************************** unsigned char nRF24L01_RxPacket(unsigned char* rx_buf){unsigned char revale=0;sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况if(RX_DR) // 判断是否接收到数据{CE = 0; //SPI使能SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO bufferrevale =1; //读取数据完成标志}SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志return revale;}/****************************************************************************** /*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)/*功能:发送tx_buf中数据/****************************************************************************** void nRF24L01_TxPacket(unsigned char * tx_buf){CE=0; //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_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送CE=1; //置高CE,激发数据发送inerDelay_us(10);}//************************************串口初始化void StartUART( void ){ //波特率4800SCON = 0x50;TMOD = 0x20;TH1 = 0xFA;TL1 = 0xFA;PCON = 0x00;TR1 = 1;}//************************************通过串口将接收到数据发送给PC端void R_S_Byte(uchar R_Byte){SBUF = R_Byte;while( TI == 0 ); //查询法TI = 0;}//************************************主函数void main(void){uchar i,temp;uchar RxBuf[32];init_NRF24L01() ;led0=0;led1=0;led2=0;led3=0;StartUART();Delay(6000);while(1){if(temp<4){switch(temp){case 1:P0= 0xFE;break;case 2:P0= 0xBF;break;case 3:P0= 0xf7;break;default: break;}}if(temp==3){temp=0;}SetRX_Mode();if(nRF24L01_RxPacket(RxBuf)){temp++;for(i=0;i<32;i++){R_S_Byte(RxBuf[i]);Delay(600);}}}}。

相关文档
最新文档