完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
各位大虾,小弟初来乍到,调试nrf24l01时遇到问题了。我想把之前在51和stm8s上的nrf通信程序移植到STM32上,就用精英版,在官方的程序上做修改。接收端是51的单片机,接收到数据会改变led指示灯。我用stm32的程序能与无线模块通信是正常的,可是无法通信,不知道是什么原因。接收端用原来51的发射端控制是有反应的。以下是部分程序:
//中断程序 void EXti4_IRQHandler(void) { u8 status,i; delay_ms(10); if(KEY0==0) //按键判断 { LED0=!LED0; tmp_buf[1]=0x02; NRF24L01_TX_Mode(); status=NRF24L01_TxPacket(tmp_buf); if(status==MAX_TX) { LED1=0; } else if(status==TX_OK) { LED1=1; } tmp_buf[1]++; if(tmp_buf[1]==7) tmp_buf[1]=1; } EXTI_ClearITPendingBit(EXTI_Line4); //清中断标记 } int main(void) { delay_init(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); LED_Init(); EXTIX_Init(); NRF24L01_Init(); while(NRF24L01_Check()) //检测是否有模块 { LED0=0; delay_ms(200); LED0=1; delay_ms(200); } LED0=1; while(1) { } } u8 NRF24L01_TxPacket(u8 *txbuf) { u8 sta; SPI2_SetSpeed(SPI_BaudRatePrescaler_8); NRF24L01_CE=0; NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//D′êy¾Yμ½TX BUF 32¸ö×Ö½ú NRF24L01_CE=1;//发送数据 while(NRF24L01_IRQ!=0);//等待IRQ拉低,发送完毕 sta=NRF24L01_Read_Reg(STATUS); //读取标志位 NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清标志位 if(sta&MAX_TX) { NRF24L01_Write_Reg(FLUSH_TX,0xff); return MAX_TX; } if(sta&TX_OK) { return TX_OK; } return 0xff; } void NRF24L01_TX_Mode(void) { NRF24L01_CE=0; NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//D′TX½úμãμØÖ· NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //éèÖÃTX½úμãμØÖ·,Ö÷òaÎaáËê1ÄüACK NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x00); //ê1Äüí¨μà0μÄ×Ô¶ˉó|′e NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x00); //ê1Äüí¨μà0μĽóêÕμØÖ· NRF24L01_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x00);//éèÖÃ×Ô¶ˉÖØ·¢¼ä¸ôê±¼ä:500us + 86us;×î′ó×Ô¶ˉÖØ·¢′Îêy:10′Î NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40); //éèÖÃRFí¨μàÎa40 NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f); //éèÖÃTX·¢éä2Îêy,0dbÔöòæ,2Mbps,μíÔëéùÔöòæ¿aÆô NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG,0x06); //ÅäÖûù±¾1¤×÷Ä£ê½μÄ2ÎêyWR_UP,EN_CRC,16BIT_CRC,½óêÕÄ£ê½,¿aÆôËùóDÖD¶Ï NRF24L01_CE=1;//CEÎa¸ß,10usoóÆô¶ˉ·¢Ëí } 用了按键中断,key0按一下发送一次数据,我保证按键中断是对的,指示灯也会亮。每次NRF24L01_TxPacket()返回值是TX_OK,接收端没有反应。 与原子哥程序不同的是TX_ADDRESS,TX_ADR_WIDTH,这些参数与接收端都是一样的。 NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x00); //ê1Äüí¨μà0μÄ×Ô¶ˉó|′e NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x00); //ê1Äüí¨μà0μĽóêÕμØÖ· NRF24L01_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x00);//éèÖÃ×Ô¶ˉÖØ·¢¼ä¸ôê±¼ä:500us + 86us;×î′ó×Ô¶ˉÖØ·¢′Îêy:10′Î NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40); //éèÖÃRFí¨μàÎa40 NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f); //éèÖÃTX·¢éä2Îêy,0dbÔöòæ,2Mbps,μíÔëéùÔöòæ¿aÆô NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG,0x06); //ÅäÖûù±¾1¤×÷Ä£ê½μÄ2ÎêyWR_UP,EN_CRC,16BIT_CRC,½óêÕÄ£ê½,¿aÆôËùóDÖD¶Ï 这些寄存器设置也是和51的发射端的参数设置是一样的,不知道为什么就是没有数据传到接收端。 注释变乱码了,不好意思。。 |
|
相关推荐
8个回答
|
|
我查到错误的地方了。频道不对。。。看了好几遍没发现,昨天终于发现了。
|
|
|
|
51那边的代码也发下吧
|
|
|
|
51代码:
void main() { Delay(500); NRF24L01Int(); INT_CLKO |= 0x20; //(EX3 = 1)使能INT3下降沿中断 EA = 1; while(1) { TxDate[1]=0x0a; // TxDate[1]=0x0f; // keyscan(); Delay100ms(); PCON = 0x02; //MCU进入掉电模式 _nop_(); //掉电模式被唤醒后,首先执行此语句,然后再进入中断服务程序 _nop_(); } } void exint3() interrupt 11 { keyscan(); } void keyscan() { if(key==0) { Delay100ms(); if(key==0) { NRFSetTxMode(TxDate);//发送 while(CheckACK()); //检测是否发送完毕 while(!key); } } } void NRFSetTxMode(unchar *TxDate) {//发送模式 CE=0; NRFWriteTxDate(W_REGISTER+TX_ADDR,TxAddr,TX_ADDR_WITDH);//写寄存器指令+接收地址使能指令+接收地址+地址宽度 NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH);//为了应答接收设备,接收通道0地址和发送地址相同 NRFWriteTxDate(W_TX_PAYLOAD,TxDate,TX_DATA_WITDH);//写入数据 /******下面有关寄存器配置**************/ NRFWriteReg(W_REGISTER+EN_AA,0x00); // 使能接收通道0自动应答 // 0x01 NRFWriteReg(W_REGISTER+EN_RXADDR,0x00); // 使能接收通道0 //0x01 NRFWriteReg(W_REGISTER+SETUP_RETR,0x00); // 自动重发延时等待250us+86us,自动重发10次 //0x0a NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40 NRFWriteReg(W_REGISTER+RF_SETUP,0x0f); // 数据传输率2Mbps,发射功率0dBm,低噪声放大器增益 NRFWriteReg(W_REGISTER+CONFIG,0x06); // CRC使能,16位CRC校验,上电 //0x0e CE=1; Delay(5);//保持10us秒以上 } unchar CheckACK() { //用于发射 sta=NRFReadReg(R_REGISTER+STATUS); // 返回状态寄存器 P1=sta; if(TX_DS||MAX_RT) //发送完毕中断 { NRFWriteReg(W_REGISTER+STATUS,0xff); // 清除TX_DS或MAX_RT中断标志 CSN=0; NRFSPI(FLUSH_TX);//用于清空FIFO !!关键!!不然会出现意想不到的后果!!!大家记住!! CSN=1; return(0); } else return(1); } 以上是51的发射程序。用外部中断退出掉电模式,发射nrf24l01信号。 |
|
|
|
我明天发
|
|
|
|
void main()
{ open_f=1; WDT_CONTR=0x33; //看门狗 NRF24L01Int(); //初始化无线模块 Int3_int(); open_c=IapReadByte(IAP_ADDRESS0); //读取eeprom的占空比值 CCP0_ini(0); init_timer(); //初始化定时器 NRFSetRXMode();//设置为接收模式 SetRX_Mode(); while(1) { //SetRX_Mode(); // GetDate();//开始接受数 WDT_CONTR=0x33; /* if(RevTempDate[0]==0xaa) { if(RevTempDate[1]==0x0f) //上调 { if(CCAP1H<=250) //$254 { CCAP1H=CCAP1H+1; CCAP1L=CCAP1H; } pwm_f=1; AUXR |= 0x10; //定时器2开始计时 } else if(RevTempDate[1]==0xf0) //下调 { if(CCAP1H>1) { CCAP1H=CCAP1H-1; CCAP1L=CCAP1H; } pwm_f=1; AUXR |= 0x10; //定时器2开始计时 } /* else if(RevTempDate[1]==0x11) //上传占空比 { TxDate[0]=0x00; TxDate[1]=(uchar)CCAP1H; //发射占空比 Delay1ms(5); NRFSetTxMode(TxDate);//发送 while(CheckACK()); //检测是否发送完毕 // NRFSetRXMode();//设置为接收模式 SetRX_Mode(); } */ // RevTempDate[0]=0x00; // RevTempDate[1]=0x00; // } /* if(RevTempDate[0]==0xff) //下载占空比 { CCAP1H=RevTempDate[1]; RevTempDate[0]=0x00; RevTempDate[1]=0x00; CCAP1L=CCAP1H; IapEraseSector(IAP_ADDRESS0); //erase current sector Delay5ms(); IapProgramByte(IAP_ADDRESS0,(BYTE)CCAP1H); } */ /* if(eep_f==1) { IapEraseSector(IAP_ADDRESS0); //erase current sector Delay5ms(); IapProgramByte(IAP_ADDRESS0,(BYTE)CCAP1H); eep_f=0; }*/ if(RevTempDate[1]==0x0a) { if(CCAP1H <=55 ) CCAP1H = CCAP1L =56; //9W else if(CCAP1H<=100) CCAP1H = CCAP1L =101; //7W else if(CCAP1H<=143) CCAP1H = CCAP1L =144; //5W else if(CCAP1H<=193) CCAP1H = CCAP1L =194; //3W else if(CCAP1H<=234) CCAP1H = CCAP1L =235; //1W else CCAP1H = CCAP1L =0; //12W IapEraseSector(IAP_ADDRESS0); //erase current sector Delay5ms(); IapProgramByte(IAP_ADDRESS0,(BYTE)CCAP1H); RevTempDate[1]=0x00; } else if(RevTempDate[1]==0x01) { CCAP1H=235; //1W CCAP1L = CCAP1H; IapEraseSector(IAP_ADDRESS0); //erase current sector Delay5ms(); IapProgramByte(IAP_ADDRESS0,(BYTE)CCAP1H); RevTempDate[1]=0x00; } else if(RevTempDate[1]==0x02) { CCAP1H=194; //3W CCAP1L = CCAP1H; IapEraseSector(IAP_ADDRESS0); //erase current sector Delay5ms(); IapProgramByte(IAP_ADDRESS0,(BYTE)CCAP1H); RevTempDate[1]=0x00; } else if(RevTempDate[1]==0x03) { CCAP1H=144; //5W CCAP1L = CCAP1H; IapEraseSector(IAP_ADDRESS0); //erase current sector Delay5ms(); IapProgramByte(IAP_ADDRESS0,(BYTE)CCAP1H); RevTempDate[1]=0x00; } else if(RevTempDate[1]==0x04) { CCAP1H=101; //7W CCAP1L = CCAP1H; IapEraseSector(IAP_ADDRESS0); //erase current sector Delay5ms(); IapProgramByte(IAP_ADDRESS0,(BYTE)CCAP1H); RevTempDate[1]=0x00; } else if(RevTempDate[1]==0x05) { CCAP1H=56; //9W CCAP1L = CCAP1H; IapEraseSector(IAP_ADDRESS0); //erase current sector Delay5ms(); IapProgramByte(IAP_ADDRESS0,(BYTE)CCAP1H); RevTempDate[1]=0x00; } else if(RevTempDate[1]==0x06) { CCAP1H=0; //12W CCAP1L = CCAP1H; IapEraseSector(IAP_ADDRESS0); //erase current sector Delay5ms(); IapProgramByte(IAP_ADDRESS0,(BYTE)CCAP1H); RevTempDate[1]=0x00; } // PCON = 0x02; //MCU进入掉电模式 // _nop_(); //掉电模式被唤醒后,首先执行此语句,然后再进入中断服务程序 // _nop_(); } } void main() { open_f=1; WDT_CONTR=0x33; //看门狗 NRF24L01Int(); //初始化无线模块 Int3_int(); open_c=IapReadByte(IAP_ADDRESS0); //读取eeprom的占空比值 CCP0_ini(0); init_timer(); //初始化定时器 NRFSetRXMode();//设置为接收模式 SetRX_Mode(); while(1) { //SetRX_Mode(); // GetDate();//开始接受数 WDT_CONTR=0x33; /* if(RevTempDate[0]==0xaa) { if(RevTempDate[1]==0x0f) //上调 { if(CCAP1H<=250) //$254 { CCAP1H=CCAP1H+1; CCAP1L=CCAP1H; } pwm_f=1; AUXR |= 0x10; //定时器2开始计时 } else if(RevTempDate[1]==0xf0) //下调 { if(CCAP1H>1) { CCAP1H=CCAP1H-1; CCAP1L=CCAP1H; } pwm_f=1; AUXR |= 0x10; //定时器2开始计时 } /* else if(RevTempDate[1]==0x11) //上传占空比 { TxDate[0]=0x00; TxDate[1]=(uchar)CCAP1H; //发射占空比 Delay1ms(5); NRFSetTxMode(TxDate);//发送 while(CheckACK()); //检测是否发送完毕 // NRFSetRXMode();//设置为接收模式 SetRX_Mode(); } */ // RevTempDate[0]=0x00; // RevTempDate[1]=0x00; // } /* if(RevTempDate[0]==0xff) //下载占空比 { CCAP1H=RevTempDate[1]; RevTempDate[0]=0x00; RevTempDate[1]=0x00; CCAP1L=CCAP1H; IapEraseSector(IAP_ADDRESS0); //erase current sector Delay5ms(); IapProgramByte(IAP_ADDRESS0,(BYTE)CCAP1H); } */ /* if(eep_f==1) { IapEraseSector(IAP_ADDRESS0); //erase current sector Delay5ms(); IapProgramByte(IAP_ADDRESS0,(BYTE)CCAP1H); eep_f=0; }*/ if(RevTempDate[1]==0x0a) { if(CCAP1H <=55 ) CCAP1H = CCAP1L =56; //9W else if(CCAP1H<=100) CCAP1H = CCAP1L =101; //7W else if(CCAP1H<=143) CCAP1H = CCAP1L =144; //5W else if(CCAP1H<=193) CCAP1H = CCAP1L =194; //3W else if(CCAP1H<=234) CCAP1H = CCAP1L =235; //1W else CCAP1H = CCAP1L =0; //12W IapEraseSector(IAP_ADDRESS0); //erase current sector Delay5ms(); IapProgramByte(IAP_ADDRESS0,(BYTE)CCAP1H); RevTempDate[1]=0x00; } else if(RevTempDate[1]==0x01) { CCAP1H=235; //1W CCAP1L = CCAP1H; IapEraseSector(IAP_ADDRESS0); //erase current sector Delay5ms(); IapProgramByte(IAP_ADDRESS0,(BYTE)CCAP1H); RevTempDate[1]=0x00; } else if(RevTempDate[1]==0x02) { CCAP1H=194; //3W CCAP1L = CCAP1H; IapEraseSector(IAP_ADDRESS0); //erase current sector Delay5ms(); IapProgramByte(IAP_ADDRESS0,(BYTE)CCAP1H); RevTempDate[1]=0x00; } else if(RevTempDate[1]==0x03) { CCAP1H=144; //5W CCAP1L = CCAP1H; IapEraseSector(IAP_ADDRESS0); //erase current sector Delay5ms(); IapProgramByte(IAP_ADDRESS0,(BYTE)CCAP1H); RevTempDate[1]=0x00; } else if(RevTempDate[1]==0x04) { CCAP1H=101; //7W CCAP1L = CCAP1H; IapEraseSector(IAP_ADDRESS0); //erase current sector Delay5ms(); IapProgramByte(IAP_ADDRESS0,(BYTE)CCAP1H); RevTempDate[1]=0x00; } else if(RevTempDate[1]==0x05) { CCAP1H=56; //9W CCAP1L = CCAP1H; IapEraseSector(IAP_ADDRESS0); //erase current sector Delay5ms(); IapProgramByte(IAP_ADDRESS0,(BYTE)CCAP1H); RevTempDate[1]=0x00; } else if(RevTempDate[1]==0x06) { CCAP1H=0; //12W CCAP1L = CCAP1H; IapEraseSector(IAP_ADDRESS0); //erase current sector Delay5ms(); IapProgramByte(IAP_ADDRESS0,(BYTE)CCAP1H); RevTempDate[1]=0x00; } // PCON = 0x02; //MCU进入掉电模式 // _nop_(); //掉电模式被唤醒后,首先执行此语句,然后再进入中断服务程序 // _nop_(); } } void SetRX_Mode(void) { CE=0; NRFWriteReg(W_REGISTER + CONFIG, 0x07); // IRQ收发完成中断响应,16位CRC ,主接收 中断使能 CE = 1; NRFDelay(130); } void SetRX_Mode(void) { CE=0; NRFWriteReg(W_REGISTER + CONFIG, 0x07); // IRQ收发完成中断响应,16位CRC ,主接收 中断使能 CE = 1; NRFDelay(130); } 用IRQ引脚触发外部中断,读取数据。设置nrf的函数也贴出来了。 |
|
|
|
原子哥,我nrf模块软件调不出来。我在你的程序里看到发射时,先调用tx_mode,再调用tx_packet,我接收端没有反应。checknrf函数能检测到模块存在,是不是说明spi通信没有问题?
|
|
|
|
是的,check能通过,一般说明你的SPI就无问题了,检查其他地方
|
|
|
|
收发地址,地址长度,数据长度都改成与51的程序一样了。nrf模块的寄存器参数也是与51的一样,可就是没有反应。原子哥,你觉得应该要往哪方面调?
|
|
|
|
只有小组成员才能发言,加入小组>>
如何使用STM32+nrf24l01架构把有线USB设备无线化?
2568 浏览 7 评论
请问能利用51单片机和nRF24L01模块实现实时语音无线传输吗?
2359 浏览 5 评论
3207 浏览 3 评论
2836 浏览 8 评论
为什么ucosii上移植lwip后系统进入了HardFault_Handler?
2786 浏览 4 评论
请教各位大咖:有没有接收频率32M左右的芯片推荐的?先感谢啦!
658浏览 1评论
897浏览 0评论
1019浏览 0评论
664浏览 0评论
494浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 16:59 , Processed in 1.067898 second(s), Total 60, Slave 54 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号