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.

[参考译文] TM4C129ENCPDT:SST25VF016B 闪存 EEPROM SPI 问题

Guru**** 2464780 points
Other Parts Discussed in Thread: TM4C129ENCPDT

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/660300/tm4c129encpdt-sst25vf016b-flash-eeprom-spi-problem

器件型号:TM4C129ENCPDT

您好!

我尝试在 TM4C129ENCPDT 和 SST25VF016B 之间使用 SPI 通信。

我在论坛中阅读了其他一些文章、但无法实现任何字节的发送和读取。  我可以读取 JEDEC ID。 这里是我的代码。 等待响应。

//初始化

unsigned long ui32废物桶;

SysCtlPeripheralEnable (SYSCTL_Periph_SSI2);
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD);
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOQ);

GPIOPinConfigure (GPIO_PD3_SSI2CLK);

GPIOPinConfigure (GPIO_PD0_SSI2XDAT1);//MISO/RX 线路

GPIOPinConfigure (GPIO_PD1_SSI2XDAT0);//MOSI//TX 线路
GPIOPinConfigure (GPIO_PD2_SSI2FSS);
GPIOPinTypeSSI (GPIO_PORTD_base、GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);

SSIConfigSetExpClk (SSI2_base、SysCtlClockGet ()、SSI_FRF_MOTO_MOTO_0、SSI_MODE_MASTER、1000000、 8);
SSIAdvModeSet (SSI2_base、SSI_ADV_MODE_WRITE);
SSIAdvFrameHoldEnable (SSI2_base);
SSIEnable (SSI2_base);

while (SSIDataGetNonBlocking (SSI2_base、&ui32Trash)){}


一些功能

//芯片选择启用,PD2
void ce_set (void){
GPIOPinTypeGPIOOutput (GPIO_PORTD_base、GPIO_PIN_2);
GPIOPinWrite (GPIO_PORTD_base、GPIO_PIN_2、GPIO_PIN_2);

//芯片选择禁用,PD2
void ce_clear (void){
GPIOPinTypeGPIOOutput (GPIO_PORTD_base、GPIO_PIN_2);
GPIOPinWrite (GPIO_PORTD_BASE、GPIO_PIN_2、0);

//写保护使能,PQ0
void wp_set (void){
GPIOPinTypeGPIOOutput (GPIO_PORTQ_BASE、GPIO_PIN_0);
GPIOPinWrite (GPIO_PORTQ_BASE、GPIO_PIN_0、GPIO_PIN_0);

//禁用写保护,PQ0
void wp_clear (void){
GPIOPinTypeGPIOOutput (GPIO_PORTQ_BASE、GPIO_PIN_0);
GPIOPinWrite (GPIO_PORTQ_BASE、GPIO_PIN_0、0);


发送 Byte 例程:

uint8_t TX_DATA = 0x11;
uint32_t ui32Address = 0x012345;

wp_clear();

ce_clear();
SSIAdvModeSet (SSI2_base、SSI_ADV_MODE_WRITE);
SSIAdvDataPutFrameEnd (SSI2_base、0x50);
ce_set();

ce_clear();
SSIAdvModeSet (SSI2_base、SSI_ADV_MODE_WRITE);
SSIDataPut (SSI2_base、0x01);
SSIAdvDataPutFrameEnd (SSI2_base、0x00);
ce_set();

ce_clear();
SSIAdvModeSet (SSI2_base、SSI_ADV_MODE_WRITE);
SSIAdvDataPutFrameEnd (SSI2_base、0x06);
ce_set();

ce_clear();
SSIAdvModeSet (SSI2_base、SSI_ADV_MODE_WRITE);
SSIAdvFrameHoldEnable (SSI2_base);
SSIDataPut (SSI2_base、0x02);
SSIDataPut (SSI2_base、(ui32Address >> 16)& 0xff);
SSIDataPut (SSI2_base、(ui32Address >> 8)& 0xff);
SSIDataPut (SSI2_base、ui32Address 和0xff);

SSIAdvDataPutFrameEnd (SSI2_base、TX_DATA);

ce_set();

读取 Byte 例程:

unsigned long ui32MfgID;

uint32_t ui32Address = 0x012345;

ce_clear();

SSIAdvModeSet (SSI2_base、SSI_ADV_MODE_READ_WRITE);

SSIDataPut (SSI2_base、0x03);
SSIDataPut (SSI2_base、(ui32Address >> 16)& 0xff);
SSIDataPut (SSI2_base、(ui32Address >> 8)& 0xff);
SSIDataPut (SSI2_base、ui32Address 和0xff);
SSIAdvDataPutFrameEnd (SSI2_base、0x00);
SSIDataGet (SSI2_base、&ui32MfgID);

ce_set();

我将 FF 视为输出。

读取 JEDEC ID:

 uint32_t a、b、c、d;
 SSIAdvModeSet (SSI2_base、SSI_ADV_MODE_READ_WRITE);
 SSIDataPut (SSI2_base、0x9F);
 SSIDataPut (SSI2_base、0x00);
 SSIDataGet (SSI2_base、&a);//读取制造 ID
 SSIDataPut (SSI2_base、0x00);
 SSIDataGet (SSI2_base、&b);//读取制造 ID
 SSIDataPut (SSI2_base、0x00);
 SSIDataGet (SSI2_base、&c);//读取制造 ID
 SSIAdvDataPutFrameEnd (SSI2_base、0x00);
 SSIDataGet (SSI2_base、&d);

我将 FF BF 25 41视为输出。

 

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

    ***更新并更正,谢谢 CB1!

    您好 Chandler、

    欢迎来到论坛。 如果您选择"插入代码..."、我建议您在将来发布帖子 并使用" "按钮、您可以发布 C 代码、它将保留格式并添加语法突出显示。 这将使您的代码更易于阅读、这将帮助其他人对您的帖子作出响应。

    我快速查看了微芯片数据表。 它看起来像是在上升沿输出、而在下降沿输出时钟(我不是微芯片专家)。

    要匹配此格式、您需要使用 SPO = 0和 SPH = 0的飞思卡尔 SPI 帧格式、即 SSI_FRF_MOTO_MODE_0。 您似乎已经正确配置了该配置。

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

    您好 Bob、

    应该注意海报设置 "Moto_Mode_0"-我认为是正确的吗?    他的守则如下:

    SSIConfigSetExpClk (SSI2_base、SysCtlClockGet ()、SSI_FRF_MOTO_MOTO_0、SSI_MODE_MASTER、1000000、 8);

    现在、您已经足够关心和组织起来、能够展示一个关键的"数据表摘录"(我认为应该是"提供的海报")、并且-可能是由于这种额外的努力(强加给您)、您对"SPI 时钟与数据"的解释似乎有点混乱。   请注意、您的(顶部/第一个)项在您的突出显示列表中、供应商的"时钟与数据规格"-您的(书面)解释会将其反转。   (当您回复许多帖子时、这不难理解。)

    由于这种"扰频"、您的第二个亮点指示使用 "Moto_Mode_1"、这是不正确的。   (您的"舵柄控制器"应超过您的"高亮绘图精度"-至少这是您的"MChip 航海 crüe…"报告。  从"《仲裁示范法》"中收回的少数人.  我们(两者)似乎从类似的(没有太熟练的)库存中提取了 crüe!)

    还有另一个要点 "支持海报的代码"-至少一部分-那就是他(几乎) 完全/正确地恢复了 SPI 器件的"ID"(BFH 25H 41H)-所有这些都在器件的规格表中得到了确认。

    海报的回收代码-"即将结束"-显示以下"值得审核的项目:"

    读取 JEDEC ID:

     uint32_t a、b、c、d;

     SSIAdvModeSet (SSI2_base、SSI_ADV_MODE_READ_WRITE);
     SSIDataPut (SSI2_base、0x9F);
     SSIDataPut (SSI2_base、0x00);
     SSIDataGet (SSI2_base、&a);//读取制造 ID

    对 SSIDataPut ()的"背靠背"调用被认为是可疑的-并导致""FFH"的垃圾回收 。   SPI 供应商的数据表显示: "9FH -后跟3个"无关写入(此处为"放置")"-因此怀疑应采用:

    SSIDataPut ()
    SSIDataGet ()

    连续四次。   (案例(可能)被制造3次-这是留给读者的...)

    还需要注意的  是、海报最初订购了" MCU 的"FSS 自动使用(通过 SPI 初始化)-但后来更改为"手动 GPIO 切换"-替代了自动使用。   (然而、代码从未被改变-以正确地反映此类变化-混乱/浪费时间-到下游审核者。)

    至于其他 SPI "读/写"故障-我们的海报会一如既往地要求进一步澄清。    实施了一个相当严格的"命令响应"协议-数据表中显示了一个更加仔细的"阅读并遵守"协议...

    正如我们的"海报所指出的"、  我们期待着及时的回应!    (但绝不: 预期、命令或"神禁止"紧急...)

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

    感谢 Bob、

    我有一点困惑、我是新加入的 Tiva 平台。 我不是 Microchip 和 TI 产品的专家、但我看到、使用的闪存 EEPROM 支持您强调的模式0和模式3。 那么,您能否给我一个提示,让我将代码更改为方便的模式0或3?

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

    观察到: (海报 CB1... 再一次…… 缓慢地将手枪升高到"头部水平"。)    (也许它应该针对  那些不感激的人?)

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

    尊重 CB1_MOBILE。 您是否有任何解决方案建议? 特别是对于 FSS 信号?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!
    针对您的问题的一些观察/建议:
    1.写入/发送一个字节:
    -您需要在实际写入周期的开始和结束时提供独立的 WRITE_ENABLE 和 WRITE_DISABLE 命令。 这是强制性的、应由以下部分组成:
    *)清除芯片选择引脚;
    *)发送 WRITE_ENABLE 命令;(或结束时为 WRITE_DISABLE)
    *)设置芯片选择引脚;
    我建议将这两个单独的函数设置为1。 似乎您仅使用硬件写保护-请查看您的器件数据表、所有 SPI 存储器都具有强制的软件写启用/禁用命令。

    读取一个字节:
    -您需要提供:发送地址、发送虚拟字节(阅读数据表以了解需要多少虚拟字节)、以及另一个虚拟字节以真正从器件读取字节。 您似乎避免了最后一步。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Petrei、
    我尝试执行以下操作。 仍然看到0xFF
    关于读取字节:
    我检查了数据表,发现如果我使用正常速度读取(25MHz) 03H > 24字节地址>开始从 SPI 线路获取。

    如果我使用高速读取(50 MHz) 0Bh>24 Byte Address >X( SEND 虚拟字节)>开始从 SPI 线路获取。



    #define dummy_byte 0x00
    #define READ0x03
    #define READ_FAST 0x0B
    #define ERASE_4KB 0x20
    #define ERASE_32KB 0x52
    #define ERASE_64KB 0xD8
    #define ERASE_CHIP 0x60
    #define program_BYTE 0x02
    #define program_AAI 0xAD
    #define RDSR0x05 //读取状态寄存器
    #define EWR 0x50 //启用写入状态寄存器
    #define WRSR0x01 //写入状态寄存器
    #define WREN0x06 //写入使能
    #define WRDIS0x04 //写禁用
    #define RDID0x90 //读取 ID
    #define R_JEDEC 0x9F //读取 JEDEC–ID
    #define EBSY0x70 //启用 SO 以在 AAI 编程期间输出 RY/BY#状态
    #define DBSY0x80 //禁用、因此在 AAI 编程期间为 RY/BY#状态
    #define WRSR_NOT 0x9C //不允许执行 WRSR
    #define ENABLE_Protection 0x1C //启用块保护
    #define DISABLE_Protection 0x00 //无块保护

    空 Config_SPI (空)

    unsigned long ui32废物桶;


    SysCtlPeripheralEnable (SYSCTL_Periph_SSI2);
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD);
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOQ);
    GPIOPinConfigure (GPIO_PD3_SSI2CLK);
    GPIOPinConfigure (GPIO_PD0_SSI2XDAT1);//MISO/RX 线路
    GPIOPinConfigure (GPIO_PD1_SSI2XDAT0);//MOSI//TX 线路

    GPIOPinConfigure (GPIO_PD2_SSI2FSS);
    GPIOPinTypeSSI (GPIO_PORTD_base、GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);

    //GPIOPinTypeGPIOOutput (GPIO_PORTD_base、GPIO_PIN_2);
    //GPIOPinWrite (GPIO_PORTD_base、GPIO_PIN_2、GPIO_PIN_2);
    //GPIOPinTypeSSI (GPIO_PORTD_base、GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3);

    SSIConfigSetExpClk (SSI2_base、SysCtlClockGet ()、SSI_FRF_MOTO_MOTO_0、SSI_MODE_MASTER、1000000、 8);
    SSIAdvModeSet (SSI2_base、SSI_ADV_MODE_WRITE);
    SSIAdvFrameHoldEnable (SSI2_base);
    SSIEnable (SSI2_base);

    while (SSIDataGetNonBlocking (SSI2_base、&ui32Trash)){}

    protection_Enable();


    //芯片选择启用,PD2
    void ce_set (void){
    GPIOPinTypeGPIOOutput (GPIO_PORTD_base、GPIO_PIN_2);
    GPIOPinWrite (GPIO_PORTD_base、GPIO_PIN_2、GPIO_PIN_2);


    //芯片选择禁用,PD2
    void ce_clear (void){
    GPIOPinTypeGPIOOutput (GPIO_PORTD_base、GPIO_PIN_2);
    GPIOPinWrite (GPIO_PORTD_BASE、GPIO_PIN_2、0);


    //写保护使能,PQ0
    void wp_set (void){
    GPIOPinTypeGPIOOutput (GPIO_PORTQ_BASE、GPIO_PIN_0);
    GPIOPinWrite (GPIO_PORTQ_BASE、GPIO_PIN_0、GPIO_PIN_0);


    //禁用写保护,PQ0
    void wp_clear (void){
    GPIOPinTypeGPIOOutput (GPIO_PORTQ_BASE、GPIO_PIN_0);
    GPIOPinWrite (GPIO_PORTQ_BASE、GPIO_PIN_0、0);


    void Protection_Enable()

    wp_set();

    WRITE_Status_Register (WRSR_NOT);

    wp_clear();


    void Protection_Disable ()

    WRITE_Status_Register (disable_protection);//可以写入所有存储器段


    空 Enable_Write_Status_Register (空)

    无符号超长整型虚拟;
    ce_clear();

    SSIAdvModeSet (SSI2_base、SSI_ADV_MODE_WRITE);
    SSIAdvFrameHoldEnable (SSI2_base);
    SSIAdvDataPutFrameEnd (SSI2_base、EWR);
    //SSIDataGet (SSI2_base、&dummy);

    ce_set();


    空 Write_Status_Register (Int16值)

    wp_clear();

    ENABLE_Write_Status_Register ();
    无符号超长整型虚拟;

    ce_clear();

    SSIAdvModeSet (SSI2_base、SSI_ADV_MODE_WRITE);
    SSIAdvFrameHoldEnable (SSI2_base);
    SSIDataPut (SSI2_base、WRSR);
    //SSIDataGet (SSI2_base、&dummy);
    SSIAdvDataPutFrameEnd (SSI2_base、value);
    //SSIDataGet (SSI2_base、&dummy);

    ce_set();
    wp_set();


    空 Write_Enable()

    无符号超长整型虚拟;
    ce_clear();

    SSIAdvModeSet (SSI2_base、SSI_ADV_MODE_WRITE);
    SSIAdvFrameHoldEnable (SSI2_base);
    SSIAdvDataPutFrameEnd (SSI2_base、WREN);
    //SSIDataGet (SSI2_base、&dummy);

    ce_set();


    void Chip_Eras()

    protection_disable();
    Write_Enable();
    无符号超长整型虚拟;

    ce_clear();

    SSIAdvModeSet (SSI2_base、SSI_ADV_MODE_WRITE);
    SSIAdvFrameHoldEnable (SSI2_base);
    SSIAdvDataPutFrameEnd (SSI2_base、ERASE_CHIP);
    //SSIDataGet (SSI2_base、&dummy);

    ce_set();


    空 Write_Byte (uint32_t ui32Address、uint8_t 数据)

    protection_disable();
    Write_Enable();
    无符号超长整型虚拟;

    ce_clear();

    SSIAdvModeSet (SSI2_base、SSI_ADV_MODE_WRITE);
    SSIAdvFrameHoldEnable (SSI2_base);
    SSIDataPut (SSI2_base、program_Byte);
    //SSIDataGet (SSI2_base、&dummy);
    SSIDataPut (SSI2_base、(ui32Address >> 16)& 0xff);
    //SSIDataGet (SSI2_base、&dummy);
    SSIDataPut (SSI2_base、(ui32Address >> 8)& 0xff);
    //SSIDataGet (SSI2_base、&dummy);
    SSIDataPut (SSI2_base、ui32Address 和0xff);
    //SSIDataGet (SSI2_base、&dummy);
    SSIAdvDataPutFrameEnd (SSI2_base、data);
    //SSIDataGet (SSI2_base、&dummy);

    ce_set();


    Int16 Read_Byte (uint32_t ui32Address)

    无符号长假 dum;

    ce_clear();

    SSIAdvModeSet (SSI2_base、SSI_ADV_MODE_READ_WRITE);
    SSIAdvFrameHoldEnable (SSI2_base);
    SSIDataPut (SSI2_base、读取);
    //SSIDataGet (SSI2_base、&dummy);
    SSIDataPut (SSI2_base、(ui32Address >> 16)& 0xff);
    //SSIDataGet (SSI2_base、&dummy);
    SSIDataPut (SSI2_base、(ui32Address >> 8)& 0xff);
    //SSIDataGet (SSI2_base、&dummy);
    SSIDataPut (SSI2_base、ui32Address 和0xff);
    //SSIDataGet (SSI2_base、&dummy);
    SSIAdvDataPutFrameEnd (SSI2_base、dummy_byte);
    SSIDataGet (SSI2_base、&dummy);
    DUM =虚拟和0xff;

    ce_set();
    返回(dum);


    Int_main(){
    protection_disable();
    chip_Erase ();
    WRITE_Byte (0x000002、0xAA);
    Read_Byte (0x000002);
    while (1);
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    CB1、
    您完全正确。 我不知道我昨天在想什么、我发布的图片显示原始海报的配置正确、我错了。 感谢您查看我的回答。 我将编辑我之前的帖子、以避免误导此主题的一些后续读者、他们无法阅读整个内容。

    Chandler、
    请选择"这没有回答我的问题"(或类似问题)。 我无法撤消"TI 认为已解决"、但您可以撤消。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢、Bob。    请注意:我确实承认 您(和其他)供应商代理提供的优质且实质性的服务。

    你的是一个简单的"转位"-当然员工和我也做过同样的-很多次...

    似乎朋友 Petrei 将承担责任-在这里。

    我确实向(印有海报的)钱德勒提供了关键的代码指导-这一点没有得到承认-因此、还有" 反应更灵敏的墙/风车"-等待我-和被骗的 -(位)硬头。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我认为我的配置不正常。 我甚至无法读取和写入状态寄存器值。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="ChandlerBing "] 我可以读取 JEDEC ID[/引用]

    这是否意味着 TM4C129ENCPDT 上的 SSI 配置正确?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    取决于代码、但至少可以说我使用实际的 SSI 配置读取 JEDEC ID。 我尝试编写有用的代码供我和其他人使用。

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

    我在这里看到了两个基本问题

    使用 SSI 高级模式时、不需要将 CE 控制为 GPIO
    2.使用高级 RW 模式时,DataPut 和 DataGet 的数目应匹配,但我也看不到。

    最后、在纠正同样的情况后、您能否发布总线接口的波形/LA 快照?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Amit、您好!

    当您写入您的字时、我尝试实现、最后我可以读取和写入字节。

    一段时间后、我将在这里编写工作代码、一起查看我的其他故障并帮助他人。