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.
您好、TI 社区:
我在开发板上遇到了一个关于 MAX1978的问题、它无法响应来自 C2000 MCU 的 SPI 传输。 我将 MAX5144 DAC 用于 SPI-DAC 转换。 我发送了一个固定测试值计算为uint16_t fixedData = (uint16_t)(0.3 * 16383)
,考虑 MAX5144的14位分辨率。
//############################################################################# // // FILE: spi_ex3_external_loopback_fifo_interrupt.c // // TITLE: SPI Digital Loopback with FIFO Interrupts // //! \addtogroup driver_example_list //! <h1>SPI Digital External Loopback with FIFO Interrupts</h1> //! //! This program uses the external loopback between two SPI modules. Both //! the SPI FIFOs and their interrupts are used. SPIA is configured as a slave //! and receives data from SPI B which is configured as a master. //! //! A stream of data is sent and then compared to the received stream. //! The sent data looks like this: \n //! 0000 0001 \n //! 0001 0002 \n //! 0002 0003 \n //! .... \n //! FFFE FFFF \n //! FFFF 0000 \n //! etc.. \n //! This pattern is repeated forever. //! //! \b External \b Connections \n //! -GPIO25 and GPIO17 - SPISOMI //! -GPIO24 and GPIO16 - SPISIMO //! -GPIO27 and GPIO19 - SPISTE //! -GPIO26 and GPIO18 - SPICLK //! //! \b Watch \b Variables \n //! - \b sData - Data to send //! - \b rData - Received data //! - \b rDataPoint - Used to keep track of the last position in the receive //! stream for error checking //! // //############################################################################# // // $Release Date: $ // $Copyright: // Copyright (C) 2013-2023 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //############################################################################# // // Included Files // #include "driverlib.h" #include "device.h" // // Globals // volatile uint16_t sData[2]; // Send data buffer volatile uint16_t rData[2]; // Receive data buffer volatile uint16_t rDataPoint = 0; // To keep track of where we are in the // data stream to check received data // // Function Prototypes // void initSPIBMaster(void); void initSPIASlave(void); void configGPIOs(void); __interrupt void spibTxFIFOISR(void); __interrupt void spiaRxFIFOISR(void); // // Main // void main(void) { uint16_t i; // // Initialize device clock and peripherals // Device_init(); // // Disable pin locks and enable internal pullups. // Device_initGPIO(); // // Initialize PIE and clear PIE registers. Disables CPU interrupts. // Interrupt_initModule(); // // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // Interrupt_initVectorTable(); // // Interrupts that are used in this example are re-mapped to ISR functions // found within this file. // Interrupt_register(INT_SPIB_TX, &spibTxFIFOISR); Interrupt_register(INT_SPIA_RX, &spiaRxFIFOISR); // // Configure GPIOs for external loopback. // configGPIOs(); // // Set up SPI B as master, initializing it for FIFO mode // initSPIBMaster(); // // Set up SPI A as slave, initializing it for FIFO mode // initSPIASlave(); // // Initialize the data buffers // for(i = 0; i < 2; i++) { sData[i] = i; rData[i]= 0; } // // Enable interrupts required for this example // Interrupt_enable(INT_SPIA_RX); Interrupt_enable(INT_SPIB_TX); // // Enable Global Interrupt (INTM) and realtime interrupt (DBGM) // EINT; ERTM; // // Loop forever. Suspend or place breakpoints to observe the buffers. // while(1) { ; } } // // Function to configure SPI B as master with FIFO enabled. // void initSPIBMaster(void) { // // Must put SPI into reset before configuring it // SPI_disableModule(SPIB_BASE); // // SPI configuration. Use a 500kHz SPICLK and 16-bit word size. // SPI_setConfig(SPIB_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0, SPI_MODE_MASTER, 500000, 16); SPI_disableLoopback(SPIB_BASE); SPI_setEmulationMode(SPIB_BASE, SPI_EMULATION_FREE_RUN); // // FIFO and interrupt configuration // SPI_enableFIFO(SPIB_BASE); SPI_clearInterruptStatus(SPIB_BASE, SPI_INT_TXFF); SPI_setFIFOInterruptLevel(SPIB_BASE, SPI_FIFO_TX2, SPI_FIFO_RX2); SPI_enableInterrupt(SPIB_BASE, SPI_INT_TXFF); // // Configuration complete. Enable the module. // SPI_enableModule(SPIB_BASE); } // // Function to configure SPI A as slave with FIFO enabled. // void initSPIASlave(void) { // // Must put SPI into reset before configuring it // SPI_disableModule(SPIA_BASE); // // SPI configuration. Use a 500kHz SPICLK and 16-bit word size. // SPI_setConfig(SPIA_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0, SPI_MODE_SLAVE, 500000, 16); SPI_disableLoopback(SPIA_BASE); SPI_setEmulationMode(SPIA_BASE, SPI_EMULATION_FREE_RUN); // // FIFO and interrupt configuration // SPI_enableFIFO(SPIA_BASE); SPI_clearInterruptStatus(SPIA_BASE, SPI_INT_RXFF); SPI_setFIFOInterruptLevel(SPIA_BASE, SPI_FIFO_TX2, SPI_FIFO_RX2); SPI_enableInterrupt(SPIA_BASE, SPI_INT_RXFF); // // Configuration complete. Enable the module. // SPI_enableModule(SPIA_BASE); } // // Configure GPIOs for external loopback. // void configGPIOs(void) { // // This test is designed for an external loopback between SPIA // and SPIB. // External Connections: // -GPIO25 and GPIO17 - SPISOMI // -GPIO24 and GPIO16 - SPISIMO // -GPIO27 and GPIO19 - SPISTE // -GPIO26 and GPIO18 - SPICLK // // // GPIO17 is the SPISOMIA. // GPIO_setMasterCore(17, GPIO_CORE_CPU1); GPIO_setPinConfig(GPIO_17_SPISOMIA); GPIO_setPadConfig(17, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(17, GPIO_QUAL_ASYNC); // // GPIO16 is the SPISIMOA clock pin. // GPIO_setMasterCore(16, GPIO_CORE_CPU1); GPIO_setPinConfig(GPIO_16_SPISIMOA); GPIO_setPadConfig(16, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(16, GPIO_QUAL_ASYNC); // // GPIO19 is the SPISTEA. // GPIO_setMasterCore(19, GPIO_CORE_CPU1); GPIO_setPinConfig(GPIO_19_SPISTEA); GPIO_setPadConfig(19, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(19, GPIO_QUAL_ASYNC); // // GPIO18 is the SPICLKA. // GPIO_setMasterCore(18, GPIO_CORE_CPU1); GPIO_setPinConfig(GPIO_18_SPICLKA); GPIO_setPadConfig(18, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(18, GPIO_QUAL_ASYNC); // // GPIO25 is the SPISOMIB. // GPIO_setMasterCore(25, GPIO_CORE_CPU1); GPIO_setPinConfig(GPIO_25_SPISOMIB); GPIO_setPadConfig(25, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(25, GPIO_QUAL_ASYNC); // // GPIO24 is the SPISIMOB clock pin. // GPIO_setMasterCore(24, GPIO_CORE_CPU1); GPIO_setPinConfig(GPIO_24_SPISIMOB); GPIO_setPadConfig(24, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(24, GPIO_QUAL_ASYNC); // // GPIO27 is the SPISTEB. // GPIO_setMasterCore(27, GPIO_CORE_CPU1); GPIO_setPinConfig(GPIO_27_SPISTEB); GPIO_setPadConfig(27, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(27, GPIO_QUAL_ASYNC); // // GPIO26 is the SPICLKB. // GPIO_setMasterCore(26, GPIO_CORE_CPU1); GPIO_setPinConfig(GPIO_26_SPICLKB); GPIO_setPadConfig(26, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(26, GPIO_QUAL_ASYNC); } // // SPI A Transmit FIFO ISR // /*__interrupt void spibTxFIFOISR(void) { uint16_t i; // // Send data // for(i = 0; i < 2; i++) { SPI_writeDataNonBlocking(SPIB_BASE, sData[i]); } // // Increment data for next cycle // for(i = 0; i < 2; i++) { sData[i] = sData[i] + 1; } // // Clear interrupt flag and issue ACK // SPI_clearInterruptStatus(SPIB_BASE, SPI_INT_TXFF); Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP6); }*/ __interrupt void spibTxFIFOISR(void) { uint16_t i; // 计算DAC的固定值,例如0.3的比例 uint16_t fixedData = (uint16_t)(0.3 * 16383); // 16383 = 2^14 - 1 uint8_t highByte, lowByte; // 从16位数据中提取两个8位字节 highByte = (fixedData >> 8) & 0xFF; // 高8位 lowByte = fixedData & 0xFF; // 低8位 // 发送数据 for(i = 0; i < 2; i++) { // 发送高8位 SPI_writeDataNonBlocking(SPIB_BASE, highByte); // 发送低8位 SPI_writeDataNonBlocking(SPIB_BASE, lowByte); } // Increment data for next cycle - 但在这里我们不修改数据,因为我们发送固定的值 for(i = 0; i < 2; i++) { // 在这里不需要修改sData,因为我们总是发送相同的固定值 } // 清除中断标志并确认 SPI_clearInterruptStatus(SPIB_BASE, SPI_INT_TXFF); Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP6); } // // SPI B Receive FIFO ISR // __interrupt void spiaRxFIFOISR(void) { uint16_t i; // // Read data // for(i = 0; i < 2; i++) { rData[i] = SPI_readDataNonBlocking(SPIA_BASE); } // // Check received data // for(i = 0; i < 2; i++) { if(rData[i] != (rDataPoint + i)) { // Something went wrong. rData doesn't contain expected data. Example_Fail = 1; ESTOP0; } } rDataPoint++; // // Clear interrupt flag and issue ACK // SPI_clearInterruptStatus(SPIA_BASE, SPI_INT_RXFF); Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP6); Example_PassCount++; } // // End of File //
SPI 输出看上去正确、但 MAX1978未按预期作出响应、尤其是在 TEC 温度控制方面。 我预计 TEC 会因对应于0.3 DAC 值而升温。 是否有人可以就此问题提供见解或故障排除建议?
提前感谢!
内罗
我更新了代码以符合 MAX5144接收格式、但输出信号现在为奇数;有人能解释原因吗?
第一个看起来不错、但为什么第二个看起来
现在有一个奇怪的加热效应,一个常规的加热,然后突然冷却。
尊敬的 Nero:
下面是代码中的几个观察结果:
1.在 init 函数中、两个 SPI 实例都 配置为传输16位字。 对于您的用例,您需要修改 SPI_setConfig ()中的 dataWidth 参数。 至8。
2. 如前文所述,传输的数据必须以16位格式传递,所需的 N 位左对齐。 因此,在 spibTxFIFOISR ()中,highByte 和 lowByte 需要匹配此格式。 此外、 对于循环将在每个 ISR 中传输来自 fixedData 的位两次。
更新这些选项会为您提供正确的 SPI 输出。
关于 MAX1978答复中的不一致性,我建议查阅它们的参考手册。 输入数据的格式化约定可能不同、因此这需要在接收板上处理。
谢谢。
阿纳维
我面临一个问题、在 DAC 数据传输完成后、我的 SPI 设置中的 CS 线路保持低电平、而不是变为高电平。 时序图显示、在最后一个数据位随时钟移出后、CS 不会返回高电平。 验证所有连接并仔细检查 SPI 配置。 对于可能导致 CS 线路保持低电平的原因、提供任何建议都会有所帮助。
我做了这个,在改变了它之后,现在没有更多的信号哈哈
CS 仍然无法正常工作。 真正需要帮助。
尊敬的 Nero:
在一次传输结束到另一次传输开始之间应该有一个特定的延迟周期、以便 CS 恢复到高电平无效状态。 您可以参阅 F28379D 数据表( 8.12.5.1.1.2 )了解确切详情:
由于 TX 中断持续进入、两个中断之间的间隔可能不足以使 CS 线路返回。 您可以尝试在 N 个传输完成后停止中断、或在传输之间添加足够的延迟、并观察 CS 引脚。
谢谢。
阿纳维
我在 DAC 电压控制的 SPI 通信方面取得了一些进展。 目标是将电压稳定在0.3V、以匹配相应的温度设置。 但是、我观察到电压持续保持在0.4V。
我怀疑热敏电阻与 TEC 的接触可能存在问题、因此我尝试通过使用 uint16_t fixedData =((0.2/1.5)* 16383)(这是针对0.2V 计算得出的14位 DAC 值)来降低代码中的目标电压、从而调整 DAC 设置。 尽管如此、输出保持在0.4V、没有如预期的那样下降。
是否存在妨碍 DAC 正确调整电压的通信问题? 或者、问题更有可能出在热敏电阻与 TEC 的物理组装或接触上?
非常感谢您的深入见解。
内罗
我目前遇到 SPI 通信问题、即在预期传输结束后附加了意外的字节。 所需的行为是传输一对0x22
字节。 但是、逻辑分析仪布线可以证明、0x20
字节始终按照正确的对进行传输、我俗称为"小尾"。
这个假字节不是预期数据帧的一部分、并且它的持续出现表明它可能是当前 SPI 缓冲区处理或 ISR 配置的产物。 我努力修改传输代码、消除这个多余的字节、但尚未产生所需的干净信号。
我正在寻求帮助或建议以解决这一不正常现象。 我们非常感谢您对潜在原因或纠正措施的任何深入了解。
此问题的核心是、在将代码中的值从0.2更改为0.4后、为了将输出加倍至 DAC、SPI 输出不显示预期结果。 与双倍不同的是,输出显示0x88
在 MOSI 线上,这不是计算值(0x4444
左对齐后),并且偶尔有意外的变化,如0x80
或0x8C
. 这表明数据准备或 SPI 传输过程存在问题。
__interrupt void spibTxFIFOISR (void)
{
//计算DAC的固定值,例如0.3的比例
uint16_t fixedData =(uint16_t)((0.4 / 1.5)* 16383);// 14位 DAC 值
fixedData = fixedData << 2;//左对齐数据以使其变为16位
//将固定值放入sData数组中,准备发送
sData[0]= fixedData;
//检查发送FIFO是否为空并准备好发送新数据
while ((SPI_getTxFIFOStatus (SPIB_BASE)和 SPI_FIFO_TXEMPTY)!= SPI_FIFO_TXEMPTY);
//发送数据
SPI_writeDataNonBlocking (SPIB_BASE、sData[0]);
device_delay_us (100);
//清除发送FIFO中断标志
SPI_clearInterruptStatus (SPIB_BASE、SPI_INT_TXFF);
INTERRUPT_clearACKGROUP (INTERRUPT_ACK_group6);
// device_delay_us (100);
}
我将根据 TI 数据表的主模式开关特性对我们项目中的 SPI 时序进行微调。 我需要在 SCLK 的上升沿之前对齐 MOSI 信号、但我们系统的微秒级粒度对实现规格中详述的纳秒级精确计时提出了挑战。
您能建议在我们的微控制器的限制范围内转移 MOSI 时序的策略、或者这种精度是否需要额外的硬件吗?
尊敬的 Nero:
为此,您可以调整 SPI_setConfig()中的协议参数。 利用该选项、您可以配置极性(是否在上升沿或下降沿输出数据)和相位(是否添加半个周期延迟)。
谢谢。
阿纳维