第一次用这个芯片,博主用的是中断的方式读取状态以及接收数据,发现发送端每次读出来的值是0x1F,说明发送到达了最大发送次数而没有被接收?发送是OK的吗?然而接收端怎么也没有数据打印出来,接收不到任何数据,不知道问题出现在哪里,读写寄存器函数是OK的,求大神指点一下。
#ifdef nRF24l01_EN
#define NRF24L01_TX 0 //发送使能 1:发送 0:接收
#define MOSI_PORT JL_PORTB
#define MOSI_BIT BIT(1)
#define MISO_PORT JL_PORTB
#define MISO_BIT BIT(0)
#define SCK_PORT JL_PORTB
#define SCK_BIT BIT(6)
#define CSN_PORT JL_PORTB
#define CSN_BIT BIT(3)
#define CE_PORT JL_PORTB
#define CE_BIT BIT(5)
#define MOSI_SET(x) do{x?(MOSI_PORT->OUT|=MOSI_BIT):(MOSI_PORT->OUT&=~MOSI_BIT);}while(0)
#define CSN_SET(x) do{x?(CSN_PORT->OUT|=CSN_BIT):(CSN_PORT->OUT&=~CSN_BIT);}while(0)
#define CE_SET(x) do{x?(CE_PORT->OUT|=CE_BIT):(CE_PORT->OUT&=~CE_BIT);}while(0)
#define SCK_SET(x) do{x?(SCK_PORT->OUT|=SCK_BIT):(SCK_PORT->OUT&=~SCK_BIT);}while(0)
#define MISO_DAT() (MISO_PORT->IN&MISO_BIT)
uint8_t const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址
uint8_t const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
void spi_io_init(void)
{
MOSI_PORT->DIR &= ~MOSI_BIT;
MISO_PORT->DIR |= MISO_BIT;
CE_PORT->DIR &= ~CE_BIT;
CE_PORT->OUT &= ~CE_BIT;
CSN_PORT->DIR &= ~CSN_BIT;
CSN_PORT->OUT |= CSN_BIT;
SCK_PORT->DIR &= ~SCK_BIT;
SCK_PORT->OUT &= ~SCK_BIT;
}
void inerDelay_us(unsigned char n)
{
for(;n>0;n--)
asm("nop");
}
uint8_t SPI_RW(uint8_t uchar)
{
uint8_t bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
{
MOSI_SET(uchar & 0x80); // output 'uchar', MSB to MOSI
uchar = (uchar << 1); // shift next bit into MSB..
SCK_SET(1); // Set SCK high..
uchar |= MISO_DAT(); // capture current MISO bit
SCK_SET(0); // ..then set SCK low again
}
return(uchar); // return read uchar
}
uint8_t SPI_Read(uint8_t reg)
{
uint8_t reg_val;
CSN_SET(0); // CSN low, initialize SPI communication...
SPI_RW(reg); // Select register to read from..
reg_val = SPI_RW(0); // ..then read registervalue
CSN_SET(1); // CSN high, terminate SPI communication
return(reg_val); // return register value
}
uint8_t SPI_RW_Reg(uint8_t reg, uint8_t value)
{
uint8_t status;
CSN_SET(0); // CSN low, init SPI transaction
status = SPI_RW(reg); // select register
SPI_RW(value); // ..and write value to it..
CSN_SET(1); // CSN high again
return(status); // return nRF24L01 status uchar
}
uint8_t SPI_Read_Buf(uint8_t reg, uint8_t *pBuf, uint8_t uchars)
{
uint8_t status,uchar_ctr;
CSN_SET(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<uchars;uchar_ctr++)
pBuf[uchar_ctr] = SPI_RW(0); //
CSN_SET(1);
return(status); // return nRF24L01 status uchar
}
uint8_t SPI_Write_Buf(uint8_t reg, uint8_t *pBuf, uint8_t uchars)
{
uint8_t status,uchar_ctr;
CSN_SET(0); //SPI使能
status = SPI_RW(reg);
for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
SPI_RW(*pBuf++);
CSN_SET(1); //关闭SPI
return(status); //
}
void SetRX_Mode(void)
{
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, (uint8_t *)RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收
}
/*
*/
void nRF24L01_RxPacket(unsigned char* rx_buf)
{
unsigned char revale=0;
uint8_t sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况
CE_SET(1);
// printf("R:%x ",sta);
if(sta & BIT(6)) // 判断是否接收到数据
{
CE_SET(0);
printf("R");
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
}
SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
}
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
//printf("s");
CE_SET(0); //StandBy I模式
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, (uint8_t *)RX_ADDRESS, RX_ADR_WIDTH); // 装载接收端地址
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
CE_SET(1); //置高CE,激发数据发送
}
void nrf24l01_irq_init(void);
void NRF24L01_RX_Mode(void)
{
}
/******************************************************************************
* \par Description:
* \param[in] NULL
* \param[out] NULL
* \return NULL
* \ note:
*******************************************************************************/
void init_NRF24L01(void)
{
spi_io_init();
nrf24l01_irq_init();
CE_SET(0);
SPI_Write_Buf(WRITE_REG + TX_ADDR, (uint8_t *)TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, (uint8_t *)RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 频道0自动 ACK应答允许
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Page21
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 设置重发次数
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // 设置信道工作为2.4GHZ,收发必须一致
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为2MHZ,发射功率为最大值0dB
#if (NRF24L01_TX == 0)
SetRX_Mode();
#endif
}
const u8 send_data[32]={0x55,0x5a,0xa5,0xaa};
u8 rx_buf[32];
void nrf24l01_msg_handler(void)
{
#if (NRF24L01_TX == 0)
//nRF24L01_RxPacket(rx_buf);
#endif
}
/******************************************************************************
* \par Description: 1秒消息处理
* \param[in] NULL
* \param[out] NULL
* \return NULL
* \ note:
*******************************************************************************/
void one_second_handler(void)
{
#if (NRF24L01_TX)
nRF24L01_TxPacket((u8 *)send_data);
#endif
}
u8 nrf24l01_rx_buf[32];
/******************************************************************************
* \par Description: 外部中断服务
* \param[in] NULL
* \param[out] NULL
* \return NULL
* \ note:
*******************************************************************************/
void nrf24l01_isr(void)
{
/* CE_SET(0);
uint8_t sta = SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况
printf("%x ",sta);
SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
if (sta & 0x10){
CE_SET(1); // chip enable
SPI_RW_Reg(WRITE_REG+FLUSH_TX,0xff);
}*/
nRF24L01_RxPacket(nrf24l01_rx_buf);
JL_WAKEUP->CON2 |= BIT(12);//clean pending
}
IRQ_REGISTER(IRQ_PORT_IDX, nrf24l01_isr);
/******************************************************************************
* \par Description: 外部中断初始化
* \param[in] NULL
* \param[out] NULL
* \return NULL
* \ note: 下降沿触发
*******************************************************************************/
void nrf24l01_irq_init(void)
{
JL_PORTB->DIR |=BIT(4);
JL_PORTB->DIE |= BIT(4);
JL_PORTB->PU |=BIT(4);
JL_PORTB->PD &=~BIT(4);
printf("*****nrf24l01_irq_init init***\n");
JL_WAKEUP->CON0 |= BIT(12);//检查PA8电平触发
JL_WAKEUP->CON1 |= BIT(12);//下降沿触发
IRQ_REQUEST(IRQ_PORT_IDX, nrf24l01_isr);
}
#endif