This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TM4C129XNCZAD:与 W25Q128JV 闪存的 SPI 通信不工作。

Guru**** 2390995 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1084051/tm4c129xnczad-spi-communication-with-w25q128jv-flash-memory-not-working

部件号:TM4C129XNCZAD

大家好,我正在尝试用  Winbond 写入 W25Q128JV 闪存并从中读取。 我现在有一个简单的代码,该代码应该启用写入操作并读回状态寄存器1的值,状态寄存器1在位-1上具有写入启用状态。 尽管写入启用状态的预期值为0x02,但读取上的所有0仍是如此。 如果我不能确定是我的写作还是阅读有问题,我将非常感谢您的帮助。

下面是我的代码:

//Disable the SSI module to change the settings for Memory communication.
SSIDisable(SSI3_BASE);

//make sure the polarity and phase configuration is correct for Memory communication
SSIConfigSetExpClk(SSI3_BASE, ui32SysClock, SSI_FRF_MOTO_MODE_3, SSI_MODE_MASTER, 2000000 , 8);

//Enable the SSI module after settings change.
SSIEnable(SSI3_BASE);

GPIOPinWrite(PQ_SPI_PORT, PQ1_SPI_SS_MEMORY_PIN, 0x0);

//Send the data over SPI.
SSIDataPut(SSI3_BASE, 0x06 );
while(SSIBusy(SSI3_BASE)){

}
//Turn SS pin high to finish write enable.
GPIOPinWrite(PQ_SPI_PORT, PQ1_SPI_SS_MEMORY_PIN, PQ1_SPI_SS_MEMORY_PIN);

GPIOPinWrite(PQ_SPI_PORT, PQ1_SPI_SS_MEMORY_PIN, 0x0);

//Send the data over SPI.
SSIDataPut(SSI3_BASE, 0x05 );

SSIDataGet(SSI3_BASE, (uint32_t *) &Laser.Miscellaneous.Monitor.TECSupplyVoltage);
while(SSIBusy(SSI3_BASE)){

}

GPIOPinWrite(PQ_SPI_PORT, PQ1_SPI_SS_MEMORY_PIN, PQ1_SPI_SS_MEMORY_PIN);

下面是我的 SPI 初始化代码:

uint32_t ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                            SYSCTL_OSC_MAIN |
                                            SYSCTL_USE_PLL |
                                            SYSCTL_CFG_VCO_240), 50000000);

//enable the pins used for SPI communication.
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ);

while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOQ)){

}
//
// Configure the SS pin and communication pins as GPIO output pins.
//
GPIOPinTypeGPIOOutput(PQ_SPI_PORT, (PQ3_SPI_RX_PIN              |
                                    PQ1_SPI_SS_MEMORY_PIN       |
                                    PQ4_SPI_SS_DIGIPOT_PIN      |
                                    PQ5_SPI_SS_DAC_PIN));

//drive the clear pin high.
GPIOPinWrite(PQ_SPI_PORT, PQ3_SPI_RX_PIN, PQ3_SPI_RX_PIN);

//
// Enable the SSI3 peripheral
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI3);

while(!SysCtlPeripheralReady(SYSCTL_PERIPH_SSI3)){

}

GPIOPinConfigure(GPIO_PQ0_SSI3CLK);
GPIOPinConfigure(GPIO_PQ2_SSI3XDAT0);

GPIOPinTypeSSI(PQ_SPI_PORT, (   PQ0_SPI_CLK_PIN         |
                                PQ2_SPI_TX_PIN          ));

//
// Configure the SSI.
//
SSIConfigSetExpClk(SSI3_BASE, ui32SysClock, SSI_FRF_MOTO_MODE_3, SSI_MODE_MASTER, 2000000 , 12);

//
//Enable the SSI module
//
SSIEnable(SSI3_BASE);

//Set the SS pins to high to disable communication.
GPIOPinWrite(PQ_SPI_PORT, PQ1_SPI_SS_MEMORY_PIN, PQ1_SPI_SS_MEMORY_PIN);
GPIOPinWrite(PQ_SPI_PORT, PQ4_SPI_SS_DIGIPOT_PIN, PQ4_SPI_SS_DIGIPOT_PIN);
GPIOPinWrite(PQ_SPI_PORT, PQ5_SPI_SS_DAC_PIN, PQ5_SPI_SS_DAC_PIN);

SSIIntEnable(SSI3_BASE, SSI_TXFF);

以下是数据表中的启用写入和读取状态寄存器1说明:

据我所知,此设备应该可以与模式0 或模式3 SPI 通信配合使用,我已经尝试了这两种方式。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,

     我感到困惑的是,您在两个不同的位置将 SSI 字符长度设置为8和12。 你想要哪一个? 我建议您使用逻辑分析器或范围来查看 SPI 接口上正在写入和读取的内容。 这将极大地帮助您进行调试。 我还看到,您 首先断言 CS 引脚过低,在写入后,您将断言 CS 引脚过高。 然后,您在读取前再次断言 CS 针脚过低,然后再次断言 CS 针脚过高。 但是,查看随附的计时图8a,CS 必须在写入和读取过程中处于活动状态。 这可能是您的问题,因为闪存可能会认为您在 CS 运行较高时终止了命令。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    字符长度的变化是因为我有多个设备通过 SPI 进行通信,而对于大约12个设备,比8更容易。 我切换 CS 引脚高是因为,据我了解,要使写入功能能够注册到状态寄存器,我需要在执行任何其他指令之前先将引脚高切换。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,

     这不是我从你们的时间图中看到的。 在指令阶段和数据阶段,CS 处于活动低电平状态。 无论如何,您应该使用逻辑分析器来确保 SPI 总线上的定时与图中所示相匹配。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我发现了这个问题,我将 RX 引脚定义为输出,因为其中一个设备需要将其驱动到较高位置才能正常工作,并且永远不会将其设置回 SSI,从而根据与修正后的设备通信更改配置。 此外,我还需要在发送 read 命令后调用另一个 SSIDataPut,以确保为读取数据断言时钟。