完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我是大二的学生 参加飞思卡尔智能汽车比赛,用到了无线模块NRF24L01 ,但我学习了好久还是有很多不懂得地方,求大神指导,
无线模块与单片机如何连接(STC89C52 IO口),无线模块是如何发送数据的, 如果我用一个单片机+无线模块发数据给另一个单片+无线模块,希望点亮第二块单片机板子上的流水灯,那么发的是什么数据,???? |
|
相关推荐
22个回答
|
|
你去看一下SPI总线的时序图,nRF24L01芯片和单片机连接最主要的就是这个时序问题.
|
|
|
|
嗯 ,那个时序图我看了好几天,有好多地方看不懂 !!!!!我再看看 ,如果再不会 那是向你请教,,希望不吝赐教
|
|
|
|
|
|
|
|
目前正在弄,头疼呢。。。
|
|
|
|
我也不懂,只是想做成个无线遥控而已
|
|
|
|
同问,有没有人能给一份程序,不胜感激
|
|
|
|
版主很复杂啊,糊涂了,mcu的。。。你是不是用的是射频前端啊?
|
|
|
|
|
|
|
|
|
|
|
|
恩恩,希望谁给一个历程
|
|
|
|
你不妨看看这个:
89C52RC + NRF24L01 + 1602液晶显示 我昨晚刚调出来的。这家伙前前后后花了 我近一个月时间呐!!!对我这种小白,无线实在难搞,太狗血了!几次想放弃了, 但比赛作品需要它来润色,不得不咬牙坚持了下来。当看到接收机上亮起数字时, 我已老泪纵横了!!! 最容易出毛病的就是整篇代码打完后一编译,各种奇葩错误!明明定义过了还说undefined! 还有什么语法错误啦。。。最好写一段编译一下(代码度娘上太多了)。然后,调试的时候 一定要一块块来,先是MCU和NRF之间的通讯,然后检测载波,两块板子都OK了再进行无线 传输的调试! 发射程序: #include #define uchar unsigned char #define uint unsigned int //****************************************IO端口定义*************************************** ***it IRQ=P2^2; ***it MISO=P2^3; ***it MOSI=P2^1; ***it SCK=P2^4; ***it CSN=P2^0; ***it CE=P2^5; ***it rs=P3^3; ***it rw=P3^4; ***it en=P3^5; uchar bdata sta; //状态标志 // bData是可位寻址的变量 ***it RX_DR =sta^6; ***it TX_DS =sta^5; ***it MAX_RT =sta^4; //uchar str[7]; //***************************************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 4 // 3 uints TX payload //到底几位??????????????????? #define RX_PLOAD_WIDTH 4 // 3 uints TX payload uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址 uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址 uchar Tx_Buf[TX_PLOAD_WIDTH]={0x00,0x01,0x02,0x03};//发送数据 //uchar Rx_Buf[RX_PLOAD_WIDTH];//接收数据 //******************************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(uchar z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } //******************************** 液 晶 ************************************* void write_com(uchar com) { rs=0; en=0; P1=com; delay(3); en=1; delay(3); en=0; } void write_date(uchar date) { rs=1; en=0; P1=date; delay(3); en=1; delay(3); en=0; } void init_lcd() //光标关闪烁 { en=0; rw=0; write_com(0x38); write_com(0x0c); write_com(0x06); //写一个字光标右移一位 write_com(0x01); //清屏 } void display(uchar add,uchar temp) //显示函数 { uchar shi,ge,yi; shi=temp/100; ge=temp%100/10; yi=temp%10; write_com(0x80+add); if(shi==0) { write_date(' '); } else { write_date(0x30+shi); } write_date(0x30+ge); write_date(0x30+yi); } //****************************IO 口模拟SPI总线 代码********************************* uchar SPI_RW(uchar byte) // 写一个byte // { uchar bit_ctr; for(bit_ctr=0;bit_ctr<8;bit_ctr++) { MOSI=(byte&0x80); // 写一个 。。。CSN不用置低吗?// byte=(byte<<1); SCK=1; byte|=MISO; // 读一个 // SCK=0; } return(byte); // 读回来的byte // } uchar SPI_RW_Reg(uchar reg,uchar value) // 向寄存器reg写一个字节(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 状态。发送0,读回byte 给reg_val // CSN=1; return(reg_val); } uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes) // 选择 reg 写入 *pBuf 的地址 ,bytes 地址长度 // //怎么起到选择作用?????????? { uchar status,byte_ctr; CSN = 0; // Set CSN low, init SPI tranaction status = SPI_RW(reg); // Select register to write to and read status byte for(byte_ctr=0; byte_ctr CSN = 1; // Set CSN high again return(status); // return nRF24L01 status byte } uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)//吧reg里数据读到buf里 { uchar status,uchar_ctr; CSN = 0; // Set CSN low, init SPI tranaction status = SPI_RW(reg); // Select register to write to and read status uchar for(uchar_ctr=0;uchar_ctr CSN = 1; return(status); // return nRF24L01 status uchar } /******************************* 发 ***** 送 ***** 模 **** 式 ***** 代 ***** 码 *************************************/ void TX_Mode(void) //初始化! { CE=0; SPI_RW_Reg(FLUSH_TX,0x00); SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0 // 向EN_AA写入0x01,通道0自动应答. SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0 SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 向自动重发寄存器写入0x1a,等待500+86us,重发10次 SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40 //向RF_CH写入40,频率为40....? //?????????? SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0f); // 向RF_SETUP 写入0x0f,传输率2Mbps 发射功率0dBm 低噪声放大增益器。 SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为2字节 //不是32字节? //?????????? SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // 向CONFIG写入0x0e,CRC使能,CRC校验码16位,上电,发送模式。 CE=1; //CE高启动发射(10us之后) delay(100); } void Transmit(uchar * tx_buf) // 发送数据 { CE=0; //StandBy I模式 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); // 装载接收端地址 SPI_RW_Reg(FLUSH_TX,0x00); SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载tx_buf数据(写到PLOAD里) SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送 CE=1; //置高CE,激发数据发送 delay(150); } void main() { // uchar status,FIFO; CE=0; SCK=0; CSN=1; IRQ=1; status=0; init_lcd(); delay(10); TX_Mode(); // SPI_RW_Reg(FLUSH_TX,0x00); // SPI_RW_Reg(WRITE_REG+STATUS,0xff); while(1) { Tx_Buf[0]++; Transmit(Tx_Buf); delay(1000); delay(1000); delay(1000); //控制数字变化速度 //***********************************读寄存器状态****************************************** /* status=SPI_Read_Buf(TX_ADDR,str,TX_ADR_WIDTH); display(0x00,str[0]); display(0x04,str[1]); display(0x08,str[2]); display(0x0c,str[3]); display(0x40,str[4]); display(0x44,str[5]); delay(10);*/ //读发射机地址 status=SPI_Read(STATUS); display(0x00,status); FIFO=SPI_Read(FIFO_STATUS); display(0x04,FIFO); Transmit(Tx_Buf); status=SPI_Read(STATUS); display(0x40,status); FIFO=SPI_Read(FIFO_STATUS); display(0x44,FIFO); //************************************发送失败检测********************************************* sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据发送状况 if(!TX_DS) { write_com(0x88); write_date('T'); write_date('X'); write_date(' '); write_date('E'); write_date('R'); write_date('R'); write_date('O'); write_date('R'); //发送失败(没收到应答信号) delay(5); } if(MAX_RT) { write_com(0X80+0x48); write_date('R'); write_date('E'); write_date(' '); write_date('E'); write_date('R'); write_date('R'); write_date('O'); write_date('R'); delay(5); //多次重发失败 } } } |
|
|
|
还有接收部分:
|
|
|
|
89C52 、NRF24L01+、1602液晶显示 我昨晚刚调成。
无线确实难调,前前后后花了我近一个月呐!几次想放弃了都!但比赛作品需要它来润色,不得不咬牙坚持下来。功夫不负有心人啊!加油,你也可以的! 有一个特别头疼的问题就是当你去辛辛苦苦打完一整篇代码,完了一编译,艹!各种奇葩错误。比如明明定义了它却说没定义。所以最好每写一段编译一下。还有调试一定要一块块板子来。先把每块板子MCU和NRF之间的通讯建立完成,然后检测载波,再才是两板子之间一对一的无线收发调试。 这是发射部分: #include #define uchar unsigned char #define uint unsigned int //****************************************IO端口定义*************************************** ***it IRQ=P2^2; ***it MISO=P2^3; ***it MOSI=P2^1; ***it SCK=P2^4; ***it CSN=P2^0; ***it CE=P2^5; ***it rs=P3^3; ***it rw=P3^4; ***it en=P3^5; uchar bdata sta; //状态标志 // bData是可位寻址的变量 ***it RX_DR =sta^6; ***it TX_DS =sta^5; ***it MAX_RT =sta^4; //uchar str[7]; //***************************************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 4 // 3 uints TX payload //到底几位??????????????????? #define RX_PLOAD_WIDTH 4 // 3 uints TX payload uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址 uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址 uchar Tx_Buf[TX_PLOAD_WIDTH]={0x00,0x01,0x02,0x03};//发送数据 //uchar Rx_Buf[RX_PLOAD_WIDTH];//接收数据 //******************************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(uchar z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } //******************************** 液 晶 ************************************* void write_com(uchar com) { rs=0; en=0; P1=com; delay(3); en=1; delay(3); en=0; } void write_date(uchar date) { rs=1; en=0; P1=date; delay(3); en=1; delay(3); en=0; } void init_lcd() //光标关闪烁 { en=0; rw=0; write_com(0x38); write_com(0x0c); write_com(0x06); //写一个字光标右移一位 write_com(0x01); //清屏 } void display(uchar add,uchar temp) //显示函数 { uchar shi,ge,yi; shi=temp/100; ge=temp%100/10; yi=temp%10; write_com(0x80+add); if(shi==0) { write_date(' '); } else { write_date(0x30+shi); } write_date(0x30+ge); write_date(0x30+yi); } //****************************IO 口模拟SPI总线 代码********************************* uchar SPI_RW(uchar byte) // 写一个byte // { uchar bit_ctr; for(bit_ctr=0;bit_ctr<8;bit_ctr++) { MOSI=(byte&0x80); // 写一个 。。。CSN不用置低吗?// byte=(byte<<1); SCK=1; byte|=MISO; // 读一个 // SCK=0; } return(byte); // 读回来的byte // } uchar SPI_RW_Reg(uchar reg,uchar value) // 向寄存器reg写一个字节(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 状态。发送0,读回byte 给reg_val // CSN=1; return(reg_val); } uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes) // 选择 reg 写入 *pBuf 的地址 ,bytes 地址长度 // //怎么起到选择作用?????????? { uchar status,byte_ctr; CSN = 0; // Set CSN low, init SPI tranaction status = SPI_RW(reg); // Select register to write to and read status byte for(byte_ctr=0; byte_ctr CSN = 1; // Set CSN high again return(status); // return nRF24L01 status byte } uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)//吧reg里数据读到buf里 { uchar status,uchar_ctr; CSN = 0; // Set CSN low, init SPI tranaction status = SPI_RW(reg); // Select register to write to and read status uchar for(uchar_ctr=0;uchar_ctr CSN = 1; return(status); // return nRF24L01 status uchar } /******************************* 发 ***** 送 ***** 模 **** 式 ***** 代 ***** 码 *************************************/ void TX_Mode(void) //初始化! { CE=0; SPI_RW_Reg(FLUSH_TX,0x00); SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0 // 向EN_AA写入0x01,通道0自动应答. SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0 SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 向自动重发寄存器写入0x1a,等待500+86us,重发10次 SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40 //向RF_CH写入40,频率为40.....? SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0f); // 向RF_SETUP 写入0x0f,传输率2Mbps 发射功率0dBm 低噪声放大增益器。 SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为4字节 SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // 向CONFIG写入0x0e,CRC使能,CRC校验码16位,上电,发送模式。 CE=1; //CE高启动发射(10us之后) delay(100); } void Transmit(uchar * tx_buf) // 发送数据 { CE=0; //StandBy I模式 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); // 装载接收端地址 SPI_RW_Reg(FLUSH_TX,0x00); //清空TX FIFO SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载tx_buf数据 SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送 CE=1; //置高CE,激发数据发送 delay(150); } void main() { // uchar status,FIFO; //后面读状态时候用 CE=0; SCK=0; CSN=1; IRQ=1; // status=0; //后面读状态时候用.先设为0 init_lcd(); delay(10); TX_Mode(); // SPI_RW_Reg(FLUSH_TX,0x00); // SPI_RW_Reg(WRITE_REG+STATUS,0xff); while(1) { Transmit(Tx_Buf); delay(10); //***********************************读寄存器状态****************************************** /* status=SPI_Read_Buf(TX_ADDR,str,TX_ADR_WIDTH); display(0x00,str[0]); display(0x04,str[1]); display(0x08,str[2]); display(0x0c,str[3]); display(0x40,str[4]); display(0x44,str[5]); delay(10);*/ //读发射机地址(单独调试时用) status=SPI_Read(STATUS); //读STATUS状态 display(0x00,status); FIFO=SPI_Read(FIFO_STATUS); //读FIFO状态 display(0x04,FIFO); Transmit(Tx_Buf); // 发送一次 status=SPI_Read(STATUS); //再读 display(0x40,status); FIFO=SPI_Read(FIFO_STATUS); display(0x44,FIFO); //************************************发送失败检测********************************************* sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据发送状况 if(!TX_DS) { write_com(0x88); write_date('T'); write_date('X'); write_date(' '); write_date('E'); write_date('R'); write_date('R'); write_date('O'); write_date('R'); //发送失败(没收到应答信号)时显示 delay(5); } if(MAX_RT) { write_com(0X80+0x48); write_date('R'); write_date('E'); write_date(' '); write_date('E'); write_date('R'); write_date('R'); write_date('O'); write_date('R'); delay(5); //多次重发失败时显示 } } } |
|
|
|
发送代码我好想发了两次诶,,,
结下来是接收部分的代码: #include #define uchar unsigned char #define uint unsigned int //****************************************IO端口定义*************************************** ***it IRQ=P2^2; ***it MISO=P2^3; ***it MOSI=P2^1; ***it SCK=P2^4; ***it CSN=P2^0; ***it CE=P2^5; ***it rs=P3^3; ***it rw=P3^4; ***it en=P3^5; uchar bdata sta; //状态标志 // bData是可位寻址的变量 ***it RX_DR =sta^6; ***it TX_DS =sta^5; ***it MAX_RT =sta^4; uchar f; //标志位 //uchar str[7]; //***************************************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 4 //4 uints TX payload #define RX_PLOAD_WIDTH 4 // 4 uints TX payload uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //发射机地址 uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址 //uchar code Tx_Buf[TX_PLOAD_WIDTH]={0x00,0x01,0x02,0x03};//发送数据 uchar Rx_Buf[RX_PLOAD_WIDTH];//接收数据 //******************************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(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } //******************************** 液 晶 ************************************* void write_com(uchar com) { rs=0; en=0; P1=com; delay(3); en=1; delay(3); en=0; } void write_date(uchar date) { rs=1; en=0; P1=date; delay(3); en=1; delay(3); en=0; } void init_lcd() //光标关闪烁 { en=0; rw=0; write_com(0x38); write_com(0x0c); write_com(0x06); //写一个字光标右移一位 write_com(0x01); //清屏 } void display(uchar add,uchar temp) //显示函数 { uchar bai,shi,ge; bai=temp/100; shi=temp%100/10; ge=temp%10; write_com(0x80+add); if(shi==0) { write_date(' '); } else { write_date(0x30+bai); } write_date(0x30+shi); write_date(0x30+ge); } //****************************IO 口模拟SPI总线 代码********************************* uchar SPI_RW(uchar byte) // 写一个byte // { uchar bit_ctr; for(bit_ctr=0;bit_ctr<8;bit_ctr++) { MOSI=(byte&0x80); // 写一个 。。。CSN不用置低吗?// byte=(byte<<1); SCK=1; byte|=MISO; // 读一个 // SCK=0; } return(byte); // 读回来的byte // } uchar SPI_RW_Reg(uchar reg,uchar value) // 向寄存器reg写一个字节(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 状态。发送0,读回byte 给reg_val // CSN=1; return(reg_val); } uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes) // 选择 reg 写入 *pBuf 的地址 ,bytes 地址长度 // //怎么起到选择作用?????????? { uchar status,byte_ctr; CSN = 0; // Set CSN low, init SPI tranaction status = SPI_RW(reg); // Select register to write to and read status byte for(byte_ctr=0; byte_ctr CSN = 1; // Set CSN high again return(status); // return nRF24L01 status byte } uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)//吧reg里数据读到buf里 { uchar status,uchar_ctr; CSN = 0; // Set CSN low, init SPI tranaction status = SPI_RW(reg); // Select register to write to and read status uchar for(uchar_ctr=0;uchar_ctr CSN = 1; return(status); // return nRF24L01 status uchar } /******************************************************************************************************/ /*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf) /*功能:数据读取后放入rx_buf接收缓冲区中 /******************************************************************************************************/ void nRF24L01_RxPacket(uchar *rx_buf) { sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况 if(RX_DR) // 判断是否接收到数据 { CE = 0; //SPI使能 SPI_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer f=1; //读取数据完成标志 } SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清除中断标志 } /****************************************************************************************************/ /*函数:void RX_Mode(void) /*功能:数据接收配置 /****************************************************************************************************/ void RX_Mode(void) //接收模式 { CE=0; SPI_RW_Reg(FLUSH_RX,0x00); 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.Ack SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0 向EN_AA写入0x01,通道0自动应答. SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0 // SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...1a 。接收模式不用写。 SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40 SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为2字节 SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0f); // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR CE=1; delay(130); } void Receive() //接收数据 { CE=0; SPI_RW_Reg(WRITE_REG + CONFIG, 0x0F); //向CONFIG写入0x0f,CRC使能,CRC校验码16位,上电,接收模式。 CE=1; delay(10); } void main() { uint i; init_lcd(); CE=0; SCK=0; CSN=1; IRQ=1; RX_Mode(); while(1) { Receive(); //接收 nRF24L01_RxPacket(Rx_Buf); //数据存放到Rx_Buf[] delay(10); if(f) //接收到数据时f=1 { display(0x00,Rx_Buf[0]); display(0x08,Rx_Buf[1]); display(0x40,Rx_Buf[2]); display(0x48,Rx_Buf[3]); delay(10); } else { write_com(0x80); write_date(0x3a); delay(10); //没收到时显示一个冒号 } } } 最后,祝你好运! 不要灰心,不要放弃,你会成功的! |
|
|
|
|
|
|
|
|
|
|
|
谢谢大神 !我试试看看 !非常感谢 |
|
|
|
|
|
|
|
我也不懂,只是想做成个无线遥控而已
|
|
|
|
只有小组成员才能发言,加入小组>>
物联网工程师必备:怎么选择不同的无线连接技术,本指南帮你忙!
3285 浏览 1 评论
【DFRobot TinkerNode NB-IoT 物联网开发板试用连载】WIFI功能测试
3938 浏览 0 评论
【DFRobot TinkerNode NB-IoT 物联网开发板试用连载】Arduino的替代SublimeText3+STino
3444 浏览 0 评论
使用端口扩展器轻松高效地向IIoT端点添加具有成本效益的子节点
4008 浏览 1 评论
20683 浏览 11 评论
模组有时候复位重启后输出日志为“REBOOT_CAUSE_SECURITY_PMU_POWER_ON_RESET”的原因?
804浏览 2评论
1022浏览 2评论
1025浏览 1评论
1143浏览 1评论
381浏览 1评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 12:36 , Processed in 1.521416 second(s), Total 84, Slave 77 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号