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.
大家好、
我的 SPI 在 TMS320F28377S 上运行、并且在 CLK 和 MOSI 之间具有时间抖动。
我已将 SPI 配置为每个字符输出12位、对于测试、我使用0b110010101100的位编码值。
在示波器上、我看到最后的位丢失了、而时钟开始很早。
我在初始化中n´t 考虑什么吗?
请参见下面的示波器´s 屏幕截图以及我的 SPI_Init 和 ISR。
此致!
#define SPI_BRR (((200E6 / 4)/ 500E3)- 1 void DACSink:::Init () { EALLOW; //ClkCfgRegs.LOSPP.bit.LSPCLKDIV = 0; //SpiaRegs.SPICCR.bit.HS_MODE = 0x1; // //为所选引脚启用内部上拉 // //用户可以启用或禁用上拉。 //这将启用指定引脚的上拉电阻。 //注释掉其他不需要的行。 // //GpioCtrlRegs.GPAPUD.bit.GPIO16=0;//启用 GPIO16上的上拉电阻器(SPISIMOA) //GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0;//启用 GPIO18 (SPICLKA) GpioCtrlRegs.GPBPUD.bit.GPIO58上的上拉电阻;//启用 GPIO16上的上拉电阻(SPISIMOA) GpioCtrlRegs.GPBPUD.BIO60 = 0;//启用 GPIO16上拉电阻器(SPICOL) // //仅将所选引脚的限定条件设置为异步 // //这将为所选引脚选择异步(无限定条件)。 //注释掉其他不需要的行。 // GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 3;//异步输入 GPIO16 (SPISIMOA) GpioCtrlRegs.GPBQSEL2.bit.GPIO60 = 3;//异步输入 GPIO18 (SPICLKA) // //使用 GPIO 寄存器配置 SPI-A 引脚 // //这指定哪些可能的 GPIO 引脚将是 SPI 功能 //引脚。 //注释掉其他不需要的行。 // GpioCtrlRegs.GPBGMUX2.bit.GPIO58 = 3;//将 GPIO16配置为 SPISIMOA GpioCtrlRegs.GPBGMUX2.bit.GPIO60 = 3;//将 GPIO18配置为 SPICLKA GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 3;//将 GPIO16配置为 SPISIMOA GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 3;//将 GPIO18配置为 SPICLKA // //初始化 SPI FIFO 寄存器 // SpiaRegs.SPIFFTX.bit.TXFFINTCLR = 1; SpiaRegs.SPIFFTX.bit.SPIFFENA = 1; SpiaRegs.SPIFFTX.bit.TXFIFO = 0;//复位 fifo 指针 SpiaRegs.SPIFFTX.bit.TXIFFIFO = 1;SPIFFF.TXIF.位 = 1 ;SPIFFIFT.TXIF.TXIF.SPIF.位= 1;SPIFFIF.TXIF.TXIF.SPIF.SPIF.TXIF.位= 1;SPIF.TXIF.TXIF.SPIF.TXIF.SPIF.SPIF.TXIF.SPIF.SPIFT.TXIFT.TXIF.SIFIF.SPIF.SPIF.SIFF.TXIF.SI //初始化 SPI-A //在配置更改之前将 RESET 设置为低电平 //时钟极性(0 =上升、1 =下降) // 16位字符 //启用环回 SpiaRegs.SPICCR.bit.SPISWRESET = 0; SpiaRegs.SPICCR.bit.CLKPOLARITY = 0; SpiaRegs.SPICCR.bit.SPICHAR =(12-1); SpiaRegs.SPICCR.bit.SPILBK = 0; //启用主设备(0 =从设备,1 =主设备) //启用传输(TALK) //时钟相位(0 =正常、1 =延迟) //启用 SPI 中断 SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1; SpiaRegs.SPICTL.bit.TALK = 1; SpiaRegs.SPICTL.bit.CLK_PHASE = 0; SpiaRegs.SPICTL.bit.SPIINTENA=1; //设置波特率 SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = SPI_BRR; //设置空闲位 //在断点上停止不会停止 SPI SpiaRegs.SPIPRI.bit.FREE = 1; //解除 SPI 复位 SpiaRegs.SPICCR.bit.SPISWRESET = 1; PieCtrlRegs.PIEIER6.bit.INTx2 = 1; //启用 PIE 组6、INT 2 IER = M_INT6; //启用 CPU INT6 PieVectTable.SPIA_TX_INT =&spiAint; EDIS; }
_interrupt void spiAint (void) { DELAY_US (1000); GpioDataRegs.GPACLEAR.BIO19 = 1; SpiaRegs.SPITXBUF=3244; SpiaRegs.SPIFFTX.bit.TXFFINTCLR=1;//清除中断标志 PieRegs.SPITXBUF=3244 ;SpiaRegs.SpiIFFTX.BIFT.TXT.BIEACT.BIECM=1| //发出 PIE ACK GpioDataRegs.GPASET.bit.GPIO19=1; }
我在调查其他事情时"意外地"发现自己。
密钥是将左调整后的值写入 SpiaRegs.SPITXBUF = XXX、即使 SPI 字符的大小设置为小于16;在我的情况下为12。
我想、当 SPI 硬件移出位时、它始终从位15开始、即使定义的字符大小更小、硬件也会在之后停止
定义字符大小的时钟周期的数量。 如果字符大小为12、则意味着
硬件不会移出 SPIDAT 的位[11下降至0]。 而是移出位[15降至4]。
因此、需要对要移出的值进行左调整。 关于我的 DEC.3244 12位值示例、 必须将其乘以16。 那么它可以正常工作。
您好!
您的最终解决方案是处理小于16位发送的正确方法。 您必须将 TX 数据向左移动才能正确传输。 它将从 SPIDAT 的 BIT15开始、并根据您的字大小配置发送适当的位数。 在接收端、您的数据将位于寄存器的下部;也就是说、为了安全起见、您可以读取 SPIRXBUF/SPIDAT 并屏蔽未使用的位。
谢谢、
标记
编辑:更正了第一句、我没有意识到您最初按预期传输12位。 出于某种原因、我看到了16位... 一切都很好、如果您不正确移动数据、则可以看到原始行为。