求助STM32F4的SPI随机死掉问题

2019-12-11 18:23发布

这两天在调试STM32使用SPI操作W5500时,遇到个问题。
先上代码:


SPI初始化代码:
/*名称:bspW5500_initIO
*功能:初始化W5500使用的SPI4及相关IO:
                SPI4_SCK        ----        PE2
                SPI4_NSS        ----        PE4(根据W5500的SPI接口时序,此引脚由软件控制)
                SPI4_MISO        ----        PE5
                SPI4_MOSI        ----        PE6
                -------------------
                W5500_RST        ----        PG11
                W5500_INT        ----        PG15(此引脚暂不使用,使用轮训模式查询W5500寄存器)
*输入:无
*输出:无*/
void bspW5500_initIO(void)
{
    //库函数版本
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitTypeDef GPIO_InitStructure;
    SPI_InitTypeDef SPI_InitStruct;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI4,ENABLE);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource2,  GPIO_AF_SPI4);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource5, GPIO_AF_SPI4);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource6, GPIO_AF_SPI4);

    GPIO_InitStruct.GPIO_Pin =  GPIO_Pin_2 | GPIO_Pin_5 | GPIO_Pin_6;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd  = GPIO_PuPd_DOWN;
    GPIO_Init(GPIOE, &GPIO_InitStruct);
    //初始化片选输出引脚
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOE, &GPIO_InitStruct);
    GPIO_SetBits(GPIOE,GPIO_Pin_4);

    SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
    SPI_InitStruct.SPI_Direction= SPI_Direction_2Lines_FullDuplex;
    SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
    SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
    SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
    SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStruct.SPI_CRCPolynomial = 7;
    SPI_Init(SPI4,&SPI_InitStruct);
    SPI_Cmd(SPI4, ENABLE);

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);

    /*定义RESET引脚*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;                                                 /*选择要控制的GPIO引脚*/
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 /*设置引脚速率为50MHz*/
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;                     /*设置引脚模式为通用推挽输出*/
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_Init(GPIOG, &GPIO_InitStructure);                                                         /*调用库函数,初始化GPIO*/
    GPIO_SetBits(GPIOG, GPIO_Pin_11);
    /*定义INT引脚*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;                                                 /*选择要控制的GPIO引脚*/
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 /*设置引脚速率为50MHz */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;                                 /*设置引脚模式为通用推挽模拟上拉输入*/
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
    GPIO_Init(GPIOG, &GPIO_InitStructure);                                                         /*调用库函数,初始化GPIO*/

}

SPI读写字节代码:
/*名称:bspW5500_spiShiftByte()
*功能:SPI线上移位一字节
*输入:txDat-移出的字节
*返回:移入的字节*/
INT8U bspW5500_spiShiftByte(INT8U txDat)
{
    INT32U retry = 0;
    while(0 == (SPI4->SR & SPI_I2S_FLAG_TXE))        //等待发送区空
    {}
    SPI4->DR = txDat;                                                   //发送一个byte
    while(0 == (SPI4->SR & SPI_I2S_FLAG_RXNE))//等待接收完一个byte
    {
        retry++;                //超时计数器
        if(retry > 45000000)  //时间应该够长,示波器看波形消失时间达到几秒
            return 0;      //随机进入此处断点
    }
    return (SPI4->DR);
}


现象:while(1)中持续调用bspW5500_spiShiftByte(),跑一段后,会进入重试超时检测部分代码。超时之后程序继续跑,接着再次进入超时检测部分。
是我哪里设置的不对?


谢谢大家!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。