这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » SPI启动无线收发模块的问题(检测不到nrf模块)

共10条 1/1 1 跳转至

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

菜鸟
2014-05-12 20:38:46     打赏

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

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:11     打赏
2楼

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

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


菜鸟
2014-05-12 23:12:27     打赏
3楼
手柄上不是使用的spi2吗?我现在还只是检测无线模块存不存在,就死在发送等待那句话了,悲剧。刚才我看了你分享的代码,发送那个工程里使用的是spi1,这让我很困惑,难道我理解有误?

菜鸟
2014-05-12 23:19:20     打赏
4楼
哦哦,我知道了,应该用RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2)对不对,傻逼了,我试试。

高工
2014-05-12 23:55:09     打赏
5楼
这里是个容易犯错的地方,所以在我的进程贴子里就有专门说明。 现在怎么样啦,测试通过没

菜鸟
2014-05-13 00:52:33     打赏
6楼
还是没搞定,不会死在那个地方了,现在状况是这样的:我写TX_ADDR然后读取,读出来全是0。详情再下一层

菜鸟
2014-05-13 00:59:31     打赏
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<len;u8_ctr++)
		pBuf[u8_ctr]=SPI_ReadWriteByte(0XFF);//读出数据
	CSN_H();                             //禁止SPI传输
	return status;                       //返回读到的状态值
}

 

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<len; u8_ctr++)
		SPI_ReadWriteByte(*pBuf++);     //写入数据  
	CSN_H();                        //关闭SPI传输
	return status;                  //返回读到的状态值
}

 

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:27     打赏
8楼
中午回宿舍给你看看啊,在上课用手机看不完整程序

高工
2014-05-13 13:19: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:54     打赏
    10楼

    写入数据不对

    还是SPI有问题啊

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


    共10条 1/1 1 跳转至

    回复

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