TI E2E™ 设计支持论坛将于 5 月 30 日至 6 月 1 日进行维护。如果您在此期间需要技术支持,请联系 TI 的客户支持中心寻求帮助。

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.

[参考译文] LAUNCHXL-F28379D:CCS/LAUNCHXL-F28379D:两个 f28379D LaunchPad 之间的 SPI 通信

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/984133/launchxl-f28379d-ccs-launchxl-f28379d-spi-communication-between-two-f28379d-launchpads

器件型号:LAUNCHXL-F28379D
主题中讨论的其他器件:C2000WARE

尊敬的所有人:

你好

我是 CCS 领域的初学者、我需要帮助。 我正在尝试  使用 SPI 在两个 f28379D LaunchPad 之间进行通信。 我想将数据从主器件发送到从器件。  但是、问题即将出现。 在主器件中一切都很好。 我用示波器观察到主器件中的波形。 SPICLK、SPIMOSI 和 SPISTE 的波形正确。 但是 、SPIDAT 和 SPIRXBUF 的值为0。 我认为数据(MOSI)不会进入 寄存器。


对于主器件、我有以下代码:


#if CPU_FRQ_200MHz
#define SPI_BRR ((200E6/4)/5E6)- 1.
#endif

void main (void)

uint16 sdata;//发送数据

//
//初始化系统控制:
//
InitSysCtrl();

//
//初始化 GPIO:
//
InitSpiaGpio();


Dint;

//
//将 PIE 控制寄存器初始化为默认状态。
/
InitPieCtrl();

//
//禁用 CPU __interrupts 并清除所有 CPU __interrupt 标志:
//
IER = 0x0000;
IFR = 0x0000;


InitPieVectTable();


SPI_Fifo_init();//初始化 SPI FIFO

sdata = 0x05A9;
for (;;)

//
//发送数据
//
SPI_xmit (sdata<5);


void SPI_xmit (uint16 A)

SpiaRegs.SPITXBUF = A;

void SPI_Fifo_init()

//
//初始化 SPI FIFO 寄存器
//
SpiaRegs.SPIFFTX.All=0xA040;
SpiaRegs.SPIFFRX.All=0x2044;
SpiaRegs.SPIFFCT.All=0x0;
//
//初始化内核 SPI 寄存器
//
InitSpi();

空 InitSpi()

SpiaRegs.SPICCR.All=0x00AA;
SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
SpiaRegs.SPICTL.bit.TALK = 1;
SpiaRegs.SPICTL.bit.CLK_PHASE = 1;
SpiaRegs.SPICTL.bit.SPIINTENA=1;
//设置波特率
SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = SPI_BRR;
SpiaRegs.SPICCR.bit.SPISWRESET = 1;
SpiaRegs.SPIPRI.bit.FREE = 1;

空 InitSpiaGpio()

EALLOW;
GpioCtrlRegs.GPBPUD.bit.GPIO58 = 0;//启用 GPIO58上的上拉电阻器(SPISIMOA)
GpioCtrlRegs.GPBPUD.bit.GPIO59 = 0;//启用 GPIO59上的上拉电阻器(SPISOMIA)
GpioCtrlRegs.GPBPUD.bit.GPIO60 = 0;//启用 GPIO60上拉(SPICLKA)
GpioCtrlRegs.GPBPUD.bit.GPIO61 = 0;//启用 GPIO61上的上拉电阻器(SPISTEA)

GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3;//异步输入 GPIO58 (SPISIMOA)
GpioCtrlRegs.GPBQSEL2.bit.GPIO59 = 3;//异步输入 GPIO59 (SPISOMIA)
GpioCtrlRegs.GPBQSEL2.bit.GPIO60 = 3;//异步输入 GPIO60 (SPICLKA)
GpioCtrlRegs.GPBQSEL2.bit.GPIO61 = 3;//异步输入 GPIO61 (SPISTEA)

GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 3;//将 GPIO58配置为 SPISIMOA
GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 3;//将 GPIO59配置为 SPISOMIA
GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 3;//将 GPIO60配置为 SPICLKA
GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 3;//将 GPIO61配置为 SPISTEA

GpioCtrlRegs.GPBGMUX2.bit.GPIO58 = 3;//将 GPIO58配置为 SPISIMOA
GpioCtrlRegs.GPBGMUX2.bit.GPIO59 = 3;//将 GPIO59配置为 SPISOMIA
GpioCtrlRegs.GPBGMUX2.bit.GPIO60 = 3;//将 GPIO60配置为 SPICLKA
GpioCtrlRegs.GPBGMUX2.bit.GPIO61 = 3;//将 GPIO61配置为 SPISTEA
EDIS;


对于从器件、我有以下代码:

void main (void)

uint16 RDATA;//接收的数据

//
//初始化系统控制:
//  
InitSysCtrl();

//
//初始化 GPIO:
//
InitSpiaGpio();

//
//清除所有中断:
//
Dint;

//
//将 PIE 控制寄存器初始化为默认状态。
//
InitPieCtrl();

//
//禁用 CPU __interrupts 并清除所有 CPU __interrupt 标志:
//
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();

//
//初始化设备外设:
//
SPI_Fifo_init();//初始化 SPI FIFO

for (;;)

//
//等待数据被接收
//
while (!SpiaRegs.SPISTS.bit.INT_flag){}
RDATA = SpiaRegs.SPIRXBUF;
RDATA =RDATA>>5;



void SPI_xmit (uint16 A)

SpiaRegs.SPITXBUF = A;

//
// SPI_Fifo_init -初始化 SPIA FIFO
//
void SPI_Fifo_init()

//
//初始化 SPI FIFO 寄存器
//
SpiaRegs.SPIFFRX.bit.RXFFIL = 0x00;// 4:0中断级别
SpiaRegs.SPIFFRX.bit.RXFFIENA =0;// 5中断使能0
SpiaRegs.SPIFFRX.bit.RXFFINTCLR = 0;// 6清除 INT 标志
SpiaRegs.SPIFFRX.bit.RXFFINT = 0;// 7 INT 标志
SpiaRegs.SPIFFRX.bit.RXFFST = 0;// 12:8 FIFO 状态
SpiaRegs.SPIFFRX.bit.RXFIFORESET = 0;// 13 FIFO 复位
SpiaRegs.SPIFFRX.bit.RXFFOVFCLR = 0;// 14清除溢出
SpiaRegs.SPIFFRX.bit.RXFFOVF = 0;// 15 FIFO 溢出

SpiaRegs.SPIFFCT.All=0x0;
//
//初始化内核 SPI 寄存器
//
InitSpi();

空 InitSpi (空)

//设置波特率
SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = SPI_BRR;
//在断点上停止不会停止 SPI
SpiaRegs.SPIPRI.bit.FREE = 1;
//初始化 SPI-A
SpiaRegs.SPICCR.All=0x00AA;

SpiaRegs.SPICTL.bit.MASTER_SLAVE = 0;
SpiaRegs.SPICTL.bit.TALK = 0;
SpiaRegs.SPICTL.bit.CLK_PHASE = 0;
SpiaRegs.SPICTL.bit.SPIINTENA=1;
SpiaRegs.SPIPRI.bit.STEINV = 0;

空 InitSpiaGpio()

EALLOW;
GpioCtrlRegs.GPBPUD.bit.GPIO58 = 0;//启用 GPIO16上的上拉电阻器(SPISIMOA)
GpioCtrlRegs.GPBPUD.bit.GPIO59 = 0;//启用 GPIO17上的上拉电阻器(SPISOMIA)
GpioCtrlRegs.GPBPUD.bit.GPIO60 = 0;//启用 GPIO18上的上拉电阻器(SPICLKA)
GpioCtrlRegs.GPBPUD.bit.GPIO61 = 0;//启用 GPIO19上的上拉电阻器(SPISTEA)

GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3;//异步输入 GPIO16 (SPISIMOA)
GpioCtrlRegs.GPBQSEL2.bit.GPIO59 = 3;//异步输入 GPIO17 (SPISOMIA)
GpioCtrlRegs.GPBQSEL2.bit.GPIO60 = 3;//异步输入 GPIO18 (SPICLKA)
GpioCtrlRegs.GPBQSEL2.bit.GPIO61 = 3;//异步输入 GPIO19 (SPISTEA)

GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 3;//将 GPIO16配置为 SPISIMOA
GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 3;//将 GPIO17配置为 SPISOMIA
GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 3;//将 GPIO18配置为 SPICLKA
GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 3;//将 GPIO19配置为 SPISTEA
EDIS;

//
//文件结束
//


我应该更改这部分代码的哪一部分、以便我的从器件可以读取数据?

如果您能帮我解决问题、我将不胜感激。

此致、

Jessie

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

    Jessie、您好!

    [引用 userid="479834" url="~/support/microcontrollers/c2000/f/c2000-microcontrollers-forum/984133/launchxl-f28379d-ccs-launchxl-f28379d-spi-communication-between-two-f28379d-launchpads "]此代码部分的哪一部分应该更改,以便从设备可以读取数据?

    看起来您在 SPI 上使用 FIFO 模式、但您正在尝试使用 INT_FLAG 位来确定何时接收到字符。 请参阅 F2837xD 技术参考手册中有关使用 INT_FLAG 位的说明:"注意:如果启用 FIFO 模式、则不应使用此位。 将接收到的字从 SPIRXBUF 复制到接收 FIFO 的内部过程会将该位清零。 使用 FIFO 状态或 FIFO 中断位实现相似功能。"

      应改为使用 SPIFFRX 寄存器中的 RXFFST 位。 如果不起作用、请仔细检查您的引脚多路复用器配置以及 LaunchPad 之间的连接。

    我建议您利用 SPI 外部回送示例作为参考。

    C:\ti\c2000Ware_3_03_00_00\driverlib\f2837xd\examples\cpu1\spi\spi_ex3_external_loopback_fifo_interrupts.c

    实际上、driverlib 中实现了一个用于检查 FIFO 状态的函数。 您可以在  C:\ti\c2000\C2000Ware_3_03_00_00\driverlib\spi.h 中看到源代码

    SPI_readDataBlockingFIFO (uint32_t base)

    //
    //检查参数。
    //
    assert (SPI_isBaseValid (base));

    //
    //等待数据在接收 FIFO 中可用。
    //
    while (SPI_getRxFIFOStatus (base)=SPI_FIFO_RXEMPTY)



    //
    //检查要读取的数据。
    //
    返回(HWREGH (base + SPI_O_RXBUF));

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

    您好!

    非常感谢您的帮助。 但我仍然有问题。 当我将 子例程 、SPI_readDataBlockingFIFO (uint32_t base)放入从器件代码中时、它会变成错误。 我应该 包含 spi.h 文件吗?

    此致、

    Jessie

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

    Jessie、

    我只添加了子例程作为参考。 如果您只是将代码复制粘贴到代码中、链接器将会抱怨、因为您没有正确地声明函数以及函数中的变量。

    您不需要这样做、就可以了解函数在做什么并向代码中添加类似的指令。 在这种情况下、您需要在代码中添加一条指令来轮询  SPIFFRx 中的 RXFFST 位、直到它为非零、然后读取 SPIRXBUF 寄存器。

    您基本上必须编辑自己代码的一行:

    for (;;)

    //
    //等待数据被接收
    //
    while (!SpiaRegs.SPISTS.bit.INT_flag){}
    RDATA = SpiaRegs.SPIRXBUF;
    RDATA =RDATA>>5;