51控制NRF24L01程序

合集下载

基于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;// }}}。

51单片机应用之无线通讯模块NRF24L01+

51单片机应用之无线通讯模块NRF24L01+

30、51单片机应用之............无线通讯模块NRF24L01+(一)基础知识篇
今天刚调试好,先看图吧!这张是AT89C2051控制NRF24L01+做发射调试。

看看NRF24L01细节吧!
这是LCD屏显示:
AT89S52做接收测试:
正在接收时的显示:
接收到数据后显示32个数据值:
无线模块NRF24L01+应用上篇结束,敬请期待NRF24L01+下篇的调试部分。

31、51单片机应用之............无线通讯模块NRF24L01+(二)模块调试篇
32、51单片机应用之............无线通讯模块NRF24L01+(三)发送与接收模块的联调
33、51单片机应用之............无线通讯模块NRF24L01+(四)举例应用
34、补充NRF24L01+之————LED调试篇
写了前面四篇关于NRF24L01通讯调试的文章,看来大家还是很喜欢,有帮助的。

有很多大学生朋友问我说,我们没有两个LCD来显示调试状态,连一个也没有,能不能用几个LED来显示调试状态呢?因此我就写这篇补充调试的文章,就用P0口的8个LED来显示调试NRF24L01到成功进行数据通讯。

先把51单片机的最小系统准备好,还有8个LED的小电路板,如果你的LED就在系统板上那省了这一步。

8个LED的小板子电路很简单,但你焊接要可靠,不然电路本身都不稳定,后面对判断故障会产生很大影响。

NRF24L01+模块电路还是前面说过的那样:
相同的两个模块的板子。

nRF24L01测试程序_51单片机

nRF24L01测试程序_51单片机
#define FIFO_STATUS 0x17 // 'FIFO Status Register' register address //------------------------------------------------------------
// 写一个字节到24L01,同时读出一个字节
SCK = 1; // Set SCK high..
byte |= MISO; // capture current MISO bit
SCK = 0; // ..then set SCK low again
}
return(byte); // return read byte
}
// 向寄存器reg写一个字节,同时返回状态字节
{
CE = 0; // stand by mode
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);// clear RX_DR or TX_DS or MAX_RT interrupt flag
SPI_RW(value); // ..and write value to it..
CSN = 1; // CSN high again
return(status); // return nRF24L01 status byte
}
// 读出bytes字节的数据
uchar SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)

无线模块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.。

nrf24l01发送接收一体程序(以调通-解决了接收端只能接收一次的问题)

nrf24l01发送接收一体程序(以调通-解决了接收端只能接收一次的问题)
uchar flag; //无线模块接受数据标志
uchar DATA = 0x01;
uchar bdata sta;
unsigned int a,k; //定时器延时参数
uchar mark; //传感器响应标志位
uchar mark1;//延时标志位
sbit RX_DR= sta^6;//接受数据成功标志位
描述:
语音模块发送地址信号
/**************************************************/
void sendadd(unsigned char addr)
{
uchar i;
SDA=0;
delayms(5);/*数据信号置于低电平5ms */
for(i=0;i<8;i++)
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; //语音模块数据控制端
{
uchar status, i;
CSN = 0; // CSN置低,开始传输数据
status = SPI_RW(reg); //选择寄存器,同时返回状态字
for(i=0; i<bytes; i++)
SPI_RW(pBuf[i]); //逐个字节写入nRF24L01
CSN = 1; // CSN拉高,结束数据传输
{ SDA=1;
if(addr & 1)

nrf24l01无线通信模块与51单片机工作原理

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无线通信模块与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单片机

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();}}}。

MSP430G2553(51单片机)_NRF24L01无线模块接收程序

MSP430G2553(51单片机)_NRF24L01无线模块接收程序
************************************************************************************* * 函数:init_IO_MSP430() * 描述:NRF24L01初始化 * 参数:无 * 返回:无 ****************************************************************************************************/ void init_IO_MSP430() { P1DIR|=BIT0+BIT3+BIT4+BIT5; P1DIR&=~BIT6; P1DIR&=~BIT7; P2DIR|=BIT2; P2OUT&=~BIT2; } /**************************************************************************************************** * 函数:void init_NRF24L01() * 描述:NRF24L01初始化 * 参数:无 * 返回:无 ****************************************************************************************************/ void init_NRF24L01() { delayus(100); CE_0; // 片选使能 CSN_1; // SPI使能 SCK_0; // SPI时钟拉低 SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址 SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址 SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); //通道0自动应答 SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); //允许接收地址频道0 //SPI_RW_Reg(WRITE_REG+SETUP_AW,0x02);//Setup address width = 5bytes SPI_RW_Reg(WRITE_REG+SETUP_RETR,0x1a); //设置自动重发时间和次数:500us + 86us, 10 retrans... SPI_RW_Reg(WRITE_REG + RF_CH, 0x32); //设置信道工作频率,收发必须一致 SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度 SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0f); //设置发射速率为2MHZ,发射功率为最大值0dB SPI_RW_Reg(WRITE_REG + CONFIG, 0x7c); //IRQ引脚不显示中断 掉电模式 1~16CRC校验 } /**************************************************************************************************** * 函数:uchar SPI_RW(uchar data) * 描述:SPI读/写一个字节数据 * 参数:要写入的数据(uchar) * 返回:读取到的数据(uchar) ****************************************************************************************************/ uchar SPI_RW(uchar data) { char i,temp=0; for(i=0;i<8;i++) // output 8-bit { if((data & 0x80)==0x80) MOSI_1; // output 'uchar', MSB to MOSI else MOSI_0;

nrf24l01的51驱动程序

nrf24l01的51驱动程序
//******************************************************************************************
#endif
//-----------------------nrf24l01.h结束------------------------------
#define EN_AA 0x01 // 自动应答功能设置
#define EN_RXADDR 0x02 // 可用信道设置
#define SETUP_AW 0x03 // 收发地址宽度设置
#define SETUP_RETR 0x04 // 自动重发功能设
//---------------------nrf24l01.h----------------------------
#ifndef NRF24L01_H
#define NRF24L01_H
#include <reg52.h>
//模式选择
//#define RMODE
#define TMODE
#define RF_CH 0x05 // 工作频率设置
#define RF_SETUP 0x06 // 发射速率、功耗功能设置
#define STATUS 0x07 // 状态寄存器
#define OBSERVE_TX 0x08 // 发送监测功能
#define RX_ADDR_P3 0x0D // 频道3接收数据地址
#define RX_ADDR_P4 0x0E // 频道4接收数据地址
#define RX_ADDR_P5 0x0F // 频道5接收数据地址

基于51单片机与nRF24L01无线门禁控制系统设计

基于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无线门禁控制系统设计

基于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无线模块 发送端程序for 51单片机

nRF24l01无线模块 发送端程序for 51单片机
sbit E = P2^6; //Pin6
#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无线串口开发板程序详解

1.源程序开发环境建立1.1程序编译软件编译软件用keil C51,打开安装文件,一路点击下一步即可完成。

1.2程序下载软件使用STC ISP下载软件。

2.源程序文件整体结构工程中,只有一个main.c文件,所有程序都写在这个文件里面。

Reg51.h是包含的头文件。

是不是非常简单!3.源程序执行流程无线数据处理程序:串口数据处理程序:4.串口配置函数void serial_open(void){SCON = 0X50;AUXR |= 0X04;TL2 = 0Xc0; // 9600TH2 = 0Xfd;AUXR|=0X10;}此串口配置函数,利用单片机内部的定时器2作为波特率发生器。

共用到4个寄存器:SCON AUXR TL2 TH2SM0和SM1的位决定串口工作的4种方式:程序中,SCON=0X50,即SM0=0 SM1=1,即串口工作在“方式1”;REN=1,允许串口接收数据。

TL2和TH2是定时器2的高位和低位寄存器。

程序中,首先AUXR|=0X40,最后AUXR|=0X10。

即首先把T2x12置1,然后把T2R置1。

即首先把定时器2设置为1T模式,然后把定时器打开。

5.串口发送数据函数void senddata(uchar data_buf){SBUF = data_buf;while(!TI);TI = 0;}用到了寄存器SBUF和寄存器SCON中的TI位。

SBUF寄存器是串口收发数据缓存寄存器,放到这个寄存器中的数据,会通过串口发送出去,接收到的串口数据,也会放到这个寄存器中。

也就是串口接收和发送都是使用这个寄存器。

程序中,SBUF=data_buf,就是把data_buf给了SBUF,单片机自动把SBUF里面的数据发送到串口。

TI是串口发送数据完成标志位,当串口发送完一个数据,此位置1,置位后,需要通过软件清0。

所以通过while(!TI),来检测TI位,达到检测串口是否发送完数据的目的。

51 系列 nRF24L01代码

51 系列 nRF24L01代码

#include <reg51.h>#include <intrins.h>#include "api.h"/**This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTYT;**uart:9600BPS苏州天铱电子免费代码公布****************** 官方网址: * 官方论坛: /bbs*******************TY Tech*****bai chun yu *****qq:472230383 328997835 *****Email:baichunyu1232000@ *******************//***************************************************/#define uchar unsigned char#define TX_ADR_WIDTH 5 // 5 bytes TX(RX) address width#define TX_PLOAD_WIDTH 20 // 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];uchar flag;/**************************************************/sbit CE = P1^0;sbit CSN= P1^1;sbit SCK= P1^2;sbit MOSI= P1^3;sbit MISO= P1^4;sbit IRQ = P1^5;/**************************************************/uchar bdata sta;sbit RX_DR=sta^6;sbit TX_DS=sta^5;sbit MAX_RT=sta^4;/**************************************************//**************************************************Function: init_io();Description:flash led one time,chip enable(ready to TX or RX Mode),Spi disable,Spi clock line init high/**************************************************/#define KEY 0xaavoid init_io(void){P0=KEY;// led lightCE=0;// chip enableCSN=1;// Spi disableSCK=0;// Spi clock line init highP0=0xff;// led close}/**************************************************//**************************************************Function: Inituart();Description:set uart working mode/**************************************************/void Inituart(void){TMOD = 0x20;//timer1 working mode 1TL1 = 0xfd;//f7=9600 for 16mhz Fosc,and ...TH1 = 0xfd;//...fd=19200 for 11.0592mhz FoscSCON = 0xd8;//uart mode 3,ren==1PCON = 0x80;//smod=0TR1 = 1;//start timer1}/**************************************************//**************************************************Function: init_int0();Description:enable int0 interrupt;/**************************************************/void init_int0(void){EA=1;EX0=1;// Enable int0 interrupt. }/**************************************************//**************************************************Function: delay100();Description:delay 100ms/**************************************************void delay(uchar ){uchar x;uchar y;for(x=0;x<100;x++){for(y=0;y<100;y++)_nop_();}}/**************************************************/void delay_ms(unsigned int x){unsigned int i,j;i=0;for(i=0;i<x;i++){j=108;;while(j--);}}/**************************************************//**************************************************Function: SPI_RW();Description:Writes one byte to nRF24L01, and return the byte readfrom nRF24L01 during write, according to SPI protocol/**************************************************/uchar SPI_RW(uchar byte){uchar bit_ctr;for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit{MOSI = (byte & 0x80); // output 'byte', MSB to MOSIbyte = (byte << 1); // shift next bit into MSB..SCK = 1; // Set SCK high..byte |= MISO; // capture current MISO bitSCK = 0; // ..then set SCK low again }return(byte); // return read byte}/**************************************************//**************************************************Function: SPI_RW_Reg();Description:Writes value 'value' to register 'reg'/**************************************************/uchar SPI_RW_Reg(BYTE reg, BYTE 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 byte}/**************************************************//**************************************************Function: SPI_Read();Description:Read one byte from nRF24L01 register, 'reg'/**************************************************/BYTE SPI_Read(BYTE reg){BYTE 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}/**************************************************//**************************************************Function: SPI_Read_Buf();Description:Reads 'bytes' #of bytes from register 'reg'Typically used to read RX payload, Rx/Tx address/**************************************************/uchar SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes){uchar status,byte_ctr;CSN = 0; // Set CSN low, init SPI tranactionstatus = SPI_RW(reg); // Select register to write to and read status byte for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)pBuf[byte_ctr] = SPI_RW(0); // Perform SPI_RW to read byte from nRF24L01CSN = 1; // Set CSN high againreturn(status); // return nRF24L01 status byte}/**************************************************//**************************************************Function: SPI_Write_Buf();Description:Writes contents of buffer '*pBuf' to nRF24L01Typically used to write TX payload, Rx/Tx address/**************************************************/uchar SPI_Write_Buf(BYTE reg, BYTE *pBuf, BYTE bytes){uchar status,byte_ctr;CSN = 0; // Set CSN low, init SPI tranactionstatus = SPI_RW(reg); // Select register to write to and read status bytefor(byte_ctr=0; byte_ctr<bytes; byte_ctr++) // then write all byte in buffer(*pBuf)SPI_RW(*pBuf++);CSN = 1; // Set CSN high againreturn(status); // return nRF24L01 status byte}/**************************************************//**************************************************Function: RX_Mode();Description:This function initializes one nRF24L01 device toRX Mode, set RX address, writes RX payload width,select RF channel, datarate & LNA HCURR.After init, CE is toggled high, which means thatthis device is now ready to receive a datapacket./**************************************************/void RX_Mode(void){CE=0;SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // Use the same address on the RX device as the TXdeviceSPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // Select same RX payload width as TX Payload widthSPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURRSPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // Set PWR_UP bit, enable CRC(2 bytes) & Prim:RX. RX_DR enabled..CE = 1; // Set CE pin high to enable RX device// This device is now ready to receive one packet of 16 bytes payload from a TX device sending to address// '3443101001', with auto acknowledgment, retransmit count of 10, RF channel 40 and datarate = 2Mbps.}/**************************************************//**************************************************Function: TX_Mode();Description:This function initializes one nRF24L01 device toTX mode, set TX address, set RX address for auto.ack,fill TX payload, select RF channel, datarate & TX pwr.PWR_UP is set, CRC(2 bytes) is enabled, & PRIM:TX.ToDo: One high pulse(>10us) on CE will now send thispacket and expext an acknowledgment from the RX device./**************************************************/void TX_Mode(void){CE=0;SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // Writes TX_Address to nRF24L01 SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.AckSPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // Writes data to TX payloadSPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURRSPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // Set PWR_UP bit, enable CRC(2 bytes) & Prim:TX.MAX_RT & TX_DS enabled..CE=1;}/**************************************************//**************************************************Function: check_ACK();Description:check if have "Data sent TX FIFO interrupt",if TX_DS=1,all led light and after delay 100ms all led close/**************************************************void check_ACK(){uchar test;test=SPI_Read(READ_REG+STATUS);// read register STATUS'stest=test&0x20;// check if have Data sent TX FIFO interrupt (TX_DS=1)if(test==0x20)// TX_DS =1{P0=0x00;// turn on all leddelay100();// delay 100msP0=0xff;}}/**************************************************//**************************************************Function: TxData();Description:write data x to SBUF/**************************************************/void TxData (uchar x){SBUF=x;// write data x to SBUFwhile(TI==0);TI=0;}/**************************************************//**************************************************Function: CheckButtons();Description:check buttons ,if have press,read the key values,turn on led and transmit it; after transmition,if received ACK, clear TX_DS interrupt and enter RX Mode;turn off the led/**************************************************/void CheckButtons(){uchar Temp,xx,Tempi;P0=0xff;Temp=P0&KEY; //read key value from port P0if (Temp!=KEY){delay_ms(10);Temp=P0&KEY;// read key value from port P0if (Temp!=KEY){xx=Temp;Tempi=Temp>>1;// Left shift 4 bitsP0=Tempi; // Turn On the ledtx_buf[0]=Tempi;// Save to tx_buf[0]TX_Mode();// set TX Mode and transmittingTxData(xx);// send data to uart//check_ACK();// if have acknowledgment from RX device,turn on all ledSPI_RW_Reg(WRITE_REG+STATUS,SPI_Read(READ_REG+STATUS));// clear interrupt flag(TX_DS)delay_ms(500);P0=0xff;// Turn off the ledRX_Mode();// set receive modewhile((P0&KEY)!=KEY);}}}/**************************************************//**************************************************Function: main();Description:control all subprogrammes;/**************************************************/void main(void){89LV51.Cuchar xx;init_io();// Initialize IO portInituart();// initialize 232 uart//init_int0();// enable int0 interruptRX_Mode();// set RX modewhile(1){CheckButtons(); // scan key value and transmitsta=SPI_Read(STATUS);// read register STATUS's valueif(RX_DR)// if receive data ready (RX_DR) interrupt{SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO bufferflag=1;}if(MAX_RT){SPI_RW_Reg(FLUSH_TX,0);}SPI_RW_Reg(WRITE_REG+STATUS,sta);// clear RX_DR or TX_DS or MAX_RT interrupt flagif(flag)// finish received{flag=0;//set flag=0P0=rx_buf[0];// turn on leddelay_ms(500);P0=0xff;// turn off ledxx=rx_buf[0]>>1;// right shift 4 bitsTxData(xx);// send data to uart}}}/**************************************************//**************************************************Function: ISR_int0() interrupt 0;Description:if RX_DR=1 or TX_DS or MAX_RT=1,enter this subprogram;if RX_DR=1,read the payload from RX_FIFO and set flag;/**************************************************/void ISR_int0(void) interrupt 0{sta=SPI_Read(STATUS);// read register STATUS's valueif(RX_DR)// if receive data ready (RX_DR) interrupt{SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO bufferflag=1;}if(MAX_RT){SPI_RW_Reg(FLUSH_TX,0);}SPI_RW_Reg(WRITE_REG+STATUS,sta);// clear RX_DR or TX_DS or MAX_RT interrupt flag}/**************************************************/。

Nrf24L01程序==

Nrf24L01程序==

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

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

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

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

下面是程序源码(有好几个文件,分别创建)//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#include<reg52.h>#include<stdio.h>#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<reg52.h>#include<stdio.h>#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<reg52.h>#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<8;i++) // 循环8次{if(date&0x80)MOSI=1;elseMOSI=0; // byte最高位输出到MOSIdate<<=1; // 低一位移位到最高位SCLK=1;if(MISO) // 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据date|=0x01; // 读MISO到byte最低位SCLK=0; // SCK置低}return(date); // 返回读出的一字节}/**********************NRF24L01初始化函数*******************************/void NRF24L01Int(){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);//写入值CSN=1;return(BackDate);}/*****************SPI读取RXFIFO寄存器的值********************************/ uchar NRFReadRxDate(uchar RegAddr,uchar *RxDate,uchar DateLen){ //寄存器地址//读取数据存放变量//读取数据长度//用于接收uchar BackDate,i;CSN=0;//启动时序BackDate=NRFSPI(RegAddr);//写入要读取的寄存器地址for(i=0;i<DateLen;i++) //读取数据{RxDate[i]=NRFSPI(0);}CSN=1;return(BackDate);}/*****************SPI写入TXFIFO寄存器的值**********************************/ uchar NRFWriteTxDate(uchar RegAddr,uchar *TxDate,uchar DateLen){ //寄存器地址//写入数据存放变量//读取数据长度//用于发送uchar BackDate,i;CSN=0;BackDate=NRFSPI(RegAddr);//写入要写入寄存器的地址for(i=0;i<DateLen;i++)//写入数据{NRFSPI(*TxDate++);}CSN=1;return(BackDate);}/*****************NRF设置为发送模式并发送数据******************************/ void NRFSetTxMode(uchar *TxDate){//发送模式CE=0;NRFWriteTxDate(W_REGISTER+TX_ADDR,TxAddr,TX_ADDR_WITDH);//写寄存器指令+接收地址使能指令+接收地址+地址宽度NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH);//为了应答接收设备,接收通道0地址和发送地址相同NRFWriteTxDate(W_TX_PAYLOAD,TxDate,TX_DA TA_WITDH);//写入数据/******下面有关寄存器配置**************/NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0NRFWriteReg(W_REGISTER+SETUP_RETR,0x0a); // 自动重发延时等待250us+86us,自动重发10次NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益NRFWriteReg(W_REGISTER+CONFIG,0x0e); // CRC使能,16位CRC校验,上电CE=1;DDelay(5);//保持10us秒以上}/*****************NRF设置为接收模式并接收数据******************************/ //主要接收模式void NRFSetRXMode(){CE=0;NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH); // 接收设备接收通道0使用和发送设备相同的发送地址NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40NRFWriteReg(W_REGISTER+RX_PW_P0,TX_DATA_WITDH); // 接收通道0选择和发送通道相同有效数据宽度NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益*/NRFWriteReg(W_REGISTER+CONFIG,0x0f); // CRC使能,16位CRC校验,上电,接收模式CE = 1;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无线测温通信系统设计

基于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. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
};
code uchar RxBuf[32]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
#define CD 0x09 // 地址检测
#define RX_ADDR_P0 0x0A // 频道0接收数据地址
#define RX_ADDR_P1 0x0B // 频道1接收数据地址
#define RX_ADDR_P2 0x0C // 频道2接收数据地址
描述:定时器0初始化程序
*****************************************************************************************/
void InitTimer(void)
{
TMOD = 0x21; //定时器1工作方式2,定时器0工作方式1
0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,
0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,
};
uchar dis_buf[2]={0x00,0x00}; //显示数组
code uchar LED7Code[]={
#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 REUSE_TX_PL 0xE3 // 定义重复装载数据指令
#define NOP 0xFF // 保留
/***SPI(nRF24L01)寄存器地址***/
#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes); //从寄存器reg读出bytes个字节,通常用来读取接收通道数据或发送地址
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes);//把pBuf缓存中的数据写入到nRF24L01,通常用来写入发射通道数据或接收/发送地址
#define RX_ADDR_P3 0x0D // 频道3接收数据地址
#define RX_ADDR_P4 0x0E // 频道4接收数据地址
#define RX_ADDR_P5 0x0F // 频道5接收数据地址
#define TX_ADDR 0x10 // 发送地址寄存器
函数:void Delay(uint s)
描述:
**********************************************************************/
void Delayms(uint s)
{
unsigned int i,j;
for(i=0; i<s; i++);
uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
/***NRF24L01寄存器指令***/
#define READ_REG 0x00 // 读寄存器指令
#define WRITE_REG 0x20 // 写寄存器指令
/***以下为接收***/
#include <REGX52.H>
#include <INTRINS.H> //for funtion _NOP_
#include <STDIO.H>
/***自定义数据类型声明***/
typedef unsigned char uchar;
typedef unsigned int uint;
#define RD_RX_PLOAD 0x61 // 读取接收数据指令
#define WR_TX_PLOAD 0xA0 // 写待发数据指令
#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令
#define FLUSH_RX 0xE2 // 冲洗,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,
0xC0, // 0
0xF9, // 1
0xA4, // 2
0xB0, // 3
0x99, // 4
0x92, // 5
0x82, // 6
0xF8, // 7
0x80, // 8
0x90, // 9
0x88, // A
0x83, // B
0xC6, // C
#define TIMER0H (65535-SCAN_CYCLE)/256
#define TIMER0L (65535-SCAN_CYCLE)%256 //定时3MSVR3*FOSC/12/1000
/***I/O口定义***/
sbit MISO =P1^6;
sbit MOSI =P1^5;
TH0 = TIMER0H; //设定T0每隔SCAN_CYCLE us中断一次
#define RF_CH 0x05 // 工作频率设置
#define RF_SETUP 0x06 // 发射速率、功耗功能设置
#define STATUS 0x07 // 状态寄存器
#define OBSERVE_TX 0x08 // 发送监测功能
void InitTimer(void);
void InitUART(void);
void InitNRF24L01(void);
void SetRXMode(void);
uchar SPI_RW(uchar); //NRF24L01的SPI写时序;写一个字节到24l01,同时读出一个字节
#define EN_AA 0x01 // 自动应答功能设置
#define EN_RXADDR 0x02 // 可用信道设置
#define SETUP_AW 0x03 // 收发地址宽度设置 11 0x03 5bytes
#define SETUP_RETR 0x04 // 自动重发功能设置
uint bdata sta; //状态标志
sbit RX_DR =sta^6;
sbit TX_DS =sta^5;
sbit MAX_RT =sta^4;
uchar flag;
/***函数声明***/
void Delayms(uint s);
void Delayus(uchar n);
/***宏定义***/
#define TRANSMIT_LED 1
#define RECEIVE_LED 0
#define LEDDATA P0
#define SCAN_CYCLE 500 //数码管动态扫描间隔
#define TIMER1 0xe6 //256-(110592/(12*32*96))
#define TX_PLOAD_WIDTH 32 // 32 uints TX payload
#define RX_PLOAD_WIDTH 32 // 32 uints TX payload
uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址
void Delayus(uchar n)
{
for(;n>0;n--)
_nop_();
}
/*****************************************************************************************
函数:void InitTimer(void)
sbit SCK =P1^7;
sbit CE =P1^3;
sbit CSN =P1^4;
sbit IRQ =P3^2;
sbit LED0 =P2^0;
sbit LED1 =P2^1;
/***显示及接收数据数组***/
code uchar TxBuf[32]=
{
#define RX_PW_P4 0x15 // 接收频道0接收数据长度
#define RX_PW_P5 0x16 // 接收频道0接收数据长度
#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置
/***NRF24L01状态标志***/
uchar SPI_Read(uchar reg); //NRF24L01的SPI读时序
uchar SPI_Read_Reg(uchar reg);//从寄存器reg读一个字节
uchar SPI_RW_Reg(uchar reg, uchar value);//向寄存器reg写一个字节,同时返回状态字节
for(j=0; j<12; j++);
相关文档
最新文档