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.

[参考译文] MSPM0G1106:SPI 读取和写入

Guru**** 2386620 points
Other Parts Discussed in Thread: MSPM0G1106, SYSCONFIG
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1424028/mspm0g1106-spi-read-and-write

器件型号:MSPM0G1106
主题中讨论的其他器件: SysConfig

工具与软件:

您好!

我想使用德州 MSPM0G1106 IC 进行 SPI 读取和写入。

首先、我之前已经完成了使用另一个 MCU 的 SPI 读取和写入。 这是代码。

unsigned char MFRC522_SPIreceive(unsigned char address_rcv)
	{
		SPI_receive_address= (((address_rcv<<1)&0x7E) | 0x80);
		
  	SPI_NSS= 0;
    
		SPI_WRITE_TX(SPI0, SPI_receive_address);
		while(SPI_IS_BUSY(SPI0));
	
    SPI_ClearRxFIFO(SPI0);
	
		SPI_WRITE_TX(SPI0, DUMMY);
		while(SPI_IS_BUSY(SPI0));
  	
		SPI_Received_data = SPI_READ_RX(SPI0);
  		
		SPI_NSS= 1; 
	
		return SPI_Received_data;
	}

在查看 MCU 的调试时、我可以看到想要的值。 但当我查看 TExaS 的调试时、我读取了0xFF。 通常我应该读取0x3F。

(在下图中、您可以看到从 Logic Analayzer 中拍摄的图像)。

SPI 初始化

  

SPI 设置

SPI 设置

SYSCONFIG_WEAK void SYSCFG_DL_SPI_0_init(void)
{
    DL_SPI_setClockConfig(SPI_0_INST, (DL_SPI_ClockConfig *) &gSPI_0_clockConfig);

    DL_SPI_init(SPI_0_INST, (DL_SPI_Config *) &gSPI_0_config);

    /* Configure Controller mode */
    /*
     * Set the bit rate clock divider to generate the serial output clock
     *     outputBitRate = (spiInputClock) / ((1 + SCR) * 2)
     *     400000 = (16000000)/((1 + 19) * 2)
     */
    DL_SPI_setBitRateSerialClockDivider(SPI_0_INST, 19);
    /* Set RX and TX FIFO threshold levels */
    DL_SPI_setFIFOThreshold(SPI_0_INST, DL_SPI_RX_FIFO_LEVEL_1_2_FULL, DL_SPI_TX_FIFO_LEVEL_1_2_EMPTY);

    /* Enable module */
    DL_SPI_enable(SPI_0_INST);
}

SPI 初始化代码

IC 引脚

配置等设置与图片中的设置相同。

我使用的代码如下所示。

unsigned char MFRC522_SPIreceive(uint8_t address_rcv)
{
    uint8_t SPI_receive_address = (((address_rcv << 1) & 0x7E) | 0x80);

    //MFRC_NSS_OFF;

    DL_SPI_transmitData8(SPI_0_INST, SPI_receive_address);
    delay_cycles(500);
    while (DL_SPI_isBusy(SPI_0_INST));

    DL_SPI_transmitData8(SPI_0_INST, DUMMY);
    delay_cycles(500);
    while (DL_SPI_isBusy(SPI_0_INST));

    SPI_Received_data= DL_SPI_receiveData8(SPI_0_INST);

    //MFRC_NSS_ON;


    return SPI_Received_data;
}

主代码

MFRC522_SPIreceive(0x11);
delay_cycles(500);

我在读取代码时是否出错? 如果是、如何解决?

提前感谢您。

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

    您之前的代码

    > SPI_ClearRxFIFO (SPI0);

    为了清除您从发送命令返回的 Rx 字节。 我没有看到完全等效的数据、但您知道 Rx FIFO 中只有一个字节、因此您可以使用:

    >(void) DL_SPI_receiveData8 (SPI_0_INST);//读取并丢弃

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

    (void) DL_SPI_receiveData8 (SPI_0_INST);//我正在尝试使用该代码、但没有数据检索、我应该编写什么代码?

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

    尝试添加:

    while (DL_SPI_isRXFIFOEMpty (SPI));

    在 SPI_RECEIVED_DATA= DL_SPI_receiveData8 (SPI_0_INST)之前;

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

    uint8_t DUMMY=0x00;
    
    
    unsigned char MFRC522_SPIreceive(uint8_t address_rcv)
    {
    
        uint8_t SPI_receive_address = (((address_rcv << 1) & 0x7E) | 0x80);
    
       
    
        DL_SPI_transmitData8(SPI_0_INST, SPI_receive_address);
    
        while (DL_SPI_isBusy(SPI_0_INST));
    
        while (DL_SPI_isRXFIFOEmpty(SPI_0_INST));
    
    
    
    
        DL_SPI_transmitData8(SPI_0_INST, DUMMY);
    
        while (DL_SPI_isBusy(SPI_0_INST));
    
        SPI_Received_data= DL_SPI_receiveData8(SPI_0_INST);
    
    
    
    
        return SPI_Received_data;
    }
    
    
    
    
    
    
    int main(void)
    {
        SYSCFG_DL_init();
    
        while (1) {
    
           MFRC522_SPIreceive(0x11);
            delay_cycles(500000);
    
        }
    }

    我可以在另一个 MCU 中看到0x3f、但我在德州看不到它、它在调试中看不到。

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

    我不确定我是否理解您所说的"无数据检索"。

    该行应插入到第二次调用 DL_SPI_transmitData8之前(就像在您的原始代码中一样)。

    在 SPI 中、每个 Tx 字节返回一个 Rx 字节。 即使您对 Rx 字节不感兴趣、也需要对它进行处理、处理方法通常是读取它并将其丢弃。

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

    我不明白为什么我没有它。 我不断从缓冲区中读取0xff。 我检查了我的硬件。 我的 SPI 配置操作是否错误? 您可以查看一下吗?

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

    如果您返回的是0xFF、而不是分析器跟踪中显示的0x00、我想这意味着您从某些早期事务中返回了(Rx) FIFO 中剩余的字节。 如果是、那么你应该用如下命令清空 FIFO:

    while (! DL_SPI_isRXFIFOEMpty (SPI_0_INST){(void) DL_SPI_receiveData8 (SPI_0_INST);}// 将 Rx FIFO 清空

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

    我需要从 FIFO 读取的值是0x3f、但我始终读取0xff。 我将执行你明天说的话,让你知道情况。

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

    我们正在读取、但我们需要阅读下面的数学过程。 为什么会这样?

    uint8_t SPI_receive_address = (((address_rcv << 1) & 0x7E) | 0x80);
    
    
    
        DL_SPI_transmitData8(SPI_0_INST, SPI_receive_address);
    
        while (DL_SPI_isBusy(SPI_0_INST));
    
    
        while (DL_SPI_isRXFIFOEmpty(SPI_0_INST));
    
        DL_SPI_transmitData8(SPI_0_INST, DUMMY);
    
        while (DL_SPI_isBusy(SPI_0_INST));
    
    
    
        while (!DL_SPI_isRXFIFOEmpty(SPI_0_INST)) {
            SPI_Received_data= DL_SPI_receiveData8(SPI_0_INST);
    }
        SPI_Received_data=0xff-SPI_Received_data;<-------------

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

    这并不是我所建议的那样,但它似乎应该起作用。

    听起来您好像已经在 Iomux 配置中设置了"反相"。 在 SysConfig 中、"Communications->SPI->Pin Configuration->SPI POCI [Enable pin configuration checkbox]->Digital IOMUX Features->Invert"下会显示什么内容?

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

    您好、我想我们已经取得了长足的进步、但我马上就告诉您我的问题、因为它并不完全符合预期。 我解决了正确读取数据的问题、但我在 FIFO 中读取的某些数据是旧数据。 让我这样解释一下:我在发送的附件中读取的字段与在调试中读取的字段不同。 我认为这是数据读取差异、我无法确定 FIFO 是否被清空、也无法手动将其清空。 通过方式 TxControlReg = 0x14。 你有新的建议吗?

      ...

    unsigned char MFRC522_SPIreceive(unsigned char address_rcv)
    {
        // Okuma işlemi için adres
        uint8_t SPI_receive_address = (((address_rcv << 1) & 0x7E) | 0x80);
    
        MFRC_NSS_OFF;
    
    
        DL_SPI_transmitData8(SPI_0_INST, SPI_receive_address);
    
        while (DL_SPI_isBusy(SPI_0_INST));
    
    
        //while (!DL_SPI_isRXFIFOEmpty(SPI_0_INST));
    
        DL_SPI_transmitData8(SPI_0_INST, DUMMY);
        while (DL_SPI_isBusy(SPI_0_INST));
    
    
        while (!DL_SPI_isRXFIFOEmpty(SPI_0_INST)) {
        SPI_Received_data= DL_SPI_receiveData8(SPI_0_INST);
    }
        //SPI_Received_data=0xff-SPI_Received_data;
    
    
    MFRC_NSS_ON;
    
    
    delay_cycles(200);
    
    
    
        return SPI_Received_data;
    }

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

    您可以读取 SPI 数据清空 FIFO

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

    unsigned char MFRC522_SPIreceive(unsigned char address_rcv)
    {
        // Okuma işlemi için adres
        uint8_t SPI_receive_address = (((address_rcv << 1) & 0x7E) | 0x80);
    
        // NSS'i düşürün, böylece SPI ile haberleşme başlayacak
        MFRC_NSS_OFF;
    
        // Adresi gönderin
        DL_SPI_transmitData8(SPI_0_INST, SPI_receive_address);
    
        // SPI işlemi bitene kadar bekleyin
        while (DL_SPI_isBusy(SPI_0_INST));
    
        // RX FIFO'nun boş olup olmadığını kontrol edin ve boş olduğundan emin olun
        while (!DL_SPI_isRXFIFOEmpty(SPI_0_INST)) {
            // Eğer FIFO'da veri varsa eski veriyi temizleyin
            DL_SPI_receiveDataBlocking8(SPI_0_INST);
        }
    
        // Veri gönderin, dummy data kullanarak (saat sinyali üretmek için)
        DL_SPI_transmitData8(SPI_0_INST, DUMMY);
    
        // SPI işlemi bitene kadar bekleyin
        while (DL_SPI_isBusy(SPI_0_INST));
    
        // RX FIFO'nun dolu olup olmadığını kontrol edin ve veri al
        while (DL_SPI_isRXFIFOEmpty(SPI_0_INST));  // FIFO dolana kadar bekleyin
    
        SPI_Received_data = DL_SPI_receiveDataBlocking8(SPI_0_INST);
    
        // SPI işlemi tamamlandıktan sonra NSS'i tekrar yükseltin
        MFRC_NSS_ON;
    
        // Gerekli gecikme
        delay_cycles(200);
    
        // Alınan veriyi döndürün
        return SPI_Received_data;
    }
    

    大家好、我想我解决了我的问题。 我读取的数据是之前读取并写入 FIFO 的数据。 我一发送地址、我就将其清空并丢弃、然后读取真实的数据。

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

    我很高兴您启动了该工具。