论坛» DIY与开源设计» 电子DIY

SPI启动无线收发模块的问题(检测不到nrf模块)

菜鸟
2014-05-12 20:38 1楼

首先,我用的是手柄做的无线模块的检测,通过写入一个地址然后读出,来检测无线收发模块是否存在。

spi配置:


void SPI_Configuration() { SPI_InitTypeDef SPI_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB1Periph_SPI2| RCC_APB2Periph_GPIOA| RCC_APB2Periph_GPIOB| RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15|GPIO_Pin_13; //PB13-SCK PB15-MOSI GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;//PB14-MISO GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14;//PC13-CSN PC14-CE GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; //PC15-IPU GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOC, &GPIO_InitStructure); /* 配置SPI1模块 初始化*/ SPI_I2S_DeInit(SPI2); SPI_Cmd(SPI2, DISABLE); //必须先禁用,才能改变MODE SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //两线全双工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //CPOL=0 时钟悬空低 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //CPHA=0 数据捕获第1个 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //软件NSS SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4 ; //256分频 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB; //高位在前 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC7 SPI_Init(SPI2, &SPI_InitStructure); SPI_Cmd(SPI2, ENABLE); //SPI_ReadWriteByte(0xff); //启动传输 }

nrf init

//24L01片选信号 #define CE_H() GPIO_SetBits(GPIOC, GPIO_Pin_14) #define CE_L() GPIO_ResetBits(GPIOC, GPIO_Pin_14) //SPI片选信号 #define CSN_H() GPIO_SetBits(GPIOC, GPIO_Pin_13) #define CSN_L() GPIO_ResetBits(GPIOC, GPIO_Pin_13)

void NRF24L01_Init(void) { CE_L(); //使能24L01 CSN_H(); //SPI片选取消 }

spi 字节收发

u8 SPI_ReadWriteByte(u8 data) { u8 temp; printf(" Enter SPIRW%d\n ",data); while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); /* Send SPI2 data */ SPI_I2S_SendData(SPI2, data); printf(" send ok "); while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET); /* Read SPI2 received data */ temp = SPI_I2S_ReceiveData(SPI2); printf(" Leave SPIRW%d\n ",temp); return temp; //返回收到的数据 }

每次都会死在这一句

while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);


mian 函数相关部分

SPI_Configuration(); NRF24L01_Init(); //printf("aaaUART SUCCESS!!!");Delay(0x1EFF); if(NRF24L01_Check()==0) printf(" nrf check success"); while (1) {}

其中NRF24L01_Check:

u8 NRF24L01_Check(void) { u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5}; u8 i; SPI2_SetSpeed(SPI_SPEED_8); //spi速度为9Mhz(24L01的最大SPI时钟为10Mhz) NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,buf,5);//写入5个字节的地址. NRF24L01_Read_Buf(TX_ADDR,buf,5); //读出写入的地址 for(i=0;i<5;i++)if(buf[i]!=0XA5)break; if(i!=5)return 1;//检测24L01错误 return 0; //检测到24L01 }

每次spi发送就会死机,求大神解答!!!



高工
2014-05-12 21:05 2楼

楼主你好。这个问题,请看这:http://forum.eepw.com.cn/thread/248747/5#43

SPI2是挂在APB1上的,而SPI1才是挂在APB2上~

菜鸟
2014-05-12 23:12 3楼
手柄上不是使用的spi2吗?我现在还只是检测无线模块存不存在,就死在发送等待那句话了,悲剧。刚才我看了你分享的代码,发送那个工程里使用的是spi1,这让我很困惑,难道我理解有误?
菜鸟
2014-05-12 23:19 4楼
哦哦,我知道了,应该用RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2)对不对,傻逼了,我试试。
高工
2014-05-12 23:55 5楼
这里是个容易犯错的地方,所以在我的进程贴子里就有专门说明。 现在怎么样啦,测试通过没
菜鸟
2014-05-13 00:52 6楼
还是没搞定,不会死在那个地方了,现在状况是这样的:我写TX_ADDR然后读取,读出来全是0。详情再下一层
菜鸟
2014-05-13 00:59 7楼

代码:

u8 NRF24L01_Check(void) { u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5}; u8 i; SPI2_SetSpeed(SPI_SPEED_8); //spi速度为9Mhz(24L01的最大SPI时钟为10Mhz) NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,buf,5);//写入5个字节的地址. NRF24L01_Read_Buf(TX_ADDR,buf,5); //读出写入的地址 for(i=0;i<5;i++)if(buf[i]!=0XA5)break; printf("i=%d\n",i); if(i!=5)return 1;//检测24L01错误 return 0; //检测到24L01 }

u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len) { u8 status,u8_ctr; CSN_L(); //使能SPI传输 status=SPI_ReadWriteByte(reg); //发送寄存器值(位置),并读取状态值 for(u8_ctr=0;u8_ctr
        

u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len) { u8 status,u8_ctr; CSN_L(); //使能SPI传输 status = SPI_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值 for(u8_ctr=0; u8_ctr
        

u8 SPI_ReadWriteByte(u8 data) { u8 temp; printf(" W%d \n ",data); while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); /* Send SPI2 data */ SPI_I2S_SendData(SPI2, data); while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET); /* Read SPI2 received data */ temp = SPI_I2S_ReceiveData(SPI2); printf(" R%d \n ",temp); return temp; //返回收到的数据 }

现在调用NRF24L01_Check,打印消息如下

W48
R112
W165
R195
W165
R195
W165
R195
W165
R195
W165
R195
W16
R112
W255
R0
W255
R0
W255
R0
W255
R0
W255
R0
i=0

就是写进去的地址跟读出来的不一样

高工
2014-05-13 09:53 8楼
中午回宿舍给你看看啊,在上课用手机看不完整程序
高工
2014-05-13 13:19 9楼

楼主,你主函数里

if(NRF24L01_Check()==0)

  • printf(" nrf check success‘}
  • 运行结果如何?

    现在SPI初始化正确了是吗?

    、、、、、、、、、、、、、、、、、、、、、、、、、

    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;

    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; 这是八分频,9MHZ,你程序中是4分频,SPI8分频足以。。。。

    。。。

    然后你程序里还有一句“ SPI2_SetSpeed(SPI_SPEED_8);//spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)

    感觉你的程序有点混乱,是网上借鉴的吗。

    可参考一下昨晚给你的链接,你里有我的工程。

    在那个帖子里,我把移植的飞控代码都开源了,你也可以参考一下

    高工
    2014-05-14 11:22 10楼

    写入数据不对

    还是SPI有问题啊

    撸主是不是漏掉什么重要环节了?

    共10条 1/1 1 跳转至

    回复

    匿名不能发帖!请先 [ 登陆 注册]