不知道为什么了,经常用到NRF程序,换到新做的板子上自检就一直不通过,硬件检测了,我把SPI1和NRF其他的脚全都设成推挽输出,然后全给高,万用表都能测出是3.3V,但是不知道为什么自检通不过。求大神们帮忙。
SPI_InitTypeDef SPI_InitStructure;
1,SPI1的程序
void SPI1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );// |RCC_APB2Periph_SPI1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //串行同步时钟的空闲状态为高电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; //定义波特率预分频的值:波特率预分频值为4
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
SPI_Cmd(SPI1, ENABLE); //使能SPI外设
}
//SPI 速度设置函数
//SpeedSet:
//SPI_BaudRatePrescaler_2 2分频 (SPI 36M
@sys 72M)
//SPI_BaudRatePrescaler_8 8分频 (SPI 9M@sys 72M)
//SPI_BaudRatePrescaler_16 16分频 (SPI 4.5M@sys 72M)
//SPI_BaudRatePrescaler_256 256分频 (SPI 281.25K@sys 72M)
void SPI1_SetSpeed(u8 SpeedSet)
{
SPI1->CR1&=0XFFC7;
SPI1->CR1|=SpeedSet; //设置SPI1速度
SPI1->CR1|=1<<6; //SPI设备使能
}
//SPIx 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI1_ReadWriteByte(u8 TxData)
{
u8 retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
{
retry++;
if(retry>200)return 0;
}
SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据
retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)//检查指定的SPI标志位设置与否:接受缓存非空标志位
{
retry++;
if(retry>200)return 0;
}
return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据
}
2,NRF的程序
u8 TX_ADDRESS[TX_ADR_WIDTH]= {0x01,0x23,0x45,0x67,0x89}; //本地地址
u8 RX_ADDRESS[RX_ADR_WIDTH]= {0x01,0x23,0x45,0x67,0x89}; //接收地址
//写寄存器
static u8 NRF24L01_Write_Reg(u8 reg, u8 value)
{
u8 status;
NRF24L01_CSN = 0; /* 选通器件 */
status = NRF24L01_ReadWriteByte(reg); /* 写寄存器地址 */
NRF24L01_ReadWriteByte(value); /* 写数据 */
NRF24L01_CSN = 1; /* 禁止该器件 */
return status;
}
//读寄存器
static u8 NRF24L01_Read_Reg(u8 reg)
{
u8 reg_val;
NRF24L01_CSN = 0; /* 选通器件 */
NRF24L01_ReadWriteByte(reg); /* 写寄存器地址 */
reg_val = NRF24L01_ReadWriteByte(0); /* 读取该寄存器返回数据 */
NRF24L01_CSN = 1; /* 禁止该器件 */
return reg_val;
}
//写缓冲区
static u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len)
{
u8 i,status;
NRF24L01_CSN = 0; /* 选通器件 */
status = NRF24L01_ReadWriteByte(reg); /* 写寄存器地址 */
for(i=0; i<len; i++)
{
NRF24L01_ReadWriteByte(*pBuf++); /* 写数据 */
}
NRF24L01_CSN = 1; /* 禁止该器件 */
return status;
}
//读缓冲区
static u8 NRF24L01_Read_Buf(u8 reg, u8 *pBuf, u8 len)
{
u8 i,status;
NRF24L01_CSN = 0; /* 选通器件 */
status = NRF24L01_ReadWriteByte(reg); /* 写寄存器地址 */
for(i=0; i<len; i++)
{
pBuf
= NRF24L01_ReadWriteByte(0XFF); /* 读取返回数据 */
}
NRF24L01_CSN = 1; /* 禁止该器件 */
return status;
}
//写数据包
void NRF24L01_TxPacket(u8 * tx_buf,u8 len)
{
NRF24L01_CE = 0; //CE拉低,使能24L01配置
NRF24L01_Write_Buf(NRF_WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
NRF24L01_Write_Buf(WR_TX_PLOAD, tx_buf, len);
NRF24L01_CE = 1; //CE拉低,使能24L01配置
}
void NRF24L01_TxPacket_AP(uint8_t * tx_buf, uint8_t len)
{
// NRF24L01_SPI_MODE();
NRF24L01_CE = 0; //StandBy I模式
NRF24L01_Write_Buf(0xa8, tx_buf, len); // 装载数据
NRF24L01_CE = 1; //置高CE
}
u8 NRF24L01_Check(void)
{
u8 buf[5];
u8 i;
/*写入5个字节的地址. */
NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,(u8 *)TX_ADDRESS,5);
/*读出写入的地址 */
NRF24L01_Read_Buf(TX_ADDR,buf,5);
/*比较*/
for(i=0;i<5;i++)
{
if(buf!=TX_ADDRESS)
break;
}
if(i==5)
return SUCCESS ; //MCU与NRF成功连接
else
return ERROR ; //MCU与NRF不正常连接
}
//初始化24L01的IO口
u8 NRF24L01_Init(u8 model, u8 ch)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE); //使能PA端口时钟 //IRQ-PB0 //CSN-PA3 CE-PA4
//CE脚配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_4);
//CS脚配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_3);
//IRQ脚配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU;// GPIO_Mode_IPU ; //上拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_0);
NRF24L01_CSN=1;
SPI1_Init();
NRF24L01_CE=0;
NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH); //写RX节点地址
NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH); //写TX节点地址
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01);//使能通道0的接收地址
NRF24L01_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us;最大自动重发次数:10次
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,ch);//设置RF通道为CHANAL
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x2f);//设置TX发射参数,0db增益,250Kbps,低噪声增益开启
if(model==1) //RX
{
NRF24L01_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH); //选择通道0的有效数据宽度
NRF24L01_Write_Reg(NRF_WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断开启,16位CRC,主接收
}
else if(model==2) //TX
{
NRF24L01_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH); //选择通道0的有效数据宽度
NRF24L01_Write_Reg(NRF_WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断开启,16位CRC,主发送
}
else if(model==3) //RX2
{
NRF24L01_Write_Reg(FLUSH_TX,0xff);
NRF24L01_Write_Reg(FLUSH_RX,0xff);
NRF24L01_Write_Reg(NRF_WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断开启,16位CRC,主接收
NRF24L01_ReadWriteByte(0x50);
NRF24L01_ReadWriteByte(0x73);
NRF24L01_Write_Reg(NRF_WRITE_REG+0x1c,0x01);
NRF24L01_Write_Reg(NRF_WRITE_REG+0x1d,0x06);
}
else //TX2
{
NRF24L01_Write_Reg(NRF_WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断开启,16位CRC,主发送
NRF24L01_Write_Reg(FLUSH_TX,0xff);
NRF24L01_Write_Reg(FLUSH_RX,0xff);
NRF24L01_ReadWriteByte(0x50);
NRF24L01_ReadWriteByte(0x73);
NRF24L01_Write_Reg(NRF_WRITE_REG+0x1c,0x01);
NRF24L01_Write_Reg(NRF_WRITE_REG+0x1d,0x06);
}
NRF24L01_CE=1;
return 0;
}
void NRF24L01_CheckEvent(u8 *NRF24L01_RXDATA)
{
static u8 cnt_lost=0;
u8 rx_len;
u8 sta;
sta = NRF24L01_Read_Reg(NRF_READ_REG + NRF_REG_STATUS); //读取到数据,相关位置1
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
if(sta & (1<<RX_DR))
{
cnt_lost=0;
rx_len= NRF24L01_Read_Reg(R_RX_PL_WID); //返回值:读取到的字节
NRF24L01_Read_Buf(RD_RX_PLOAD,NRF24L01_RXDATA,rx_len);//将读到的字节存储到入口数组里
ReceiveData(NRF24L01_RXDATA,rx_len);
}
else
{
if(++cnt_lost>=150)
{
cnt_lost=150;
// LED0 = ~LED0;
}
}
cnt_lost=0;
if(sta & (1<<TX_DS))
{
}
if(sta & (1<<MAX_RT))
{
if(sta & 0x01) //TX FIFO FULL
{
NRF24L01_Write_Reg(FLUSH_TX,0xff);
}
}
NRF24L01_Write_Reg(NRF_WRITE_REG + NRF_REG_STATUS, sta);
}
一周热门 更多>