野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 10264|回复: 6

[求助]有关STM32F429驱使nrf24L01的问题

[复制链接]
发表于 2017-8-6 11:27:24 | 显示全部楼层 |阅读模式
本帖最后由 wa163 于 2017-8-6 11:32 编辑

使用STM32F429IGT6驱使nrf24l01,移植的野火产品中F103的nrfZ24l01的资料:
http://www.firebbs.cn/forum.php? ... 2686&extra=page%3D1

把F103的库都换成了F429的固件库,然后修改了部分引脚初始化的地方。
结果使用示波器测试spi各输出引脚波形,结果均无波形。看了半天代码,没看出那儿的问题,特来寻求解答
主要代码如下。
主函数:


//***SPI_NRF2_Init函数
void SPI_NRF2_Init(void){
  SPI_InitTypeDef  SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  
  /*开启相应IO端口的时钟*/
  //RCC_APB2PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);

/*使能SPI2时钟*/
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
   
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;  
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
   
   /*配置 SPI_NRF_SPI的 SCK,MISO,MOSI引脚,GPIOA^13,GPIOA^14,GPIOA^15 */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);  

  /*配置SPI_NRF_SPI的CE引脚,和SPI_NRF_SPI的 CSN 引脚*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);


   /*配置SPI_NRF_SPI的IRQ引脚*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN ;  //上拉输入
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
         
  /* 这是自定义的宏,用于拉高csn引脚,NRF进入空闲状态 */
  NRF2_CSN_HIGH();

  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;                         //时钟极性,空闲时为低
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;                        //第1个边沿有效,上升沿为采样时刻
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                               //NSS信号由软件产生
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;  //8分频,9MHz
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                  //高位在前
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI2, &SPI_InitStructure);

  /* Enable SPI2  */
  SPI_Cmd(SPI2, ENABLE);
}//***SPI_NRF2_Init-end

//***Self_Test函数
void Self_Test(void)
{
  /*检测NRF模块与MCU的连接*/
  status = NRF_Check();

  /*判断连接状态*/  
  if(status == SUCCESS)      
    printf("\r\n      NRF1与MCU连接成功!\r\n");  
  else      
    printf("\r\n  NRF1与MCU连接失败,请重新检查接线。\r\n");
   
   
      /*检测NRF模块与MCU的连接*/
  status = NRF2_Check();
   
      /*判断连接状态*/  
  if(status == SUCCESS)      
    printf("\r\n      NRF2与MCU连接成功!\r\n");  
  else      
    printf("\r\n  NRF2与MCU连接失败,请重新检查接线。\r\n");

  while(1)
  {
    printf("\r\n 主机端 进入自应答发送模式\r\n");
    NRF_TX_Mode();
        
        printf("\r\n 从机端 进入接收模式\r\n");
    NRF2_RX_Mode();

    /*开始发送数据*/   
    status = NRF_Tx_Dat(txbuf);      

    /*判断发送状态*/
    switch(status)
    {
      case MAX_RT:
        printf("\r\n 主机端 没接收到应答信号,发送次数超过限定值,发送失败。 \r\n");
      break;

      case ERROR:
        printf("\r\n 未知原因导致发送失败。 \r\n");
      break;

      case TX_DS:
        printf("\r\n 主机端 接收到 从机端 的应答信号,发送成功! \r\n");            
      break;                                 
    }                  
        
        
        /*等待接收数据*/
    status = NRF2_Rx_Dat(rxbuf);

    /*判断接收状态*/
    if(status == RX_DR)
    {
      for(i=0;i<4;i++)
      {   
        printf("\r\n 从机端 接收到 主机端 发送的数据为:%d \r\n",rxbuf);
        /*把接收的数据+1后发送给主机*/
        rxbuf+=1;      
        txbuf = rxbuf;
      }
    }   
        
    printf("\r\n 从机端 进入自应答发送模式\r\n");
    NRF2_TX_Mode();
        
        

    printf("\r\n 主机端 进入接收模式。 \r\n");   
    NRF_RX_Mode();
        
         /*不断重发,直至发送成功*/      
    do
    {      
      status = NRF2_Tx_Dat(txbuf);
    }while(status == MAX_RT);

    /*等待接收数据*/
    status = NRF_Rx_Dat(rxbuf);

    /*判断接收状态*/
    switch(status)
    {
      case RX_DR:
      for(i=0;i<4;i++)
      {                    
        printf("\r\n 主机端 接收到 从机端 发送的数据为:%d \r\n",rxbuf);
        txbuf =rxbuf;
      }
      break;

      case ERROR:
        printf("\r\n 主机端 接收出错。   \r\n");
      break;         
    }
  }// while(1)

}//***Self_Test-end

//***NRF_Check函数
u8 NRF_Check(void)
{
    u8 buf[5]={0xC2,0xC2,0xC2,0xC2,0xC2};
    u8 buf1[5];
    u8 i;
     
    /*写入5个字节的地址.  */  
    SPI_NRF_WriteBuf(NRF_WRITE_REG+TX_ADDR,buf,5);

    /*读出写入的地址 */
    SPI_NRF_ReadBuf(TX_ADDR,buf1,5);
     
    /*比较*/               
    for(i=0;i<5;i++)
    {
        if(buf1!=0xC2)
        break;
    }
           
    if(i==5)
        return SUCCESS ;        //MCU与NRF成功连接
    else
        return ERROR ;        //MCU与NRF不正常连接
}//***NRF_Check-end

//***SPI_NRF_WriteBuf函数
u8 SPI_NRF_WriteBuf(u8 reg ,u8 *pBuf,u8 bytes)
{
     u8 status,byte_cnt;
     NRF_CE_LOW();
        /*置低CSN,使能SPI传输*/
     NRF_CSN_LOW();            

     /*发送寄存器号*/   
       status = SPI_NRF_RW(reg);
     
        /*向缓冲区写入数据*/
     for(byte_cnt=0;byte_cnt<bytes;byte_cnt++)
        SPI_NRF_RW(*pBuf++);    //写数据到缓冲区      
            
    /*CSN拉高,完成*/
    NRF_CSN_HIGH();            
  
      return (status);    //返回NRF24L01的状态         
}//***SPI_NRF_WriteBuf-end


回复

使用道具 举报

 楼主| 发表于 2017-8-6 11:30:10 | 显示全部楼层
主函数发的图片,图片没有显示,补充在这儿。
/**
  * @brief  主函数
  * @param  无
  * @retval 无
  */
int main(void)                  
{
        /* 初始化NRF1 */
  SPI_NRF_Init();        
        /* 初始化NRF2 */
        SPI_NRF2_Init();

  /* 串口1初始化 */
  //USART1_Config();
        Debug_USART_Config();
        
  printf("\r\n 这是一个 NRF24L01 无线传输实验 \r\n");
  printf("\r\n 这是无线传输 主机端 的反馈信息\r\n");
  printf("\r\n   正在检测NRF与MCU是否正常连接。。。\r\n");

        Self_Test();
}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-8-6 20:02:15 | 显示全部楼层
本帖最后由 wa163 于 2017-8-6 20:03 编辑

下午自己使用IO口模拟写了spi的读操作和写操作,替换掉了使用的SPI_I2S_ReceiveData和SPI_I2S_SendData以及修改了一些地方的延时,就好使了。
附上函数代码,供参考:
  1. #define MISO                                                                                                       GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)
  2. #define SCK_HIGH                                                                                                GPIO_SetBits(GPIOG,GPIO_Pin_3)
  3. #define SCK_LOW                                                                                                 GPIO_ResetBits(GPIOG,GPIO_Pin_3)
  4. #define MOSI_HIGH                                                                                              GPIO_SetBits(GPIOG,GPIO_Pin_2)
  5. #define MOSI_LOW                                                                                               GPIO_ResetBits(GPIOG,GPIO_Pin_2)
复制代码
  1. /*<延时函数10us>*/
  2. void delay(){
  3.         int i=0;
  4.         for(i=0;i<357;i++){
  5.                 __ASM("NOP");
  6.         }
  7. }
复制代码
  1. /*<SPI写操作
  2. *MOSI:G2 SCK:G3 MISO:A8
  3. >*/
  4. void NRF_SpiWrite(uchar byte){
  5.         uchar i;
  6.         uchar flag;
  7.         uchar data_buf = byte;
  8.         for(i=0;i<8;i++){
  9.                 flag=data_buf&0x80;                             //从高位开始发送
  10.                 if(flag){                                                //flag=data_buf^7
  11.                         MOSI_HIGH;
  12.                         delay();                                        //延时函数-10us
  13.                 }else{
  14.                         MOSI_LOW;
  15.                         delay();
  16.                 }
  17.                 SCK_HIGH;                                           //SCK给高电平
  18.                 delay();
  19.                 data_buf = data_buf<<1;
  20.                 SCK_LOW;                                           //SCK给低电平
  21.                 delay();
  22.         }
  23. }


  24. /*<SPI读操作
  25. *MOSI:G2 SCK:G3 MISO:A8
  26. >*/
  27. uchar NRF_SpiRead(void){
  28.         uchar i;
  29.         uchar flag;
  30.         uchar data_buf;
  31.         for(i=0;i<8;i++){
  32.                 data_buf = data_buf<<1;
  33.                 SCK_HIGH;
  34.                 delay();
  35.                 if(MISO){
  36.                         flag=1;
  37.                 }else{
  38.                         flag=0;
  39.                 }
  40.                 data_buf += flag;
  41.                 SCK_LOW;
  42.                 delay();
  43.         }
  44.         return (data_buf);
  45. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2017-8-7 08:13:17 | 显示全部楼层
好尴尬,没人鸟你
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-8-7 08:14:29 | 显示全部楼层
hello银 发表于 2017-8-7 08:13
好尴尬,没人鸟你

自言自语
回复 支持 反对

使用道具 举报

发表于 2017-8-7 18:11:02 | 显示全部楼层
还是没人鸟你
回复 支持 反对

使用道具 举报

发表于 2018-6-2 09:27:24 | 显示全部楼层
楼主,f429硬件SPI与nrf42L01通讯成功了吗??我也出问题了:SPI2初始配置都对,只是读写寄存器就不对了,修改SCK空闲电平及采样边沿得到不同数据,,,探讨一下呗
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-23 14:50 , Processed in 0.063429 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表