小弟刚学STM32f103,用到 无线模块NRF24l01 和 SPI,搞了很久单片机都没检测到 nrf24l01
问题1:SPIx->DR=Data之后,我再用串口传SPIx->DR,发现和Data不一致,而且是乱码
问题2:SPI2的MOSI管脚(PB15)用示波器看不到波形,一直是低电平。CLK是2Mhz的矩形波
描述:管脚连接方面我检查了很多遍了,没有接错; 代码用的原子例程里的无线通信部分,用不了,做了一点点修改还是不行,
不知道我初始化有木有问题呢;
目前一直停留在查找是否存在NRF24l01的步骤。
void SPI2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef *SPI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15; // PB13:CLK PB15:MOSI
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8; //PB7:CE PB8:CSN
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_8);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PB9: IRQ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PG9 êäèë
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_9);
SPI_Cmd(SPI2, DISABLE);
SPI_InitStructure->SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure->SPI_Mode = SPI_Mode_Master;
SPI_InitStructure->SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure->SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure->SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure->SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_InitStructure->SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure->SPI_CRCPolynomial = 7;
SPI_Init(SPI2, SPI_InitStructure);
SPI_Cmd(SPI2, ENABLE);
SPI2_ReadWriteByte(0xff);
}
u8 SPI2_ReadWriteByte(u8 TxData)
{
int retry=0;
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET)
{
retry++;
if(retry>200){
return 0;}
}
SPI2->DR=TxData; =============================================这里出问题了
retry=0;
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET)
{
retry++;
if(retry>200){
return 0;}}
return SPI2->DR;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
/*************************管脚定义************************/
#define NRF24L01_CSNON GPIOB->BSRR = GPIO_Pin_12
#define NRF24L01_CSNOFF GPIOB->BRR = GPIO_Pin_12
#define NRF24L01_CEON GPIOB->BSRR = GPIO_Pin_11
#define NRF24L01_CEOFF GPIOB->BRR = GPIO_Pin_11
/***********************************************************************
外设时钟使能
************************************************************************/
void RCC_Configuration(void)
{
/* 使能外设时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 |
RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC |
RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE
, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //使能复用IO时钟
//注意: 开启TIM2时钟时,不能同时开启USART2时钟
//原因:TIM2,USART2功能使用相同的引脚
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB1Periph_SPI2, ENABLE);/* TIM2 clock enable */
}
void NRF24L01_GPIO_SPI_Configration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
NRF24L01_CSNON;
NRF24L01_CEON;
/* SPI2 NSS SCK MISO MOSI PB12-15 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12;//SPI2的I/O使能
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //NSS 推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //口线翻转速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化函数
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_15|GPIO_Pin_14;//SPI2的I/O使能
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //SCK MOSI MISO复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //口线翻转速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化函数
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); //SPI2 时钟
SPI_I2S_DeInit(SPI2);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//全双工模式(或是半双工)
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//主机模式(Slave从机模式)
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//八位数据(16b十六位)
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;//Low低电平有效(High高)
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//第几个跳变沿传输数据
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//NSS管脚Soft软件控制 Hard是硬件控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;//(8种时钟分频2 4 8 16 32 64 128 256)
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//MSB数据高位在前 LSB低位在前
SPI_InitStructure.SPI_CRCPolynomial = 7;//校验位
SPI_Init(SPI2, &SPI_InitStructure);
SPI_Cmd(SPI2, ENABLE);//使能
}
u8 SPI2_SendData(u8 SPIData)//发送数据函数 数据长度自定
{
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET){}
SPI_I2S_SendData(SPI2,SPIData);
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET){}
return (SPI_I2S_ReceiveData(SPI2));
}
u8 SPI2_ReceiveData(void)//接收数据函数 数据长度自定
{
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET)
{}
return (SPI_I2S_ReceiveData(SPI2));
}
/****************************************************************************************************/
//功能:NRF24L01读写寄存器函数
/****************************************************************************************************/
u8 SPI_RW_Reg(u8 reg, u8 value)
{
u8 status;
NRF24L01_CSNOFF; // CSN low, init SPI transaction
status = SPI2_SendData(reg); // select register
SPI2_SendData(value); // ..and write value to it..
NRF24L01_CSNON; // CSN high again
return(status); // return nRF24L01 status uchar
}
/****************************************************************************************************/
//功能:NRF24L01读寄存器函数
/****************************************************************************************************/
u8 SPI_Read_Reg(u8 reg)
{
u8 reg_val;
NRF24L01_CSNOFF; //使能SPI传输
SPI2_SendData(reg); //发送寄存器号
reg_val = SPI2_SendData(0XFF);//读取寄存器内容
NRF24L01_CSNON; //禁止SPI传输
return(reg_val); //返回状态值
}
/****************************************************************************************************/
//函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
//功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
/****************************************************************************************************/
u8 SPI_Read_Buf(u8 reg, u8 *pBuf, u8 uchars)
{
u8 status,uchar_ctr;
NRF24L01_CSNOFF; // Set CSN low, init SPI tranaction
status = SPI2_SendData(reg); // Select register to write to and read status uchar
for(uchar_ctr = 0;uchar_ctr < uchars;uchar_ctr++)
{
pBuf[uchar_ctr] = SPI2_SendData(0XFF); //
}
NRF24L01_CSNON;
return(status); // return nRF24L01 status uchar
}
/*********************************************************************************************************/
//函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
//功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
/*********************************************************************************************************/
u8 SPI_Write_Buf(u8 reg, u8 *pBuf, u8 uchars)
{
u8 status,uchar_ctr;
NRF24L01_CSNOFF; //SPI使能
status = SPI2_SendData(reg);
for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++)
{
SPI2_SendData(*pBuf++);
}
NRF24L01_CSNON; //关闭SPI
return(status); //
}
u8 nRF24L01_TxPacket(u8 *tx_buf)
{
u8 sta;
NRF24L01_CEOFF; //StandBy I模式
SPI_Write_Buf(WRITE_REGS + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据
NRF24L01_CEON; //置高CE,激发数据发送
OSTimeDly(20);
sta = SPI_Read_Reg(STATUS); //读取状态寄存器的值
SPI_RW_Reg(WRITE_REGS + STATUS,sta); //清除TX_DS或MAX_RT中断标志
if(sta & MAX_TX)//达到最大重发次数
{
SPI_RW_Reg(FLUSH_TX,0xFF);//清除TX FIFO寄存器
return MAX_TX;
}
if(sta & TX_OK)//发送完成
{
return TX_OK;
}
return 0xff;//其他原因发送失败
}
u8 nRF24L01_RxPacket(u8 *rxbuf)
{
u8 sta;
sta = SPI_Read_Reg(STATUS); //读取状态寄存器的值
SPI_RW_Reg(WRITE_REGS + STATUS,sta); //清除TX_DS或MAX_RT中断标志
if(sta & RX_OK)//接收到数据
{
SPI_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
SPI_RW_Reg(FLUSH_RX,0XFF);//清除RX FIFO寄存器
return 0;
}
return 1;//没收到任何数据
}
/****************************************************************************************/
//NRF24L01初始化
/***************************************************************************************/
void TX_NRF24L01(void)
{
NRF24L01_CEOFF; // chip enable
SPI_Write_Buf(WRITE_REGS + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址
SPI_Write_Buf(WRITE_REGS + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
SPI_RW_Reg(WRITE_REGS + EN_AA, 0x01); // 频道0自动 ACK应答允许
SPI_RW_Reg(WRITE_REGS + EN_RXADDR, 0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Page21
SPI_RW_Reg(WRITE_REGS + SETUP_RETR, 0x1a); // 设置自动重发时间和次数:500us + 86us, 10 retrans...
SPI_RW_Reg(WRITE_REGS + RF_CH,40); // 设置信道工作为2.4GHZ,收发必须一致
SPI_RW_Reg(WRITE_REGS + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
SPI_RW_Reg(WRITE_REGS + RF_SETUP, 0x0F); //设置发射速率为1MHZ,发射功率为最大值0dB
SPI_RW_Reg(WRITE_REGS + CONFIG, 0x0E); // IRQ收发完成中断响应,16位CRC ,主接收
NRF24L01_CEON; // chip enable
}
void RX_NRF24L01(void)
{
NRF24L01_CEOFF;
SPI_Write_Buf(WRITE_REGS+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址
SPI_RW_Reg(WRITE_REGS+EN_AA,0x01); //使能通道0的自动应答
SPI_RW_Reg(WRITE_REGS+EN_RXADDR,0x01); //使能通道0的接收地址
SPI_RW_Reg(WRITE_REGS+RF_CH,40); //设置RF通信频率
SPI_RW_Reg(WRITE_REGS+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度
SPI_RW_Reg(WRITE_REGS+RF_SETUP,0x0F); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启
SPI_RW_Reg(WRITE_REGS+CONFIG, 0x0F); //配置基本工作模式的参数
NRF24L01_CEON; //CE为高,进入接收模式
}
一周热门 更多>