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.

[参考译文] CCS/LAUNCHXL-F28379D:10MHz 时的 SPI FIFO 中断问题

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/843287/ccs-launchxl-f28379d-spi-fifo-interrupt-issue-at-10mhz

器件型号:LAUNCHXL-F28379D

工具/软件:Code Composer Studio

我正在尝试使用 F28379D LaunchPad 作为具有10MHz 波特率的从器件通过 SPI 进行通信。 但接收到的数据存在一些问题。

1)使用具有8个字的缓冲器通过 FIFO 发送数据时、接收到的数据将移动1位(例如发送:0x000B、接收:0x0003)、并移动整个缓冲器(例如、收发:0xFFFF、0x0000、0x016、0x22FF、0x029A、 0x008、0x0018、0x002A、接收:0x7FFF、0x8000、 0x000B、0x117F、0x814D、0x0004、0x000C、 0x0015)。 最后一个位成为第一个接收位、依此类推。 使用5MHz 时出现同样的问题。 [问题已解决、请参阅 edit2]

2) 2)当使用1MHz 或者2MHz 波特率时、它运行完美、但是在最大值上具有8字大小的缓冲器 我找不到具有较大缓冲区的模式、但它始终以随机序列显示预设数据(例如、传输 的:0xFFFF、0x0000、0x016、0x22FF、0x029A、 0x008、0x0018、0x002A、0x44CB、接收: 0x002A、 0x44CB、0x0016、0x22FF、0x029A、0x0008、 0x0018、0x002A、0x44CB)它始终是一些预设数据、但不一定是相同顺序或相同数据。 [问题已解决、请参阅 edit1]

3) 3)我还意识到、一旦我运行代码、ISR 在开始时会执行2次、甚至会将 CS 引脚保持在高电平。[问题已解决、种子 edit3]

编辑1:解决了第二个问题。 Drec接收 SPI_FIFO_TX8和 SPI_FIFO_TX8、溢出指令。 我认为这是大小指令、但完全相反。  

编辑2:解决了第一个问题。 更改 SPI 模式、以使用阶段1 (即从 SPI_PROT_POL0PHA0到 SPI_PROT_POL0PHA1的指令模式)。  

edit3:通过将 SPI_FIFO_TX8和 SPI_FIFO_RX8更改为 SPI_FIFO_TX0和 SPI_FIFO_RX0来解决第3个问题、现在、如果它与 FIFO 中的任何插槽保持一致而没有数据、它将始终生成中断。 此外、将缓冲区大小重新密封为16、因此它始终合适、并且将在从 FIFO 读取中断时立即生成中断。  

#include "driverlib.h"
#include "device.h"

//定义
#define FIFOTX SPI_FIFO_TX8 //传输 FIFO 大小
#define FIFORX SPI_FIFO_RX8 //received FIFO 大小也未使用
#define buffer_size 8
#define BAUD_R 1000000

//Globals
volatile uint16_t RDATA[buffer_RX8]/0x29FFFF、0x0000_size]、0x29FFFF
、0x0000_size = 0x20FFFF、0x29FFFF、0x20_uFFFF、0x20_uFFF]、0x20_uFFFF、0x29FFF[0x20_SD 0x008、0x0018、0x002A};

//函数原型
void initSPI (void);
void initSPI_GPIO (void);
__interrupt void spibTxFIFOISR (void);


// Main
void main (void)
{
//
//初始化设备时钟和外设
//
device_init();

//
//禁用引脚锁定并启用内部上拉。
//
DEVICE_initGPIO();

//
//初始化 PIE 并清除 PIE 寄存器。 禁用 CPU 中断。
//
interrupt_initModule();

//
//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//
interrupt_initVectorTable();

//
//设置 SPI,将其初始化为 FIFO 模式
//
interrupt_register (INT_SPIB_TX、&spibTxFIFOISR);
initspi_gpio();
initspi();

INTERRUPT_ENABLE (INT_SPIB_TX);

//
//启用全局中断(INTM)和实时中断(DBGM)
//
EINT;
ERTM;

//
//永久循环。 暂停或放置断点以观察缓冲区。
//
while (1)
{
;
}
}

void initSPI()
{
//
//必须在配置 SPI 之前将其复位
//
SPI_disableModule (SPIB_BASE);

//
// SPI 配置。 使用12MHz SPICLK 和16位字大小。
//

SPI_setConfig (SPIB_BASE、DEVICE_LSPCLK_FREQ、SPI_PROT_POL0PHA0、
SPI_MODE_SLAVE、BAUD_R、16);
SPI_disableLoopback (SPIB_BASE);
SPI_setEmulationMode (SPIB_BASE、SPI_emulation_stop_after_transmit);
//SPI_enableHighSpeedMode (SPIB_BASE);

//FIFO 和中断配置

SPI_enableFIFO (SPIB_BASE);
SPI_clearInterruptStatus (SPIB_BASE、SPI_INT_TXFF);
SPI_setFIFOInterruptLevel (SPIB_BASE、FIFOTX、FIFORX);
SPI_enableInterrupt (SPIB_BASE、SPI_INT_TXFF);
//配置完成。 启用模块。
//
spi_enableModule (SPIB_BASE);
}

void initspi_gpio()
{
EALLOW;


//SPI B 配置

GPIO_setPadConfig (63、GPIO_PIN_TYPE_PULLUP);
GPIO_setPadConfig (64、GPIO_PIN_TYPE_PULLUP);
GPIO_setPadConfig (65、GPIO_PIN_TYPE_PULLUP);
GPIO_setPadConfig (66、GPIO_PIN_TYPE_PULLUP);

GPIO_setDirectionMode (63、GPIO_DIR_MODE_IN);
GPIO_setDirectionMode (64、GPIO_DIR_MODE_OUT);
GPIO_setDirectionMode (65、GPIO_DIR_MODE_IN);
GPIO_setDirectionMode (66、GPIO_DIR_MODE_IN);

GPIO_setQualificationMode (63、GPIO_QUAL_异 步);
GPIO_setQualificationMode (64、GPIO_QUAL_异 步);
GPIO_setQualificationMode (65、GPIO_QUAL_异 步);
GPIO_setQualificationMode (66、GPIO_QUAL_异 步);

GPIO_setPinConfig (GPIO_63_SPISIMOB);
GPIO_setPinConfig (GPIO_64_SPISOMIB);
GPIO_setPinConfig (GPIO_65_SPICLKB);
GPIO_setPinConfig (GPIO_66_SPISTEB);


EDIS;
}
//
// SPI A 发送 FIFO ISR
//
__interrupt void spibTxFIFOISR (void)
{
uint16_t i;

//
//发送数据
//
for (i = 0;i < buffer_size;i++)
{
SPI_writeDataNonBlocking (SPIB_BASE、sData[i]);
}

//
//清除中断标志并发出 ACK
//
SPI_clearInterruptStatus (SPIB_BASE、SPI_INT_TXFF);
interrupt_clearACKGroup (interrupt_ack_group6);
} 

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

    1:所有内容都被1位移位的情况使我想到预期的相位/极性设置中存在不匹配。 调整它们时、您是否看到任何差异? 我看到你有一个注释掉的调用来启用高速模式--与启用的模式没有什么区别?

    在这种情况下、您使用的 FIFO 中断级别是多少? 是否发生 FIFO 溢出?

    由于这是从器件端、因此发送功能实际上只是填充 FIFO、以便在主器件启动时钟时做好准备、因此即使 CS/CLK 未激活、也可以获得中断。

    惠特尼

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

    1.是的、主器件和从器件之间的设置是相同的相位/极性。 我将尝试对此进行调整、很快就会报告。 关于高速模式注释、启用时没有区别、而且我找不到合适的引脚来使用这种模式。 [编辑2]

    我已经注意到了、就在我发布后。 我解决了这个问题。 只是更改了 FIFO 水平(即  SPI_FIFO_TX8或 SPI_FIFO_TX8指令)

    3.我没有得到它,它是否仅在时钟被触发时才被执行? 填充 FIFO 的函数位于中断例程内。 为什么只有2次? 主器件不向该从器件发送任何内容、已从另一个从器件断开连接并将 CS 设置为高电平、一旦我运行代码、寄存器就会被修改。 对我来说毫无意义。

    编辑2:1. 报告有关更改极性/相位的情况:在某种程度上、它通过将相位更改为1来工作、极性0或极性1也可以正常工作。 这是否可行、因为存在某种总线延迟?

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

    TX FIFO 中断是根据 FIFO 中的空间大小产生的、因此、如果 FIFO 水平由于任何原因(启动、FIFO 复位、传输移出数据等)低于中断阈值、它将生成中断。 即使主器件没有输出有意义的数据、主器件也始终在 SPI 中驱动时钟。

    由于它是一个16字 FIFO、并且 FIFO 中断级别是8个字、所以在开始时它会发生两次-在前8个字被加载后、仍然有8个字的空间、因此会产生另一个中断。

    惠特尼

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

    这正是发生的事情! 更改了 FIFO 溢出指令、并调整了缓冲区大小。 现在它只发生一次。