nrf24l01无线模块基于51单片机的发送程序
基于 51 单片机的无线数据收发系统设计
基于 51 单片机的无线数据收发系统设计摘要:系统使用 51 单片机通过NRF24L01 模块远程传输数据,接收端通过NRF24L01 模块接收无线数据。
处理后由液晶进行数据显示,可根据需要设置声音提示。
系统接收与发送端模块均单片机、无线发送模块/ 接收、显示、声音提示模块。
关键词:51 单片机;NRF24L01;液晶显示;无线通讯1硬件设计1.1系统组成该系统将数据经过控制器由无线发送模块进行远距离发送,再通过接收端进行无线数据接收。
接收的数据经控制器处理后由液晶显示器显示,并根据需要可以实现一定的声音提示。
1.2无线收发模块本设计使用无线通讯技术实现数据的传送,能够实现此功能的硬件电路模块总类较多。
为符合设计需求,采用以NRF24L01 为核心的无线通讯模块。
该方案可以使系统具有低成本,低功耗,体积小等特点。
NRF24L01 无线模块出至 NORDIC 公司。
其工作频段在 2.4G— 5GHz,该模块正常工作电压为 1.9V—3.6V,内部具有 FSK 调制功能,集成了 NORDIC 公司自创的增强短脉冲协议。
该模块最多可实现 1 对 6 的数据发送与接收。
其每秒最高可传输两兆比特,能够实现地址检验及循环冗余检验。
若使用 SPI 接口,其每秒最高可传输八兆比特,多达 128 个可选工作频道,将该芯片的最小系统集成后,构成NRF24L01 无线通信模块。
1、引脚功能此模块有 6 个数据传输和控制引脚,采用 SPI 传输方式,实现全双工串口通讯,其中 CE脚为芯片模式控制线,工作情况下,CE 端协配合寄存器来决定模块的工作状态。
当4 脚电平为低时,模块开始工作。
数据写入的控制时钟由第 5 脚输入,数据写入与输出分别为 6、7 脚,中断信号放在了第 8 脚。
2、电器特性NRF24L01 采用全球广泛使用的 2.4Ghz 频率,传输速率可达 2Mbps,一次数据传输宽度可达 32 字节,其传输距离空旷地带可达2000M 此模块增强版空旷地带传输距离可达 5000M—6000M, 因内部具有 6 个数据通道,可实现 1 对 6 数据发送,还可实现 6 对 1 数据接收,其工作电压为 1.9V-3.6V,当没有数据传输时可进入低功耗模式运行,微控制器对其控制时可对数据控制引脚输入 5V 电平信号,可实现 GFSK 调制。
NRF24L01无线模块收发程序(实测成功 多图)
NRF24L01无线模块收发程序(实测成功多图)本模块是NRF24L01无线传输模块,用于无线传输数据,距离不远,一般只是能够满足小距离的传输,目测是4-5m,价格一般是4元左右,可以方便的买到。
51最小系统学习板就可以,当时是用了两块学习板,一块用于发送,一块用于接收。
小车也是比较容易购到的,四个端口控制两个电机,两个控制一个电机,当两个端口高低电平不同时电机就会转动,即为赋值1和0是电机转动,赋值可以用单片机作用,当然这是小车启动部分,前进后退左转右转就是你赋值0和1的顺序问题了。
整体思路是用发射端的按键控制小车,即为按键按下就前进,再按其他按键实现其他功能,本次程序是在用NRF24L01发射数据在接收端用1602显示的基础上改变。
下面是程序源码(有好几个文件,分别创建)////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////#include#include#include'1602.h'#include'delay.h'#include 'nrf24l01.h'#define uint unsigned int#define uchar unsigned charuint Weight_Shiwu=1234;unsigned char KeyScan(void);//键盘扫描// unsigned char KeyScan(void);//键盘扫描//#define KeyPort P0sbit KEY1 = P0^0;sbit KEY2 = P0^1;sbit KEY3 = P0^2;sbit KEY4 = P0^3;sbit KEY5 = P0^4;void main(){// char TxDate[4];// LCD_Init(); //初始化液晶屏// LCD_Clear(); //清屏// NRF24L01Int(); //初始化LCD1602// LCD_Write_String(4,0,'welcome');while(1){KeyScan();}}unsigned char KeyScan(void){/********************************************************/ char TxDate[4];{if(!KEY1) //如果检测到低电平,说明按键按下{DelayMs(10); //延时去抖,一般10-20msif(!KEY1) //再次确认按键是否按下,没有按下则退出{while(!KEY1);//如果确认按下按键等待按键释放,没有则退出{TxDate[0] = 1;//向左转TxDate[1] = 0;TxDate[2] = 1;TxDate[3] = 1;NRFSetTxMode(TxDate);//发送数据·while(CheckACK()); //检测是否发送完毕}}}/********************************************************/ else if(!KEY2) //如果检测到低电平,说明按键按下{DelayMs(10); //延时去抖,一般10-20msif(!KEY2) //再次确认按键是否按下,没有按下则退出{while(!KEY2);//如果确认按下按键等待按键释放,没有则退出{TxDate[0] = 1;//向右转TxDate[1] = 1;TxDate[2] = 1;TxDate[3] = 0;NRFSetTxMode(TxDate);//发送数据while(CheckACK()); //检测是否发送完毕}}}/********************************************************/ else if(!KEY3) //如果检测到低电平,说明按键按下{DelayMs(10); //延时去抖,一般10-20msif(!KEY3) //再次确认按键是否按下,没有按下则退出{while(!KEY3);//如果确认按下按键等待按键释放,没有则退出{TxDate[0] = 1;//前进TxDate[1] = 0;TxDate[2] = 1;TxDate[3] = 0;NRFSetTxMode(TxDate);//发送数据while(CheckACK()); //检测是否发送完毕}}}/********************************************************/ else if(!KEY4) //如果检测到低电平,说明按键按下{DelayMs(10); //延时去抖,一般10-20msif(!KEY4) //再次确认按键是否按下,没有按下则退出{while(!KEY4);//如果确认按下按键等待按键释放,没有则退出{TxDate[0] = 0;//后退TxDate[1] = 1;TxDate[2] = 0;TxDate[3] = 1;NRFSetTxMode(TxDate);//发送数据while(CheckACK()); //检测是否发送完毕}}}else if(!KEY5){DelayMs(10);if(!KEY5){while(!KEY5){TxDate[0] = 1;TxDate[1] = 1;TxDate[2] = 1;TxDate[3] = 1;NRFSetTxMode(TxDate);while(CheckACK());}}}}}////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////#include#include#include'1602.h'#include'delay.h'#include 'nrf24l01.h'#define uint unsigned int#define uchar unsigned charuint Weight;sbit a = P2^0;sbit b = P2^1;sbit c = P2^2;sbit d = P2^3;void main(){LCD_Init(); //初始化液晶屏LCD_Clear(); //清屏*(RevTempDate+4)=*\0*;NRF24L01Int();while(1){NRFSetRXMode();//设置为接收模式GetDate();//开始接受数;//Weight=RevTempDate[0]*1000+RevTempDate[1]*100+RevTempDate[2]* 10+RevTempDate[3];LCD_Write_Char(7,0,RevTempDate[0]+0x30);LCD_Write_Char(8,0,RevTempDate[1]+0x30);LCD_Write_Char(9,0,RevTempDate[2]+0x30);LCD_Write_Char(10,0,RevTempDate[3]+0x30);a = RevTempDate[0];//根据接受数据来设置高低电平(目测仅限传输1.0两种数值)b = RevTempDate[1];c = RevTempDate[2];d = RevTempDate[3];}}////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////#include#include 'nrf24l01.h'#define uchar unsigned char#define uint unsigned intsbit IRQ =P1^2;//输入sbit MISO =P1^3; //输入sbit MOSI =P1^1;//输出sbit SCLK =P1^4;//输出sbit CE =P1^5;//输出sbit CSN =P1^0;//输出uchar code TxAddr[]={0x34,0x43,0x10,0x10,0x01};//发送地址/*****************状态标志*****************************************/uchar bdata sta; //状态标志sbit RX_DR=sta^6;sbit TX_DS=sta^5;sbit MAX_RT=sta^4;/*****************SPI时序函数******************************************/uchar NRFSPI(uchar date){uchar i;for(i=0;i{if(date&0x80)MOSI=1;elseMOSI=0; // byte最高位输出到MOSIdateSCLK=1;if(MISO) // 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO 输出1位数据date|=0x01; // 读MISO到byte最低位SCLK=0; // SCK置低}return(date); // 返回读出的一字节}/**********************NRF24L01初始化函数*******************************/void NRF24L01Int(){DDelay(2);//让系统什么都不干CE=0; //待机模式1CSN=1;SCLK=0;IRQ=1;}/*****************SPI读寄存器一字节函数*********************************/uchar NRFReadReg(uchar RegAddr){uchar BackDate;CSN=0;//启动时序NRFSPI(RegAddr);//写寄存器地址BackDate=NRFSPI(0x00);//写入读寄存器指令CSN=1;return(BackDate); //返回状态}/*****************SPI写寄存器一字节函数*********************************/uchar NRFWriteReg(uchar RegAddr,uchar date){uchar BackDate;CSN=0;//启动时序BackDate=NRFSPI(RegAddr);//写入地址NRFSPI(date);//写入值return(BackDate);}/*****************SPI读取RXFIFO寄存器的值********************************/uchar NRFReadRxDate(uchar RegAddr,uchar *RxDate,uchar DateLen) { //寄存器地址//读取数据存放变量//读取数据长度//用于接收uchar BackDate,i;CSN=0;//启动时序BackDate=NRFSPI(RegAddr);//写入要读取的寄存器地址for(i=0;i{RxDate[i]=NRFSPI(0);}CSN=1;return(BackDate);}/*****************SPI写入TXFIFO寄存器的值**********************************/uchar NRFWriteTxDate(uchar RegAddr,uchar *TxDate,uchar DateLen) { //寄存器地址//写入数据存放变量//读取数据长度//用于发送uchar BackDate,i;CSN=0;BackDate=NRFSPI(RegAddr);//写入要写入寄存器的地址for(i=0;i{NRFSPI(*TxDate++);}CSN=1;return(BackDate);}/*****************NRF设置为发送模式并发送数据******************************/void NRFSetTxMode(uchar *TxDate){//发送模式NRFWriteTxDate(W_REGISTER+TX_ADDR,TxAddr,TX_ADDR_WITD H);//写寄存器指令+接收地址使能指令+接收地址+地址宽度NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WI TDH);//为了应答接收设备,接收通道0地址和发送地址相同NRFWriteTxDate(W_TX_PAYLOAD,TxDate,TX_DATA_WITDH);//写入数据/******下面有关寄存器配置**************/NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0 NRFWriteReg(W_REGISTER+SETUP_RETR,0x0a); // 自动重发延时等待250us+86us,自动重发10次NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40 NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益NRFWriteReg(W_REGISTER+CONFIG,0x0e); // CRC使能,16位CRC 校验,上电CE=1;DDelay(5);//保持10us秒以上}/*****************NRF设置为接收模式并接收数据******************************///主要接收模式void NRFSetRXMode(){CE=0;NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WI TDH); // 接收设备接收通道0使用和发送设备相同的发送地址NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0 NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40 NRFWriteReg(W_REGISTER+RX_PW_P0,TX_DATA_WITDH); // 接收通道0选择和发送通道相同有效数据宽度NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益*/NRFWriteReg(W_REGISTER+CONFIG,0x0f); // CRC使能,16位CRC 校验,上电,接收模式CE = 1;DDelay(5);//保持10us秒以上}/****************************检测应答信号******************************/uchar CheckACK(){ //用于发射sta=NRFReadReg(R_REGISTER+STATUS); // 返回状态寄存器if(TX_DS||MAX_RT) //发送完毕中断{NRFWriteReg(W_REGISTER+STATUS,0xff); // 清除TX_DS或MAX_RT中断标志CSN=0;NRFSPI(FLUSH_TX);//用于清空FIFO !!关键!!不然会出现意想不到的后果!!!大家记住!!CSN=1;return(0);}elsereturn(1);}/******************判断是否接收收到数据,接到就从RX取出*********************///用于接收模式uchar NRFRevDate(uchar *RevDate){uchar RevFlags=0;sta=NRFReadReg(R_REGISTER+STATUS);//发送数据后读取状态寄存器if(RX_DR) // 判断是否接收到数据{CE=0; //SPI使能NRFReadRxDate(R_RX_PAYLOAD,RevDate,RX_DATA_WITDH);// 从RXFIFO读取数据RevFlags=1; //读取数据完成标志}NRFWriteReg(W_REGISTER+STATUS,0xff); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标return(RevFlags);}void DDelay(uint t){uint x,y;for(x=t;x>0;x--)for(y=110;y>0;y--);}//////////////////////////////////////////////////////////////////////////////////////////////////////// #include 'delay.h'/*------------------------------------------------uS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编,大致延时长度如下T=tx2+5 uS------------------------------------------------*/void DelayUs2x(unsigned char t){while(--t);}/*------------------------------------------------mS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编------------------------------------------------*/void DelayMs(unsigned char t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}///////////////////////////////////////////////////////////////////////////////////////////下面是接收的NRF24L01的程序。
基于51单片机与nRF24L01无线门禁控制系统设计
基于51单片机与nRF24L01无线门禁控制系统设计张永宏;曹健;王丽华【期刊名称】《江苏科技大学学报(自然科学版)》【年(卷),期】2013(027)001【摘要】为了解决目前门禁系统存在的高功耗、高成本和低扩展性等问题,设计一种基于51单片机和nRF24L01无线收发芯片的低功耗无线门禁控制系统.系统由发射端和接收端组成,发送端接收、加密并发送上位机控制信号.接收端接收和解密信号并控制门禁系统.经过多次不同环境下的分组测试证明,该系统成本低,实时性好,安全性高,扩展性好,适用于不同环境下的多种小型场所.%This paper presents the hardware and software design of a low-power wireless door-guard control system based on 51 MCU and nRF24L01 wireless transceiver chip, so as to solve the current door-guard system for high power, high cost and low expansibility problems. The system consists of a sender and a receiving end. PC control signals are received, encrypted and sent by the sender. The receiving end receives and decrypts the control signals and controls the door-guard system. The result of many different environment grouping tests shows that the system is of low cost, good real-time performance, high security, good scalability and is suitable for a variety of small spaces with different environments.【总页数】6页(P64-69)【作者】张永宏;曹健;王丽华【作者单位】南京信息工程大学信息与控制学院,江苏南京,210044【正文语种】中文【中图分类】TP391.4【相关文献】1.基于Zigbee技术的无线门禁控制系统设计 [J], 张慧颖;钱同云;马淑华2.基于51单片机与nRF24L01无线测温通信系统设计 [J], 康乐为;徐丹3.基于MSP430的无线门禁控制系统设计 [J], 刘景鹏;惠玮4.基于Zigbee技术的无线门禁控制系统设计 [J], 张慧颖[1];钱同云[2];马淑华[3]5.基于STM32的无线门禁控制系统设计 [J], 刘露;李茹欣;李磊;赵德生因版权原因,仅展示原文概要,查看原文内容请购买。
基于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发送接收一体程序(以调通,解决了接收端只能接收一次的问题)/**************************************************基于单片机无线报警系统主机(机载设别)系统程序/**************************************************/#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和C8051F开发的短距离无线数据传输网络
有线网络以其可靠、高效的特点得到了广泛应用,但是有线传输的局限性也显而易见。
随着通信技术、微电子技术和嵌入式技术的飞跃发展和无线通信需求的增加,无线网络技术日渐得到普及和推广。
目前比较成熟的短距离无线数据网络技术主要有:蓝牙、Wi-Fi、超带宽技术和ZigBee技术。
但是以上技术比较复杂,而且开发成本较高,研发周期长。
在无线网络数据传输量不大的情况下,本文选用单片机加射频收发器方案组成一个无线数据传输网络。
该方案主要使用C8051F单片机和nRF24L01射频收发器件构成。
1硬件设计无线数据传传输网络主要由主控机和从机节点构成。
从机节点以C8051F410为核心,负责采集相关的数据并向主控机发送数据。
C8051F410内部集成了一个47位实时时钟,12位的AD转换器,增强型SPI接口。
利用C8051F410可以方便地组成一个数据采集模块。
nRF24L01有六个不同地址但同频的接收通道。
因此仅能扩展一对六型的星形网络。
为了方便地对每个从机节点寻址和扩展更多的网络节点,使用一片10位的拨码开关作为地址编码器。
从机节点在网络中的地址定义为拨码开关的键值。
C8051F410的SPI接口通过交叉开关设置为P2.0(SCK)、P2.1(MISO)和P2.2(MOSI)。
外部中断设置为P0.7(IRQ)。
片选设置为P2.3(CE)。
SPI片选设置为P2.4(CSN)。
从机节点结构如图1所示。
图1从机节点结构图主控机以C8051F340为核心,负责接收从机节点发送过来的数据,并将数据上传到PC机。
C8051F340内部带有4KB的RAM。
它还有可以用于访问片外存储器和存储器映射器件的外部存储器接口(EMIF)。
为了存储大容量的数据,本文中扩展了32KB的SRAM。
扩展方式采用地址/数据复用方式,P4口作为地址/数据线,P3口作为高位地址线。
各个引脚设置如下:P2.2(SCK)、P2.3(MIS-O)和P2.4(MOSI)。
无线模块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.。
nrf24l01无线通信模块与51单片机工作原理
nrf24l01无线通信模块与51单片机工作原理无线通信技术在现代社会中扮演着重要的角色,其中nrf24l01无线通信模块与51单片机也成为了无线通信的重要组成部分。
本文将探讨nrf24l01无线通信模块与51单片机的工作原理,以及它们之间的配合关系。
一、nrf24l01无线通信模块nrf24l01无线通信模块是一种低功耗的2.4GHz无线收发模块,广泛应用于物联网、无线传感器网络等领域。
其工作原理基于射频通信技术,通过无线信道进行数据的传输。
nrf24l01模块由无线收发器和嵌入式射频微控制器组成,具备高速率、长距离传输和多通道选择等特性。
1. 发射端工作原理nrf24l01发射端主要由收发器、天线和控制电路组成。
当51单片机通过SPI总线与nrf24l01通信时,可将要发送的数据通过控制电路和收发器转换成射频信号,并通过天线发送出去。
发送端的工作原理可简述为以下几个步骤:a. 初始化设置:通过配置寄存器进行初始化设置,包括工作频率、数据传输速率、天线增益等参数。
b. 数据准备与发送:将待发送的数据加载到发送缓冲区中,并通过发送指令启动数据的发送。
c. 发送前导码:在发送数据之前,发射端会先发送一段前导码作为同步信号,以确保接收端正确接收数据。
d. 数据传输与重发机制:发送端将数据以数据包的形式传输,接收端在接收到数据后会进行确认应答,发送端根据应答情况决定是否进行重发。
2. 接收端工作原理nrf24l01接收端与发送端相似,主要由收发器、天线和控制电路组成。
当发送端通过射频信号将数据发送过来时,接收端的工作原理如下:a. 初始化设置:与发送端类似,接收端也需要通过配置寄存器进行初始化设置,以匹配发送端的参数。
b. 接收与解码:接收端在接收到射频信号后,对信号进行解码,并将解码后的数据加载到接收缓冲区。
c. 数据处理与应答:通过与51单片机的交互,将接收到的数据进行处理,并向发送端发送确认应答,确保数据的可靠性。
nrf24l01无线通信模块与51单片机工作原理
nrf24l01无线通信模块与51单片机工作原理
nRF24L01是一款低功耗的2.4GHz无线通信模块,适用于微
控制器和嵌入式系统之间的短距离数据传输。
它可以与51单
片机进行配合使用。
nRF24L01模块包括一个射频发射芯片和一个射频接收芯片。
模块通过SPI接口与51单片机连接。
其工作原理如下:
1. 初始化:首先,51单片机通过SPI接口向nRF24L01模块发送配置命令,包括设置通信频率、通信通道、发射功率等参数。
2. 发送数据:当需要发送数据时,51单片机将待发送的数据
通过SPI接口发送给nRF24L01模块的发送芯片。
发送芯片将
数据转换为无线信号,并通过天线发射出去。
3. 接收数据:当有数据被接收时,nRF24L01模块的接收芯片
会把接收到的数据通过SPI接口传递给51单片机。
单片机再
根据需要对接收到的数据进行处理。
4. 确认和重传:发送芯片在发送数据后会等待接收芯片的确认信号。
如果收到确认信号,发送芯片会继续发送下一个数据包。
如果未收到确认信号,发送芯片会进行多次重传,以确保数据的可靠传输。
5. 通信协议:nRF24L01模块支持多种通信协议,如无线串口、SPI、I2C等。
可以根据需要选择合适的通信协议进行数据传输。
通过上述工作原理,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();}}}。
基于51单片机与nRF24L01无线门禁控制系统设计
基于51单片机与nRF24L01无线门禁控制系统设计1. 本文概述本文旨在探讨基于51单片机与nRF24L01无线门禁控制系统的设计。
随着科技的快速发展和智能化趋势的加强,门禁控制系统作为保障场所安全的重要手段,其设计与实现变得尤为重要。
传统的门禁系统多采用有线连接方式,布线复杂、成本较高且灵活性不足。
本文提出了一种基于51单片机与nRF24L01无线模块的门禁控制系统设计,旨在实现门禁系统的无线化、智能化和便捷化。
本文将首先介绍51单片机和nRF24L01无线模块的基本原理和特点,为后续的设计工作提供理论基础。
随后,将详细阐述系统的硬件设计,包括无线模块的选型、电路设计以及门禁控制器的实现等。
在此基础上,本文将进一步探讨软件设计的关键问题,包括无线通信协议的制定、门禁控制算法的实现以及用户界面的设计等。
通过本文的研究,旨在设计并实现一个稳定可靠、易于扩展的无线门禁控制系统,为各类场所提供高效便捷的门禁管理解决方案。
同时,本文的研究结果将为相关领域的研究人员提供有益的参考和借鉴,推动无线门禁控制技术的进一步发展。
2. 系统设计原理51单片机,作为一种经典的微控制器,其核心是基于Intel的8051架构。
它具备基本的输入输出控制能力,定时器计数器,中断系统以及一定的内存管理功能。
在本系统中,51单片机扮演着中央处理单元(CPU)的角色,负责接收传感器数据,处理输入信号,并根据预设的逻辑控制输出设备,如无线通信模块和门禁机构。
nRF24L01是一款高性能的无线传输模块,基于Nordic Semiconductor的 NRF24L01 芯片。
它工作在4GHz的ISM频段,支持点对点、点对多点的通信模式。
nRF24L01模块具有自动应答和自动重发功能,确保数据传输的可靠性。
在本系统中,nRF24L01用于无线传输门禁控制信号,包括身份验证数据和控制指令。
系统设计将51单片机和nRF24L01无线模块整合,形成一个高效、可靠的无线门禁控制系统。
基于51单片机与nRF24L01无线门禁控制系统设计
10. 3969/j. issn. 1673 -4807. 2013.01. 015基于51单片机与nRF24L01无线门禁控制系统设计 张永宏曹健王丽华南京信息工程大学信息与控制学院,江苏南京,210044摘要:为了解决目前门禁系统存在的高功耗、高成本和低扩展性等问题,设计一种基于51单片机和nRF24L01无线收发芯片的低功耗无线门禁控制系统.系统由发射端和接收端组成,发送端接收、加密并发送上位机控制信号.接收端接收和解密信号并控制门禁系统.经过多次不同环境下的分组测试证明,该系统成本低,实时性好,安全性高,扩展性好,适用于不同环境下的多种小型场所.51单片机;nRF24I01;发送端;接收端;控制信号TP391.4A1673 -4807(2013)01 -0064-06Design of wireless door guard control system based on 51 MCU and nRF24L01Zhang YonghongCao JianWang Lihua 2012-06-27江苏省“六大人才”高峰高层次人才基金资助项目(2010 -JXQC- 132);教育部留学回国人员科研启动基金(教外司留[2010]609号);江苏省“青蓝工程”中青年学术带头人基金资助项目(20101005)张永宏(1974-),男,教授,博士.研究方向为模式识别与智能系统、图像识别检测.E-mail: nuist_zyh@yahoo. com. cn充整体结}kBurstTu[7 -}、调制器、j言道工作频@@[1]向雅琴.无线门禁系统的设计与研究[D].武汉:华中 科技大学,2010:1 -85..@@[2]刘景鹏,惠玮.基于MSP430的无线门禁控制系统设 计[J].应用天地,2011,11(6):52 -55.Liu Jingpeng, Hui Wei. Wireless door control system based on MSP430[ J]. Application Notes, 2011 ,11 (6):52 -55. ( in Chinese)@@[3]许仁德.基于ZigBee技术的无线可视门禁系统的研究 与设计[D].南京:南京理工大学,2011:1 -80.@@[4]宏晶科技.STC89C51RG/RD+系列单片机中文指南 [G].深圳:宏晶科技,2005:1- 10.@@[5]郑小芹,洪健,李钟慎.基于nRF905的无线门禁系统 设计[J].过程控制科学技术与应用,2010,7(5):378 - 382.Zheng Xiaoqin, Hong Jian, Li Zhongshen. Design of wireless door-guard system based on nRF905 [ J ]. Process Control Science Technology and Applications, 2010, 7 (5) :378 -382. (in Chinese)@@[6]刘希若.无线门禁系统的设计与实现[J].科技广场, 2007,7(7):198 -201.Liu Xiruo. Wireless door-guard system design [ J ]. Science Mosaic, 2007, 7(7) :198 -201. (in Chinese)@@[7] Single chip 2.4 GHz Transceiver nRF24L01 [ R]. Eu rope:Nordic Semiconductor ASA ,2005 : 15 - 19.@@[ 8] Hee Sank John, Hakchul Jang, Jangwooh Jeon. 2.4 - GHz ISM band transceiver [ J ]. Microwave Engineering Europe,2008.5( 1 ) :2 -5.@@[9]赵轩,马健,曹仁磊,等.基于nRF24L01的无线式模型 车运动状态监控系统[J].科技导报,2010,28(2):63 -66.Zhao Xuan, Ma Jian, Cao Renlei, et al. Monitoring system of the wireless model car's motion state[J]. Science & Technology Review, 2010, 28(2):63-66. (in Chinese )@@[10]季行建,郑青.基于nRF24L01的无线监控系统的应 用与实现[J].自动化仪表,2007,5(9):112-116.Ji Xingjian, Zheng Qing. The application and implementation of Wireless monitoring system based on nRF24L01 [ J ]. Process Automation Instrumentation, 2007, 5 (9) :112- 116. (in Chinese)@@[1 1]邢文生,李希臣.一种安全的无线门禁系统及其Keil c语言实现[J].微计算机与信息,2007,8(23): 288 - 293.Xing Wensheng, Li Xichen. A safe Wireless door access system and the implementation with Keil C program [ J ]. Control & Automation, 2007, 8 ( 23 ) : 288 - 293. ( in Chinese)基于51单片机与nRF24L01无线门禁控制系统设计作者:张永宏, 曹健, 王丽华, Zhang Yonghong, Cao Jian, Wang Lihua 作者单位:南京信息工程大学信息与控制学院,江苏南京,210044刊名:江苏科技大学学报(自然科学版)英文刊名:Journal of Jiangsu University of Science and Technology年,卷(期):2013,27(1)本文链接:/Periodical_hdcbgyxy201301015.aspx。
nrf24l01无线通信模块与51单片机工作原理 -回复
nrf24l01无线通信模块与51单片机工作原理-回复nRF24L01无线通信模块与51单片机工作原理引言:随着物联网的快速发展,无线通信技术在各个领域中的应用越来越广泛。
而在无线通信领域中,nRF24L01无线通信模块和51单片机成为了常见的组合。
本文将详细介绍nRF24L01和51单片机的工作原理及其之间的通信过程。
第一部分:nRF24L01无线通信模块的工作原理nRF24L01是一款低功耗的单片机无线通信模块,广泛应用于无线传感器网络、智能家居等领域。
其工作原理可以分为硬件和软件两个方面。
硬件方面,nRF24L01模块由射频前端及基带部分两个主要部分组成。
射频前端部分包括射频收发器和RF增益模块,用于接收和发送射频信号。
基带部分包含SPI接口、调制解调器和数据缓存区,用于控制数据的传输及处理。
软件方面,nRF24L01模块的工作需要通过使用专用的库函数进行驱动。
这些库函数可以在编程环境中调用,以实现nRF24L01模块的相应功能。
软件通过SPI接口与模块进行通信,并通过设置寄存器、发送命令和接收状态等方式控制模块的工作。
第二部分:51单片机的工作原理51单片机,全称为AT89C51,是一种典型的8051架构的单片机。
在无线通信系统中,51单片机通常作为主控芯片,通过与nRF24L01模块进行交互,实现与其他设备的无线通信。
51单片机的工作原理主要包括四个方面:时钟与计时、IO口控制、中断系统和串行通信。
时钟与计时:51单片机内部由一个双字节的定时器/计数器组成,用于提供计时和延时功能。
通过设置计时器的时钟源和分频系数,可以实现不同频率和精度的计时与延时。
IO口控制:51单片机的IO口主要用于与其他设备进行数据交互。
通过设置相应的寄存器,可以控制IO口的输入输出、上拉电阻和工作模式等。
中断系统:51单片机内部集成了中断控制器,可以通过设置中断优先级和中断源等参数,实现对不同事件的响应。
在无线通信系统中,可以通过中断来处理接收数据、发送完成等事件。
nRF24l01无线模块 发送端程序for 51单片机
#define Data P0//数据端口
//=============================================================================================
#define MODE 0//MODE=1时为发送代码 为0则是接受代码
#define uchar unsigned char
#define RX_ADR_WIDTH 5
#define TX_ADR_WIDTH 5 // 5 bytes TX(RX) address width
#define TX_PLOAD_WIDTH 1 // 20 bytes TX payload
/******************************************************************/
void WriteCommand(unsigned char c)
{
DelayMs(5);//操作前短暂延时,保证信号稳定
E=0;
RS=0;
RW=0;
/* 写入字符串函数 */
/******************************************************************/
void ShowString (unsigned char line,char *ptr)
char data TimeNum[]=" ";
/******************************************************************/
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模块与单片机的通信方式1.基于SPI通信协议的数据交换nRF24L01模块与单片机基于SPI通信协议进行数据交换。
SPI是一种同步串行通信协议,它通过四个信号线进行通信:MOSI、MISO、SCK和CSN。
在这四个信号线中,MOSI用于发送数据,MISO用于接收数据,SCK用于同步时钟信号,而CSN用于片选信号。
这种通信方式具有传输速度快、数据稳定性高、抗干扰能力强等优点。
2.控制引脚与SPI通信引脚的配置nRF24L01模块的控制引脚包括CE、CSN、IRQ,这些引脚可用于控制模块的开启、关闭以及接收中断等功能。
SPI通信引脚包括MOSI、MISO、SCK,这些引脚可用于实现与单片机之间的数据传输。
值得注意的是,这些引脚可以直接接普通的IO口,而不必特意选择SPI外设对应的引脚。
二、nRF24L01模块的应用场景1. 一对多通信当有两个以上的nRF无线模块且代码中未设置SPI片选信号时,可以实现一对多通信(即一个发多个收到该信息)。
这种通信方式在需要多个接收方的情况下非常实用,可以有效提高通信效率,降低系统成本。
2.多种通信模式的选择nRF24L01模块支持多种通信模式,如广播模式、多路复用模式等。
用户可以根据实际需求选择合适的通信模式,以满足不同场景下的应用要求。
3.远程控制与监测nRF24L01模块可应用于远程控制与监测领域,如智能家居、工业自动化、智能交通等。
通过无线通信,可以实现远程控制设备的开关、调节参数以及实时监测设备状态等功能。
4.数据传输与存储nRF24L01模块还可应用于数据传输与存储领域,如物联网、传感器网络等。
在这些场景下,nRF24L01模块可以实现传感器数据的实时采集、传输和存储,为用户提供便捷的数据处理方案。
nRF24L01模块与单片机的通信方式在实际应用中具有广泛的应用价值,可以为各类工程项目提供可靠的无线通信解决方案。
基于51单片机和NRF24L01的无线温度监控
基于51单片机和NRF24L01的无线温度监控一丶实现功能:以51单片机为核心实现智能化远程无线温度监控。
利用18B20温度传感器获取温度信号,将需要测量的温度信号自动转化为数字信号,通过无线模块NRF24L01一对一传送将数据传送到接收机,最终单片机将信号转换成LCD可以识别的信息显示输出。
二丶所需原件:51单片机*2DS18B20*1 (温度测量范围为-55~+125^C)12M晶振*222uf电容*25V降压至3.3V降压模块*2NRF24101无线模块*21602液晶显示屏*1按键*3蜂鸣器*1发光二极管*1排阻10K*9脚*2四丶NRF12401JI介绍:1、GFSK调制,硬件集成OSI链路层;2、具有自动应答和自动再发射功能;3、片内自动生成报头和CRC校验码;4、数据传输率为l Mb/s或2Mb/s;5、SPI速率为0 Mb/s~10 Mb/s;6、125个频道与其他nRF24系列射频器件相兼容;7、QFN20引脚4 mm×4 mm封装;8、供电电压为1.9 V~3.6 V;封装引脚介绍:CE:使能发射或接收;CSN,SCK,MOSI,MISO:SPI引脚端,微处理器可通过此引脚配置nRF24L01:IRQ:中断标志位;VDD:电源输入端;VSS:电源地;XC2,XC1:晶体振荡器引脚;V D D_P A:为功率放大器供电,输出为1.8 V;ANT1,ANT2:天线接口;IREF:参考电流输入;工作模式:工作原理:发射数据时,首先将nRF24L01配置为发射模式:接着把接收节点地址TX_ADDR 和有效数据TX_PLD按照时序由S P I口写入nRF24L01缓存区,TX_PLD必须在CSN 为低时连续写入,而TX_ADDR在发射时写入一次即可,然后CE置为高电平并保持至少10μs,延迟130μs后发射数据;若自动应答开启,那么nRF24L01在发射数据后立即进入接收模式,接收应答信号(自动应答接收地址应该与接收节点地址TX_ADDR一致)。
基于51单片机与nRF24L01无线测温通信系统设计
基于51单片机与nRF24L01无线测温通信系统设计作者:康乐为徐丹来源:《卷宗》2015年第10期摘要:文章将51单片机和nRF24L01技术有机结合起来,组成无线远程测温通信系统。
系统由51单片机,DS18D20温度采集模块,LCD温度数据显示模块,nRF24L01无线数据收发模块组成。
具有实现无线数据传输可靠稳定,低功耗,编程简单等特点。
实践证明该系统能适应于多种环境温度的检测。
关键词:nRF24L01;温度检测;无线通信;单片机目前,无线通信领域越来越广,如:wifi,蓝牙,安全防火系统,水产养殖系统,智能家居系统等等。
凡是布线复杂或者不能布线的场合都希望通过无线方案解决。
为此需要设计相应的接口系统,完成系统数据交互,实现系统控制功能等。
本系统采用了DS18D20温度采集模块及Nordic公司新推出的工作于2.4GHz频段的nRF24L01射频芯片,并由超低功耗单片机控制实现短距离无线数据通信,打破了传统操作中距离受限的问题,使测温操作更易实现。
系统框图如图1:nRF24L01是一款工作在2.4~2.5GHz世界通用ISM频段的单片无线收发器芯片,其工作速率为0~2Mb/s,最大发射功率为0dBm,其外围元件极少,内置硬件CRC(循环冗余校验)和点对多点通信地址控制,集成了频率合成器,晶体振荡器和调制解调器.它的主要特点如下:1)低工作电压:1.9~3.6V低电压工作;2)高速率:2Mbps,由于空中传输时间很短,极大地降低了无线传输中的碰撞现象;3)多频点:125频点,满足多点通信和跳频通信需要;4)超小型:体积小巧,5mm 5mm;5)低功耗:当工作在发射模式时,发射功率为-6dBm,电流消耗为9mA,接收模式为12.3mA,掉电模式和待机模式下电流消耗更低。
6)低应用成本:nRF24L01的SPI接口可以利用单片机的硬件SPI口连接或用单片机I/O 口进行模拟,内部有FIFO可以与各种高低速微处理器接口,便于使用低成本单片机.nRF24L01芯片最突出的特点是有2种通信模式:DirectMode(直接模式)和ShockBurstMode(突发模式).直接模式的使用与其他传统射频收发器的工作一样,需要通过软件在发送端添加校验码和地址码,在接收端判断是否为本机地址并检查数据是否传输正确.ShockBurstMode使用芯片内部的先入先出堆栈区,数据可从低速微控制器送入,高速(2Mb/s)发射出去,地址和校验码硬件自动添加和去除,这种模式的优点是:可使用低速微控制器控制芯片工作;‚减小功耗;ƒ射频信号高速发射,抗干扰性强;减小整个系统的平均电流.因此,使用nRF24L01芯片特有的ShockBurstMode使得系统整体的性能和效率提高。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
uint status;
CSN = 0; // CSN low, init SPI transaction
status = SPI_RW(reg); // select register
SPI_RW(value); // ..and write value to it..
#define TX_PLOAD_WIDTH 1 // 20 uints TX payload
#define RX_PLOAD_WIDTH 1 // 20 uints TX payload
uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址
#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 EN_RXADDR 0x02 // 可用信道设置
#define SETUP_AW 0x03 // 收发地址宽度设设置
#define RF_CH 0x05 // 工作频率设置
#define RD_RX_PLOAD 0x61 // 读取接收数据指令
#define WR_TX_PLOAD 0xA0 // 写待发数据指令
#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令
#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令
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_();
}
void init_NRF24L01(void)
{
#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令
#define NOP 0xFF // 保留
#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA 0x01 // 自动应答功能设置
#define RX_PW_P5 0x16 // 接收频道0接收数据长度
#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置
void Delay(unsigned int s);
void inerDelay_us(unsigned char n);
CSN = 1; // CSN high again
return(status); // return nRF24L01 status uchar
}
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH);
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); //CE=1; //
#include <reg52.h>
#include <intrins.h>
typedef unsigned char uchar;
typedef unsigned char uint;
sbit CE =P1^1;
sbit CSN =P1^2;
sbit SCK =P1^3;
if(a==100)a=0;
*TxBuf2=a; a++;
nRF24L01_TxPacket(TxBuf2);
}
}
}
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 MOSI
#define RF_SETUP 0x06 // 发射速率、功耗功能设置
#define STATUS 0x07 // 状态寄存器
#define OBSERVE_TX 0x08 // 发送监测功能
#define CD 0x09 // 地址检测
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...
SPI_RW_Reg(WRITE_REG + RF_CH, 0);
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm, Datarate:1Mbps,
sbit MOSI =P1^4;
sbit MISO =P1^5;
sbit IRQ =P1^6;
uchar TxBuf2[1]={0};
#define TX_ADR_WIDTH 5 // 5 uints TX address width
#define RX_ADR_WIDTH 5 // 5 uints RX address width
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
SPI_RW_Reg(WRITE_REG + SETUP_AW, 0x02); // Setup address width=5 bytes
inerDelay_us(10);CE=0;SPI_RW_Reg(WRITE_REG+STATUS,0XFF);
}
void main(void)
{
uchar a=0;
init_NRF24L01() ;
Delay(6000);
while(1)
{
Delay(1000);
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
CE=1; //置高CE,激发数据发送
CSN = 1; //关闭SPI
return(status); //
}
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
CE=0; //StandBy I模式
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
SCK = 0; // ..then set SCK low again
}
return(uchar); // return read uchar
}
uint SPI_RW_Reg(uchar reg, uchar value)
inerDelay_us(100);
CE=0; // chip enable
CSN=1; // Spi disable
SCK=0;
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // Set PWR_UP bit, enable CRC(2 bytes) &
#define RX_ADDR_P0 0x0A // 频道0接收数据地址
#define RX_ADDR_P1 0x0B // 频道1接收数据地址
#define RX_ADDR_P2 0x0C // 频道2接收数据地址
#define RX_ADDR_P3 0x0D // 频道3接收数据地址
uchar = (uchar << 1); // shift next bit into MSB..
SCK = 1; // Set SCK high..
uchar |= MISO; // capture current MISO bit
uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
#define READ_REG 0x00 // 读寄存器指令
#define WRITE_REG 0x20 // 写寄存器指令
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; //状态标志