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.

[参考译文] TMS320F28335-SPI-Master 和 TMS320F28335-SPI-Slave 之间的通信

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/948327/communication-between-tms320f28335-spi-master-and-tms320f28335-spi-slave

器件型号:TMS320F28335
主题中讨论的其他器件: C2000WARE

您好!

我尝试在两个 TMS320F28335微控制器之间进行通信。 一个配置为主器件、另一个配置为从器件。

当我从主器件向从器件发送数据时、我会按预期从器件返回两个字节的数据。 然后、我得到两个字节的数据、这不是预期的那样。 我从主器件发送到从器件的数据似乎只是存储在 SPIDAT 中、并随着主器件到从器件的下一次数据传输而移出。

相反、我希望从器件将下一个数据从 TXBUF 写入 SPIDAT、并在下一次通信时发送该数据。

随附的内容发送通信屏幕截图以及主从配置代码。 通道1是主器件、通道2是从器件。

提前感谢!

主配置:

int16 init_pins_as spi_master (uint16波特率){
EALLOW;
TMC_BASE_PIO->CTL[0].PUD &=~((UINT32) 0x1<<16); //在 GPIO16 (SPISIMOA)
上启用上拉 TMC_BASE_PIO->CTL[0].QSEL2 |=(0x3); //异步输入 GPIO16 (SPISIMOA)
TMC_BAS_PIO->CTL[0].MUX2 |=(0x1); //将 GPIO16配置为 SPISIMOA

TMC_BASE_PIO->CTL[0].PUD &=~((UINT32) 0x1<<17); //启用 GPIO17 (SPISOMIA)
TMC_BASE_PIO->CTL[0].QSEL2 |=(0x3<<2); //异步输入 GPIO17 (SPISOMA)
TMC_BAS_PIO->CTL[0].MUX2 |=(0x1<<2); //将 GPIO17配置为 SPISOMIA

TMC_BASE_PIO->CTL[0].PUD &=~((UINT32) 0x1<<18); GPIO18上的//使能上拉电阻(SPICLKA)
TMC_BASE_PIO->CTL[0].QSEL2 |=((uint32) 0x3<<4); //异步输入 GPIO18 (SPICLKA)
TMC_BASE_PIO->CTL[0].MUX2 |=((uint32) 0x1<<4); //将 GPIO18配置为 SPICLKA

TMC_BASE_PIO->CTL[0].PUD &=~((UINT32) 0x1<<19); GPIO19上的//使能上拉电阻(SPISTEA)
TMC_BASE_PIO->CTL[0].QSEL2 |=((uint32) 0x3<<6); //异步输入 GPIO19 (SPISTEA)
TMC_BASE_PIO->CTL[0].MUX2 |=((uint32) 0x1<<6); //将 GPIO19配置为 SPISTEA
EDIS;

//在复位中设置
TMC_BAS_SPIA->CCR &&μ~(0x1<<7);

//启用主控模式、正常阶段、启用通话和禁用 SPI int。
TMC_BASE_SPIA->CTL |= 0x0006;//启用主模式和传输
TMC_BASE_SPIA->BRR |=波特率;
TMC_BAS_SPIA->CCR |= 0x00F;// 16位字

//初始化 SPI FIFO 寄存器
TMC_BASE_SPIA->FFRX &=~(0x1F); //接收
TMC_BASE_SPIA->FFRX |=(0x1); //////将 RX FIFO 深度设置为8
TMC_BASE_SPIA->FFRX |=(0x1<<5);//启用中断
TMC_BASE_SPIA->FFRX |=(0x1<<6);//清除中断标志
TMC_BASE_SPIA->FFRX |=(0x1<<13);//重新启用接收 FIFO 操作

TMC_BASE_SPIA->FFTX |=(0x1); //将 TX FIFO 级别设置为8
TMC_BASE_SPIA->FFTX |=(0x1<<5);//启用中断
TMC_BASE_SPIA->FFTX |=(0x1<<6);//清除中断标志
TMC_BASE_SPIA->FFTX |=(0x1<<13);//从复位状态释放 FIFO
TMC_BASE_SPIA->FFTX |=(0x1<<14);//启用 FIFO 增强功能
TMC_BASE_SPIA->FFTX |=((uint32) 0x1<<15);// SPI FIFO 恢复

//Out of Reset
TMC_BASE_SPIA->CCR |=(0x1<<7);//从复位中撤回 SPI 并设置字符长度

返回0;
}


uint16 data=0;
int main (void)
{
uint32 i=0;

set_system_controls();
INIT_PINS_AS_SPI_MASTER (0x0063);

while (1){
SPI_Send (0x8888);
SPI_READ (&data);
}

返回0;
}


void SPI_Send (uint16 data){
TMC_BASE_SPIA->TXBUF=数据;
TMC_BASE_SPIA->FFTX |=(0x1<<6);//清除中断标志

}

void SPI_Read (uint16 *数据){
*数据= TMC_BASE_SPIA->RXBUF;
TMC_BASE_SPIA->FFRX |=(0x1<<6);//清除中断标志

}


________________________________________________________________

从器件配置:


int16 init_pins_as spi_slave (){
   EALLOW;
   TMC_BASE_PIO->CTL[0].PUD &=~((uint32) 0x1<<16);      //启用 GPIO16上的上拉(SPISIMOA)
            TMC_BASE_PIO->CTL[0].QSEL2 |=(0x3);      //异步输入 GPIO16 (SPISIMOA)
            TMC_BASE_PIO->CTL[0].MUX2 |=(0x1);         //将 GPIO16配置为 SPISIMOA

            TMC_BASE_PIO->CTL[0].PUD &=~((uint32) 0x1<<17);      //启用 GPIO17上的上拉电阻器(SPISOMIA)
            TMC_BASE_PIO->CTL[0].QSEL2 |=(0x3<2);      //异步输入 GPIO17 (SPISOMIA)
            TMC_BASE_PIO->CTL[0].MUX2 |=(0x1<<2);      //将 GPIO17配置为 SPISOMIA

            TMC_BASE_PIO->CTL[0].PUD &=~((uint32) 0x1<<18);      //启用 GPIO18上的上拉电阻器(SPICLKA)
            TMC_BASE_PIO->CTL[0].QSEL2 |=((uint32) 0x3<<4);      //异步输入 GPIO18 (SPICLKA)
            TMC_BASE_PIO->CTL[0].MUX2 |=((uint32) 0x1<<4);      //将 GPIO18配置为 SPICLKA

            TMC_BASE_PIO->CTL[0].PUD &=~((uint32) 0x1<<19);      //启用 GPIO19上的上拉(SPISTEA)
            TMC_BASE_PIO->CTL[0].QSEL2 |=((uint32) 0x3<<6);      //异步输入 GPIO19 (SPISTEA)
            TMC_BASE_PIO->CTL[0].MUX2 |=((uint32) 0x1<<6);      //将 GPIO19配置为 SPISTEA
   EDIS;

   //在复位中设置
   TMC_BAS_SPIA->CCR &&μ~(0x1<<7);

   //启用从设备
   TMC_BASE_SPIA->CTL &=~(0x0004);   //禁用主控模式
   TMC_BASE_SPIA->CTL |=(0x2);      //启用传输
   TMC_BASE_SPIA->CTL |=(0x1);   //启用中断
   TMC_BAS_SPIA->CCR |= 0x00F;  // 16位字


   //初始化 SPI FIFO 寄存器
   TMC_BASE_SPIA->FFRX &=~(0x1F);      //接收
   TMC_BASE_SPIA->FFRX |=(0x1);      ////将 RX FIFO 级别设置为8
   TMC_BASE_SPIA->FFRX |=(0x1<<5);   //启用中断
   TMC_BASE_SPIA->FFRX |=(0x1<<6);   //清除中断标志
   TMC_BASE_SPIA->FFRX |=(0x1<<13);   //重新启用接收 FIFO 操作

   TMC_BASE_SPIA->FFTX |=(0x1);      //将 TX FIFO 级别设置为8
   TMC_BASE_SPIA->FFTX |=(0x1<<5);   //启用中断
   TMC_BASE_SPIA->FFTX |=(0x1<<6);   //清除中断标志
   TMC_BASE_SPIA->FFTX |=(0x1<<13);   //从复位状态释放 FIFO
   TMC_BASE_SPIA->FFTX |=(0x1<<14);   //启用 FIFO 增强功能
   TMC_BASE_SPIA->FFTX |=((uint32) 0x1<<15);   // SPI FIFO 恢复

   //Out of Reset
   TMC_BASE_SPIA->CCR |= 0x0080;  //从复位中撤回 SPI 并设置字符长度

   返回0;


void SPI_SET_Interrupt_TX (void * spiTxFIFOISR){
   //配置中断
   Dint;
   EALLOW;
   TMC_BASE_INT_regs->SPITXINTA =(uint32) spitxFIFOISR;
   EDIS;
   TMC_BASE_PIE -> CTRL |= 0x01;                //启用 PIE 块
   TMC_BASE_PIE ->组[5].IER |= 0x2;      //在 PIE 中启用 I2cInt1A:组6中断2
   IER |= 0x0020;
   EINT;


void SPI_SET_Interrupt_RX (void * spiRxFIFOISR){
   //配置中断
   Dint;
   EALLOW;
   TMC_BASE_INT_regs->SPIRXINTA =(uint32) spirxFIFOISR;
   EDIS;
   TMC_BASE_PIE -> CTRL |= 0x01;                //启用 PIE 块
   TMC_BASE_PIE ->组[5].IER |= 0x1;      //在 PIE 中启用 I2cInt1A:组6中断1
   IER |= 0x0020;
   EINT;

void interrupt_ack_SPI (){
   //确认中断以从所有中断组中获取更多信息
   TMC_BASE_PIE -> ACK |= 0xFFFF;

_interrupt void spiRxFIFOISR (void);
_interrupt void spiTxFIFOISR (void);


uint16 z=0;
uint16 data=0x0000;
int main (空)

   uint32 i=0;

   set_system_controls();
   init_pins_as spi_slave ();
   SPI_SET_Interrupt_RX (&spiRxFIFOISR);
   SPI_SET_Interrupt_TX (&spiRxFIFOISR);


   while (1){

    }

   返回0;


_interrupt void spiRxFIFOISR (void){
   spi_read (&z);
   interrupt_ack_SPI ();


_interrupt void spiTxFIFOISR (void){
   SPI_Send (data);
   interrupt_ack_SPI ();


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

    尊敬的 David:

    [引用用户="David Kliewe"]

    Uint16 data=0;
    intmain(void)
    {
        Uint32 i=0;
        set_system_controls();
        init_pins_as_spi_master(0x0063);
        while(1){
            SPI_Send(0x8888);
            SPI_Read(&data);
        }
        return0;
    }
    voidSPI_Send(Uint16 data){
        TMC_BASE_SPIA->TXBUF=data;
        TMC_BASE_SPIA->FFTX |= (0x1<<6);    // Clear Interrupt Flag
    }
    voidSPI_Read(Uint16 *data) {
        *data = TMC_BASE_SPIA->RXBUF;
        TMC_BASE_SPIA->FFRX |= (0x1<<6);    // Clear Interrupt Flag
    }

    [/报价]

    您的主代码中的 while (1)代码对我来说不正确。 您正在从 SPI 缓冲器中持续进行写入和读取、而无需检查每次写入和读取的状态。 您正在使用 FIFO、但在某些情况下、CPU 将溢出 FIFO。 与 RX 类似、在读取寄存器之前、您不会检查数据是否就绪。 我建议您在每次写入和读取前检查 FIFO 状态位。

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

    您好、Martinez、

    感谢您的快速响应。

    我更改了发送和读取函数、如下所示:

    void SPI_Send (uint16 data){
    if (TMC_BAS_SPIA->FFTX 和0x80){
    TMC_BAS_SPIA->FFTX |=(0x1<<6);//清除中断标志
    TMC_BAS_SPIA->TXBUF=DATA;
    }
    
    
    *SPI_READ (UINT16 * DATA){=0XCI_SPIA-=|/|ENTRICT_SPIA-=/|ENTRUFFICK=DATA<0x80</ENTRF=/|ENTRF=ENTRF=ENTRF=DATA<|/ENTRF=ENTRF=ENTRF=ENTRF=DATA<0x80</ENTRICK=ENTRF<SPICK=DATA<
    
    
    
    
    

    通过这些更改、我从从器件获取到主器件的信号、即-> 6x 主器件数据 ->从器件数据->主器件数据->从器件数据-> 6x 主器件数据->等等...

    在调试器中,我觉得 TXFFINT (TMC_BASE_SPIA->FFTX & 0x80)总是高电平,从不清除....

    我非常感谢您提供更多提示。
    提前感谢

    David

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

    尊敬的 David:

    [引用用户="DLK"]在调试器中,我觉得 TXFFINT (TMC_BASE_SPIA->FFTX & 0x80)总是高电平,而且从未清除...[/QUERP]

    如果 FIFO 状态小于 FIFO 中断级别、TXFFINT 位就会被置位。 除非您碰巧在 FIFO 水平高于中断水平时读取该位、否则您将始终看到该位被置位。  

    在任何情况下、我都会为您的主系统写入和读取推荐以下内容。 请注意、我正在使用的 driverlib 函数不受您所使用的器件支持、但仍然应该为您提供一个好主意。  

    静态内联 void
    SPI_writeDataBlockingFIFO (uint32_t base、uint16_t data)
    {
    //
    //检查参数。
    //
    assert (SPI_isBaseValid (base));
    
    //
    //等待接收 FIFO 中有可用空间。
    //
    while (SPI_getTxFIFOStatus (base)=SPI_FIFO_TXFULL)
    {
    }
    
    //
    //将数据写入发送缓冲区。
    //
    HWREGH (base + SPI_O_TXBUF)=数据;
    } 
    静态内联 uint16_t
    SPI_readDataBlockingFIFO (uint32_t base)
    {
    //
    //检查参数。
    //
    assert (SPI_isBaseValid (base));
    
    //
    //等待数据在接收 FIFO 中可用。
    //
    while (SPI_getRxFIFOStatus (base)=SPI_FIFO_RXEMPTY)
    {
    }
    
    //
    //检查要读取的数据。
    //
    return (HWREGH (base + SPI_O_RXBUF));
    } 

    [引用 user="dkL"]通过这些更改,我可以从从主器件获得一个信号,即--> 6x 主器件数据 -->从器件数据-->从器件数据--> 6x 主器件数据-->等。

    很抱歉、我不明白您在这里的意思。 但是、您能否重申您原来的问题? 序列是否低于您的预期?

    MOSI:0x8888 0x8888 0x8888 0x8888

    SOMI:0xaaaa 0xbbbb 0xcccc 0xddd。

    但是、您会得到这样的结果吗?

    MOSI:0x8888 0x8888 0x8888 0x8888

    SOMI:0xaaaa 0xaaaa 0xbbbb 0xbbbbbb。

    或者、您是否希望 SPI 从器件只回显从主器件接收到的数据?

    这里有几个要点:

    1. 有一个主时钟时、从器件将始终发送某些数据。 如果从机侧的 CPU 没有及时加载正确的数据、从机将移出 SPIDAT 寄存器中的任何内容。
    2. 您已在从器件侧启用 TX FIFO 模式、FIFO 深度为8、因此从理论上讲、SPI 从器件将在主器件启动 SPI 时钟之前预加载8个字符。 这应该减轻上述(1)的影响、但不确定这是您想要的吗?
    3. 如果在从器件侧禁用 TX FIFO、则在主器件持续传输数据的情况下、从器件侧的 CPU 有一个短窗口(竞态条件)可将数据加载到从器件 SPIDAT 寄存器中。 从技术上讲、根据 CPU 负载、有可能错过这个最后期限。 主器件数据传输之间的延迟为从器件提供了更多的准备时间(请注意根据 SPI 时钟周期计算此延迟)。

    让我正确理解您的问题、我可以为您提供更多建议。

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

    您好、Martinez、
    非常感谢您抽出宝贵的时间、并提供了大量的回复。

    我希望:

    MOSI:0x8888 0x8888 0x8888 0x8888

    SOMI:0xaaaa 0xbbbb 0xcccc 0xddd。

    但我得到了

    MOSI:0x8888 0x8888 0x8888 0x8888 0x8888 0x8888

    SOMI:0xaaaa 0x8888 0xbbbb 0x8888 0xcccc 0x88888..

    我认为您是对的、从器件没有足够的时间加载正确的数据(并使用主器件的数据移出 SPIDAT 寄存器)。 但我仍然没有办法为从站提供足够的时间。 另外,由于主数据传输之间的延迟,我仍然得到相同的结果....

    此致、David

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

    尊敬的 David:

    我错误地将您的代码解释为将 FIFO 级别设置为8 (如代码注释中所述)。 但是、我看到电平设置为1。 在您的应用中、是否可以将 FIFO 级别设置为更高的数字? 具体来说是从器件 TX FIFO 级别?

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

    您好、Guz、

    我将从器件中的 RX 和 TX FIFO 电平更改为0x8。

    在这些设置下、从机 TX 中断被恰好调用4次、然后再也不会被调用。 这意味着、主数据始终在 MOSI 和 MISO 通道上...

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

    主机中的 RX 和 TX FIFO 深度也设置为0x8

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

    尊敬的 David:

    [引用 USER="DLK">通过这些设置、从机 TX 中断被恰好调用4次、然后再也不会被调用。 这意味着、主数据始终在 MOSI 和 MISO 通道上...

    我认为这是因为您的 ISR 没有考虑 RX FIFO 中有多个字符、TX FIFO 中有多个字符的空间。 例如、RX 中断提示您有8个可用字符、但您只能读取1个字符。 这当然是假设您没有修改 ISR 代码。  

    下面是 C2000Ware 中 F2833x 的 SPI 中断示例的一个片段。 在此示例中、RX/TX FIFO 深度设置为8。

    C:\ti\c2000Ware_3_02_00_00\device_support\F2833x\examples\SPI_loopback _interrupts\example_2833xSpi_FFDLB_int.c

    //
    // spiTxFifoIsr -
    //
    _interrupt void
    spiTxFifoIsr (void)
    {
    uint16 i;
    for (i=0;i<8;i++)
    {
    SpiaRegs.SPITXBUF=sdata[i]; //发送数据
    }
    
    for (i=0;i<8;i++) //递增下一个周期的数据
    {
    sdata[i]= sdata[i]+ 1;
    }
    
    SpiaRegs.SPIFFTX.bit.TXFFINTCLR=1;//清除中断标志
    PieCtrlRegs.PIEACX.ALL=0x20;//发出 PIE ACK
    }
    
    //
    spiRxFifoIsr -
    //
    _ interrupt void
    spiRxFifoIsr (void)
    {
    uint16 i;
    for (i=0;i<8;i++)
    {
    RDATA[i]=SpiaRegs.SPIRXBUF;//读取数据
    }
    
    for (i=0;i<8;i++) //检查接收到的数据
    {
    if (RDATA[i]!= RDATA_POIN+I)
    {
    error();
    }
    }
    RDATA_POIN++;
    SpiaRegs.SPIFFRX.bit.RXFFOVFCLR=1;//清除溢出标志
    SpiaRegs.SPIFFRX.bit.RXFFINTCLR=1;//清除中断标志
    

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

    您好、Gus、

    感谢您的耐力!

    使用示例中的代码、我仍然会将一些主数据发送回主器件...

    以下是我当前在主设备上的配置:

    uint16 sdata[8]; //发送数据缓冲
    器 uint16 RDATA[8]; //接收数据缓冲
    区 int main (void)
    {
    uint32 i=0、c=0;
    
    for (i=0;i<8;i++)
    {
    sdata[i]= 0x8888; //配置发送数据
    }
    
    SET_SYSTEM_controls ();
    INIT_PINS_AS_SPI_MASTER (GPIO16、GPIO17、GPIO18、GPIO19、 16、1500000);//字长:16位、波特率:1.5MHz
    while (1){
    SPI_Send (&sdata[0]);
    SPI_Read (&RDATA[0]);
    }
    
    返回0;
    } 

    初始化主站{
    
    
    //重置 TMC_BASE_SPIA->CCR
    &&~(0x1<<7)中设置;
    
    //启用主站模式、正常阶段、启用通话和禁用 SPI int。
    TMC_BAS_SPIA->CTL |= 0x0004;//启用主模式
    TMC_BAS_SPIA->CTL |= 0x0002;//启用传输
    //TMC_BAS_SPIA->CTL |= 0x0001;//启用中断
    TMC_BAS_SPIA->BRR |=(FMC_LSPCLK/SPIA->TRI
    
    
    
    ~
    )|= 0x1|/TRC_DRCI_1|/ TRFSI_RX |= 0x1|/TRIBRATIF_RX_1|/ TRF_Rx1|/|= TRF_RX_TRIB-1|/ TRF_Rx1|/ TRF_TRF_Rx1|/ TRIB-|+|= TRF_Rx1|/ TRF_Rx1|/ TRFAC_Rx1|/ TRFAC_TRF_TRF_Rx1|/ TO_
    //启用中断
    TMC_BAS_SPIA->FFRX |=(0x1<<6);//清除中断标志
    TMC_BAS_SPIA->FFRX |=(0x1<<13);//重新启用接收 FIFO 操作
    
    TMC_BASE_SPIA->FFTX |=(0x8);//将 TX FIFO 级别设置为1
    |/<TMC_BAS_1|/<SPIA-0X1|/<TMC_FFTMC_FFTX-|/<SPI=|/|/FFTMC_FFTX-BAS<0x1|/|/<SPI=|/FFTMC_FFTIC=|/|/|/|/FFTMC_FFTx1|/<SPI=|/FFTx1|/|/
    
    //从重置
    TMC_BASE_SPIA->FFTX 释放 FIFO |=(0x1<<14);//启用 FIFO 增强
    功能 TMC_BAS_SPIA->FFTX |=((UINT32) 0x1<<15);// SPI FIFO 恢复
    
    //重置
    TMC_BASE_SPIA->CCR 设置(0x1<<7);//从 SPI 撤回字符和字符长度
    

    下面是我在从设备上的配置:

    _interrupt void spiRxFIFOISR (void);
    __interrupt void spiTxFIFOISR (void);
    
    
    
    UINT16 sdata[8]; //发送数据缓冲
    器 uint16 RDATA[8]; //接收数据缓冲
    区 int main (void)
    {
    uint16 i=0;
    
    for (i=0;i<8;i++)
    {
    sdata[i]= 0xF0F0; //配置发送数据
    }
    
    SET_SYSTEM_controls ();
    INIT_PINS_AS_SPI_SLAVE (GPIO16、GPIO17、GPIO18、GPIO19、 16);//字长:16
    SPI_SET_Interrupt_RX (&spiRxFIFOISR);
    SPI_SET_Interrupt_TX (&spiTxFIFOISR);
    while (1){
    
    }
    
    返回0;
    }
    
    __interrupt void spirxFIFOISR (void){
    SPI_read (&sdata[0]);
    interrupt_ack_SPI ();
    
    }
    __interrupt void spitTxFIFOISR (void){SPI_ISR
    (&RDATA_Send
    (&SPI_0]);}interrupt [interrupt_SpinT_SPI_Sack_S[interrack_0
    

    初始化从站{
    //重置 TMC_BAS_SPIA->CCR
    &&~(0x1<<7);
    
    //启用从站
    TMC_BAS_SPIA->CTL &&~
    
    
    
    
    
    
    ~(0x0004);//禁用主模式 TMC_BAS_SPIA->CTL |=(0x2);//启用传输 TMC_BAS_SPIA-|SPICR-|= 0x1|SPICM_BAS_SPI-(0x1);TM_SPICR- ENTR_TR_TRI |/|/TO_TRIC_ENTIF-(0x1|/0x1|ENTR_SPI- ENTR_TRIC_SPI-);|/|ENTR_TR_TRIC_TRIC_TRIP_ENTRIP_ENTRIP_ENTRIP_ENTRIP_
    ////将 RX FIFO 级别设置为8
    TMC_BAS_SPIA->FFRX |=(0x1<5);//启用中断
    TMC_BAS_SPIA->FFRX |=(0x1<6);//清除中断标志
    TMC_BAS_SPIA->FFRX |=(0x1<13);//重新启用 TMC_FFIA-|= 0x14|SPIAC=|ENABLE-|ENABLE-TX_FFICE|ENABLE-|ENABLE-|ENABLED (0x14<TMC_TX_FFICENABLE-|ENABLE-|ENABLE-|ENABLE-|ENABLED);
    
    
    
    //从 TMC_TX_TX_FFICENABLE-|ENABLE-|ENABLE-|//将 TX FIFO 级别设置为8
    TMC_BASE_SPIA->FFTX |=(0x1<<5);//启用中断
    TMC_BASE_SPIA->FFTX |=(0x1<<6);//清除中断标志
    TMC_BASE_SPIA->FFTX |=((UINT32) 0x1<<15);//从 TMC_SPIAR
    
    
    复位|0开始重新设置 TMC_SPIAC-0x0;//从 TMC_REST/ SPI-恢复帧长度0x80/从 TCCR
    
    返回
    

    以下是我的函数

     

    void SPI_Send (uint16 * sdata){
    
    uint16 i;
    for (i=0;i<8;i++)
    {
    TMC_BASE_SPIA->TXBUF=sdata[i]; //发送数据
    }
    
    TMC_BAS_SPIA->FFTX |=(0x1<6);//清除中断标志
    
    }
    
    void SPI_Read (UINT16 * RDATA){
    
    uint16 I;
    for (i=0;i<8;i++)
    {
    RDATA[i]=TMC_BAS_SPIA->RXBUF;//读取数据
    |= 0x14_FFICK<1
    
    
    ;TMC_RXC=0x14<1;/FFIC_RX<1 |中断溢出|= 0x14_FFICK<1
    
    ;TMC_RX<1 

    感觉我现在几乎尝试了所有东西,但我总是在 SOMI 线上得到一些主数据...
    非常感谢你的帮助。

    此致、
    David

     

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

    David、

    查看从设备代码、我看到您初始化了 sdata 缓冲区并保持 RDATA 未初始化。 然后、对于您发送 RDATA 的 TX ISR、这对吗? 对于 RX ISR、您可以将接收到的数据保存在 sdata 中。

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

    [引用用户="Gus Martinez"]

    David、

    查看从设备代码、我看到您初始化了 sdata 缓冲区并保持 RDATA 未初始化。 然后、对于您发送 RDATA 的 TX ISR、这对吗? 对于 RX ISR、您可以将接收到的数据保存在 sdata 中。

    [/报价]

    您好、Guz、

    因为我在两台不同的计算机上运行从设备和主设备、所以我只是在这个论坛中输入了从设备通过键盘输入的代码、然后在那里出错了。  

    我的从机代码是:

    uint16 sdata[8];
    uint16 RDATA[8];
    int main (void)
    {
    uint16 i=0;
    for (i=0;i<8;i++){
    sdata[i]=0xF0F0;
    }
    SET_SYSTEM_controls ();
    init_PINS_AS_SPI_SLAVE (GPIO16、GPIO17、 GPIO18、GPIO19、16);
    SPI_SET_Interrupt_RX (&spiRxFIFOISR);
    SPI_SET_Interrupt_TX (&spiTxFIFOISR);
    
    while (1){
    
    }
    返回0;
    }
    
    __interrupt void spirxFIFOISR (void){
    SPI_read (&RDATA[0]);
    interrupt_ack_SPI ();
    }
    
    __interrupt void spitTxFIFOISR (void){
    SPI_Send (&sdata[0]);
    interrupt_ack_SPI ();
    } 

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

    您好、Gus、

    完全是这样  

    uint16 sdata[8];
    uint16 RDATA[8];
    int main (void)
    {
    uint16 i=0;
    for (i=0;i<8;i++){
    sdata[i]=0xF0F0;
    }
    SET_SYSTEM_controls ();
    init_PINS_AS_SPI_SLAVE (GPIO16、GPIO17、 GPIO18、GPIO19、16);
    SPI_SET_Interrupt_RX (&spiRxFIFOISR);
    SPI_SET_Interrupt_TX (&spiTxFIFOISR);
    
    while (1){
    
    }
    返回0;
    }
    
    __interrupt void spirxFIFOISR (void){
    SPI_read (&RDATA[0]);
    interrupt_ack_SPI ();
    }
    
    __interrupt void spitTxFIFOISR (void){
    SPI_Send (&sdata[0]);
    interrupt_ack_SPI ();
    } 

    我在论坛中输入错误...  

    此致、David

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

    尊敬的 David:

    好的、我不太确定会发生什么情况。 您能否提供任何其他信息? 例如、在零时、主器件 SPI 是否在从器件 SPI 启动时开始传输? 或者您是否有某种机制(GPIO?) 以确保从器件 SPI 在主器件启动前准备就绪? 从器件上的 CPU 是否与 SPI 从器件 TX 中断一起为任何其他中断提供服务? MISO 数据在传输开始时是否正常、并在稍后开始失败?

    我可以建议在*主设备*代码中使用 SPIFFCT 寄存器中的 FFTXDLY 位。 这些位增加了字传输之间的延迟。 或许这可以帮助您避免该问题?

    另一个建议是更改从器件侧的 TX ISR。 无需仅写入8个字符、而是完全填充 FIFO。 您可以在 SPIFFTX 寄存器中写入 TX FIFO、直至 TXFFST=10h。