本帖最后由 feiyinglala 于 2022-6-11 02:39 编辑
目的:借鉴Mirf库,使用arduino驱动nRF模块,通过串口监视工作状态
特别说明:我将模块配置为了无需ACK的单发状态(EN_AA/EN_RXADDR/SETUP_RETR均配置为0x00)
现象问题:寄存器配置显示正确,数据也加载到FIFO中了,但就是发不出去(STATUS=0E,FIFO_STATUS=0X01)串口通信正常,模块是正常的(换到STM32驱动就可以发出去)
引脚关系: CE -> 8 // * CSN -> 7 // * SCK -> 13 * MOSI -> 11 * MISO -> 12 * IRQ -> 2
整体思路:nRF初始化默认配置为接收状态,在接到电脑通过串口发送的命令后启动发送
setup():
串口和定时器初始化
Mirf.init,配置CE和CSN引脚
Mirf.config 配置为接收模式--清空FIFO接收区
loop():
读取当前EN_AA / EN_RXADDR / SETUP_RETR / CONFIG寄存器配置状态和STATUS、FIFO_STATUS寄存器状态
Mirf.send 检验是否在发送状态---配置为发送模式---清空FIFO发送区---CE置高发送
读取发送后STATUS、FIFO_STATUS寄存器配置状态
延时循环计数
串口接收到的信息
Starting wireless...
Wireless initialized!
循环第0次
EN_AA:1
EN_RXADDR:1
SETUP_RETR:3
CONFIG:1F
发送前STATUS:E
发送前FIFO_STATUS:11
Mirf中send函数段:status=E
发送后STATUS:E
发送后FIFO_STATUS1:1
循环第1次
EN_AA:0
EN_RXADDR:0
SETUP_RETR:0
CONFIG:3E
发送前STATUS:E
发送前FIFO_STATUS:1
心跳还在
源代码如下:
1.主程序
void loop() {
Serial.print( "循环第" );
Serial.print(i, HEX );
Serial.println("次");
/***********1.读取EN_AA等寄存器的配置值*******************/
Mirf.readRegister(EN_AA,&temp[0],1); //读取寄存器配置值
Serial.print( "EN_AA:" );
Serial.println( temp[0], HEX );
Mirf.readRegister(EN_RXADDR,&temp[0],1); //读取寄存器配置值
Serial.print( "EN_RXADDR:" );
Serial.println( temp[0], HEX );
Mirf.readRegister(SETUP_RETR,&temp[0],1); //读取寄存器配置值
Serial.print( "SETUP_RETR:" );
Serial.println( temp[0], HEX );
Mirf.readRegister(CONFIG,&temp[0],1); //读取寄存器配置值
Serial.print( "CONFIG:" );
Serial.println( temp[0], HEX );
/***********2.读取STATUS等寄存器的初始值*******************/
//Mirf.readRegister(STATUS,&temp[0],1); //读取寄存器配置值
temp[0] = Mirf.getStatus();
Serial.print( "发送前STATUS:" );
Serial.println( temp[0], HEX );
Mirf.readRegister(FIFO_STATUS,&temp[0],1); //读取寄存器配置值
Serial.print( "发送前FIFO_STATUS:" );
Serial.println( temp[0], HEX );
/**************3.发送数据*******************/
Mirf.send(PC_Buf); //发送指令,发送32字节数据
//while(Mirf.isSending()) delay(20); //直到发送成功(TX_DS为1),退出循环 20220529卡死
/***********4.读取STATUS等寄存器的初始值*******************/
Mirf.readRegister(STATUS,&temp[0],1); //读取寄存器配置值
Serial.print( "发送后STATUS:" );
Serial.println( temp[0], HEX );
Mirf.readRegister(FIFO_STATUS,&temp[0],1); //读取寄存器配置值
Serial.print( "发送后FIFO_STATUS1:" );
Serial.println( temp[0], HEX );
//Mirf.writeRegister(STATUS,0xff,1); //改造为清除状态寄存器
delay(1000*i); if(i<5)i++; //此行为节奏控制,后续可删除
}
2.Mirf.CPP[改造后]
void Nrf24l::init()
// Initializes pins to communicate with the MiRF module
// Should be called in the early initializing phase at startup.
{
pinMode(cePin,OUTPUT); //CE配置为输出
pinMode(csnPin,OUTPUT); //CSN配置为输出
ceLow(); //默认配置为低,待机1:无数据传输
csnHi(); //默认配置为高,片选禁用
// Initialize spi module
spi->begin(); //启动SPI
}
void Nrf24l::config() //改造为默认保持收
// Sets the important registers in the MiRF module and powers the module
// in receiving mode
// NB: channel and payload must be set now.
{
// Set RF channel
configRegister(RF_CH,channel); //待核实
// Set length of incoming payload
configRegister(RX_PW_P0, payload); //数据包长度
configRegister(RX_PW_P1, payload);
// Start receiver
powerUpRx(); //默认为接收态
flushRx(); //不知用途
}
void Nrf24l::setRADDR(uint8_t * adr)
// Sets the receiving address 设置接收地址
{
ceLow();
writeRegister(RX_ADDR_P1,adr,mirf_ADDR_LEN);
ceHi();
}
void Nrf24l::setTADDR(uint8_t * adr)
// Sets the transmitting address 设置发送地址
{
/*
* RX_ADDR_P0 must be set to the sending addr for auto ack to work.
*/
writeRegister(RX_ADDR_P0,adr,mirf_ADDR_LEN);
writeRegister(TX_ADDR,adr,mirf_ADDR_LEN);
}
void Nrf24l::send(uint8_t * value)
{
uint8_t status,f_status;
status = getStatus();
while (PTX) { //PTX标志为1(发送态时),判断是否完成处于发送中
status = getStatus();
//status第4、5位任何一位置位,就表明完成了上次发送
if((status & (1 << TX_DS))){//((1 << TX_DS) | (1 << MAX_RT)))){ //数据发送完成中断 或 达到最大重发
PTX = 0; //标志状态回归接收态
break;
}//Serial.print( "当前:PTX=1,异常" ); //20220607因TX_DS未变,导致始终输出
} // Wait until last paket is send
ceLow(); //StandBy I模式
powerUpTx(); // Set to transmitter mode , Power up
csnLow(); // Pull down chip select
spi->transfer(FLUSH_TX); // Write cmd to flush tx fifo
csnHi(); // Pull up chip select
delayMicroseconds(50); //延时至少保持5us
//装填数据
csnLow(); // Pull down chip select 片选有效
spi->transfer( W_TX_PAYLOAD ); // Write cmd to write payload
transmitSync(value,payload); // 【关键动作发送】Write payload
csnHi(); // CSN拉高结束向FIFO写数据
//置高发射
ceHi(); // Start transmission
delayMicroseconds(130);
//串口监控代码
status=getStatus();
Serial.print( "Mirf中send函数段:status=" );
Serial.println(status, HEX );
}
void Nrf24l::powerUpTx(){
PTX = 1;
//20220529编写 待验证
csnHi(); // Pull up chip select
setTADDR(Tx_addr); //写发送端地址TX_ADDR 和接收端地址RX_ADDR_P0
setRADDR(Rx_addr); //写接收端RX_ADDR_P1地址(CE电平拉低写地址后变高)
//RX_ADDR_P0
writeRegister(RX_ADDR_P0,Rx_addr,mirf_ADDR_LEN);
writeRegister(TX_ADDR,Tx_addr,mirf_ADDR_LEN);
configRegister(EN_AA,0x00); //自动应答ACK禁止
configRegister(EN_RXADDR,0x00); //[发送专用]允许接收地址只有频道0
configRegister(SETUP_RETR,0x00); //[调试]自动重发禁用
configRegister(RF_CH,channel); //Set RF channel
configRegister(RF_SETUP,0x0f); //设置发射速率2MHz,发射功率为最大值0dB
// Set length of incoming payload
configRegister(RX_PW_P0, payload);
configRegister(CONFIG, 0x3e);//, mirf_CONFIG | ( (1<<PWR_UP) | (0<<PRIM_RX) ) );
//20220529编写 待验证^^^^^^
}
|