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.

[参考译文] EK-TM4C123GXL:TM4C123GXL 外部 SPI ADC (Maxim MAX11060)

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/593454/ek-tm4c123gxl-tm4c123gxl-external-spi-adc-maxim-max11060

器件型号:EK-TM4C123GXL
嗨、大家好、我在通过 SPC 从外部 ADC 读取数据时遇到问题、似乎找不到问题。 此时、我不断地从 ADC 接收0。 我使用的 ADC 是 MAX11060 (https://datasheets.maximintegrated.com/en/ds/MAX11040K-MAX11060.pdf)、我不确定是什么问题、我在下面列出了我的所有代码。 

谢谢你 





#include #include #include #include #include #include include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "driverlib/adc.h" #include "driverlib/podec.h" #include "driverlib/fpu.h" #include "driverlib/gpio.h" #include "driverlib/driver.h"#include "driverlib/moverview.h"#include "driverlib.包含"driverlib/mvoltex"driver.h"#包含"driverlib/mov.h"#包含"driverib/driverlib.hr.ide"#driver.h"#包含"driverlib#driverlib#driverlib.inc"#driver.h"#driverlib.intrintrl.ide"#包含"driver.h"#driver.h/driverlib#driver.h/driverlib#driverlib#include "driver.h"#包含"driverlib#driverlib#driver.h"#包含"driverlib#driverlib#driver.h/driverlib#driverlib#driver.h" #包含"driverlib#driv //variable DECLARTATIONS //============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================ ================================================================================================================================================================================================================SSI_DATA 2 uint32_t ui32Loop、ui32Index; uint32_t pui32DataTx[NUM_SSI_DATA] ; ================================================================================================================================================================================================================================================================================================================================================================================================================== #define UART_BAUD_RATE 115200 void ConfigureUART (void){ /*启用 UART 使用的 GPIO 外设*/ ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA); /*启用 UART0 */ ROM_SysCtlPeripheralEnable (SYSCTL_Periph_UART0); /*为 UART 模式配置 GPI 引脚*/ ROM_GPIOPinConfigure (GPIO_PA0_U0RX); ROM_GPIOPinConfigure (GPIO_PA1_U0TX); ROM_GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1); /*使用内部16MHz 振荡器作为 UART 时钟源*/ UARTClockSourceSet (UART0_BASE、UART_CLOCK_PIOSC); ROM_UARTConfigSetExpClk (UART0_BASE、ROM_SysCtlClockGet ()、 UART_BAUD_RATE、(UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE)); /*初始化控制台 I/O 的 UART */ UARTStdioConfig (0、UART_BAUD_RATE、16000000); /*启用 UART 中断*/ ROM_IntMasterEnable(); ROM_UARTIntClear (UART0_BASE、ROM_UARTIntStatus (UART0_BASE、false)); ROM_UARTIntEnable (UART0_BASE、UART_INT_RX | UART_INT_RT); ROM_IntEnable (INT_UART0); } void SPIWrite (uint32_t Addr、uint32_t Val){ while (SSIDataGetNonBlocking (SSI2_base、&pui32DataRx[0])){} pui32DataTx[0]= Addr;pui32DataVal;pui32DataTx[1]、SSSi32DataRx[0]、sudr[SSuatt_base] (s=SSDaId=puattx、SIDt_puattx (SSuattx) pui32DataTx[1]); while (SSIBusy (SSI2_base)){} void SPIRead (uint32_t Addr){ while (SSIDataGetNonBlocking (SSI2_base、&pui32DataRx[0])){} SSIDataPut (SSI2_base、(SSI2_base)、[SSI2_daId] ;[SSI2_daDataRx0]; while (SSIBusy (SSI2_base)){} UARTprintf ("\n 接收到的数据:%i "、pui32DataRx[0]); } void main (void){ ROM_FULazyStackingEnable (); //将计时设置为直接从晶体运行。 SysCtlClockSet (SYSCTL_SYSDIV_8 | SYSCTL_USE_PLL | SYSCTAL_16MHz | SYSCTL_OSC_MAIN); ConfigureUART ();//函数用于初始化 UART 协议 外设使能(SYSCTL_Periph_SSI2); SysCtl_SysTHRIST_SSIPBLOCK (SSIPB_SSIP2);SysCtl_SSIPB_S (SSIPB_SSIPB_S) GPIOPinConfigure (GPIO_PB4_SSI2CLK); GPIOPinConfigure (GPIO_PB5_SSI2FSS); GPIOPinConfigure (GPIO_PB6_SSI2RX); GPIOPinConfigure (GPIO_PB7_SSI2TX); GPIOPinTypeSSI (GPIO_PORTB_BASE、 GPIO_PIN_7 | GPIO_PIN_6 | GPIO_PIN_4); SSIConfigSetExpClk (SSI2_base、SysCtlClockGet ()、SSI_FRF_MOTO_MODE_0、 SSI_MODE_MASTER、1000000、8); GPIOPinTypeGPIOOutput (GPIO_PORTB_BASE、GPIO_PIN_5); GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_5、GPIO_PIN_5); SSIEnable (SSI2_base); SSIConfigSetExpClk (SSI2_base、 SysCtlClockGet ()、SSI_FRF_MOTO_MODE_0、 SSI_MODE_MASTER、1000000、8); SSIEnable (SSI2_base); GPIOPinWrite (GPIO_PORTB_BASE、 GPIO_PIN_5、0); SPIWrite (0x60、0x34); //SPIWrite (0x60、0xF0); SPIRead (0xE0); GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_5、GPIO_PIN_5); SSIDisable (SSI2_base); UARTprintf ("\n 程序编码..."); }

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

    快速查找-您的函数"SPIWrite()& SPIRead()"都以"while "循环顶部的"SSIDataGetNonBlocking ()"开头。 通过 SSIPut()启动 SPI 并遵循该 w/SSIGet()是否更为常见? 我一段时间内没有使用过该供应商的 SPI API -但相信这将保证您的调查。

    您使用示波器显然会"快速、轻松和增强"您和所有其他人的诊断工作。 在整个屏幕上看到您的 SPI 时钟和"锁定数据"就没什么竞争了。 减去这种见解-"希望、祈祷"上升(接近)到您的最佳选择。

    您的 SPI 器件应放置在正确的电路板上-正确互连-并正确供电。    (真的)情况是这样吗?    高性能器件(我们认为这就是您的设计)-最常见的情况是-使用试验电路板"不友好"-我们希望您已投资于正式的评估板。

    虽然(有时)可以在不使用示波器的情况下"调试 SPI"-额外的时间、工作量证明是消耗性的(并且并不总是成功的)-也许您可以从一所当地学校或类似学校借用一个示波器。

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

    尊敬的 John:

     一些意见和建议。

     1、您写入 SPIRead (0xE0)。 在 SPIREAD ()内部、您可以使用0x80或0xE0、但仍为0xE0。 0xE0表示读取配置。 您是否打算读取数据寄存器。 如果是这种情况、您应该提供 SPIRead (0x70)。

     2、配置 ADC 后、立即尝试读取转换数据。 您的代码依次为 SPIWrite()和 SPIRead()。 数字转换结果存在可用的延迟。 信号增量 ADC 通常比 SAR 类型慢。 我从数据表中看到以下内容。

    转换器的延迟由以下公式指定:延迟=(5.5 x tDOUT)+(PHI x 1.3μs)+ 30μs μ s、其中 tDOUT 是由 XINCLOCK 和所选输出数据速率确定的数据输出周期(编程采样率的倒数)、 PHI 是针对相关通道(0≤PHI≤255)编程的采样瞬时延迟。 16ksps 时的延迟约为374μs μ s。

    3.如上所述、在 DRDYOUT 置为有效后、您是否不应该从读取的数据中注销以指示数据已准备好检索?

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

    您如何采用"以 MCU 为中心"的方法是否并不有趣-而我向您说明:"用户范围、用于 ADC 的评估板以及适当的电源和互连?"

    减去示波器-和用户报告/反馈-"沼泽"可能等待...
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    查看 Maxim 芯片的 SPI 通信格式、我认为当 CS 变为低电平时、您需要输出数据、然后在时钟的下降沿计时并在上升沿移位。

    此格式的 TI 说明为极性= 1、相位= 0;

    驱动程序软件将其称为 SSI_FRF_MOTO_MODE_2、而不是软件中的模式0。

    我看到的另一件事是,我认为您需要在 SPIREAD()函数中添加一个虚拟 SSIDataPut ()调用。 SPI 的每个事务都是写的和读的。 主器件上的 SSIDataPut ()函数为写操作和读操作生成 SPI 时钟。 SSIDataGet ()函数只需返回最后一个 SSIDataPut ()捕获的值。

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

    [引用 user="Bob Crosby">我认为您需要在 SPIRead()函数中添加虚拟 SSIDataPut ()调用。 [/报价]

    我也是这样想的-在我之前的帖子中列出了-他的 SPIWrite()也不是一个(类似的) SSIDataPut ()吗?    (出于相同的原因-您刚才已经介绍过。)

    我想你明天也会来路易斯维尔-也许不会...

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Bob、
    您正是虚拟写入来时钟输出转换数据的人。

    我还看到下面的描述、这是从 ADC 的角度来看的。 因此、我认为 Moto_Mode_0应该可以。

    DIN 数据中 SCLK 时钟的下降沿。 DOUT 上的数据在 SCLK 的上升沿发生变化、在 SCLK 的下降沿有效。

    如果按照 CB1的建议使用范围、一切都将变得显而易见。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Charles、CB1、

    我的海报太慢了、当我尝试构建我的答案检查我的格式时、你们都回答了。

    CB1、

    您完全正确。 一张具有示波器的图片可以解决如此多的 SPI 格式问题。 这就是我一直在做的事情。

    查尔斯

    我不确定格式0是否有效。 如果 Maxim 从站在其在下降沿计时数据之前在第一个时钟上升沿进行移位、则从站读取的数据和发送给主站的数据都将丢失 MSB 并被左移一。 (示波器图将解决此问题。)

    约旦

    为了更具体地了解读取所有零、您进行了如下调用:

    SPIWrite (0x60、0x34); 

    SSIDataGetNonBlocking ()->在接收 FIFO 中不应为任何内容,因此不执行任何操作

    SSIDataPut(), ->写入0x60,将 junk1 (可能为0)存储在接收 FIFO 中

    SSIDataPut(),->写入0x34,将 junk2 (可能为0)存储在接收 FIFO 中

    SPIRead (0xE0); 

    SSIDataGetNonBlocking()->返回 junk1 (可能为0,无论如何都忽略)

    SSIDataPut ();->写入0xE0、将 junk3 (概率7 0)存储在接收 FIFO 中

    SSIDataGet ()->返回 junk2 (可能是您看到的零)

    因此,您需要清空接收 FIFO,使用一些虚拟数据执行另一个 SSIDataPut(),以便将来自 Maxim 的应答移出,然后再执行另一个 SSIDataGet ()来读取移出的内容。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Bob、
    您完全正确。 再次查看 Maxim 数据表、SPICLK 开始为高电平表示时钟极性为1而不是0、这是我的错。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、大家好、我想我已经做了所有这些更改、现在我总是收到128、而不是0 (在极性改变后)。 我明天将可以使用示波器、但现在我只想修复代码中的任何明显错误。 使用 SPIRead 函数时、我不确定是否已正确执行此操作、但我将 AIN0+连接到输入电压、将 AIN0-接地、并将所有其他模拟输入(1-4)完全断开。 我有这么多虚拟数据的原因是、根据数据表、来自 AIN0的数据存储在数据寄存器的位80-95中。

    void SPIWrite (uint32_t Addr、uint32_t
    
    
    
    I2){while (SSIDataGetNonBlocking (SSI2_base、&pui32DataRx[0])}pui32DataTx[0]= Addr;pui32DataTx[1]=Val;SSDataaPut (SSIDTx_base)、pu32DataVal (SSiTx_bal)、puidtx (SSi2pu) pui32DataTx[1]);
    while (SSIBusy (SSI2_base)){}
    
    
    void SPIRead (uint32_t Addr){
    while (SSIDataGetNonBlocking (SSI2_base、&pui32DataRx[0])){}
    SSIDataPut (SSI2_base、(SSI2_base、0x80
    );sIDaPudr (SS0|aIdrx);
    SSIDataPut (SSI2_base、0);
    SSIDataPut (SSI2_base、0);
    SSIDataPut (SSI2_base、 0);
    SSIDataPut (SSI2_base、0);
    SSIDataPut (SSI2_base、0);
    SSIDataPut (SSI2_base、0);
    SSIDataPut (SSI2_base、0);
    SSIDataPut (SSI2_base、 0);
    SSIDataPut (SSI2_base、0);
    SSIDataGet (SSI2_base、&pui32DataRx[0]);
    SSIDataPut (SSI2_base、0);
    SSIDataGet (SSI2_base、&pui32DataRx[1]);
    while (SSIBusy (SSI2_base)){}
    UARTprintf ("\n 接收到的数据:%i "、pui32DataRx[0]);UARTusy (SSI2_BASE)(
    
    
    
    
    )}UARTprintf (直接从晶
    
    
    
    振接收到%/nvoid 数据:%32DataRx[f]();
    
    SysCtlClockSet (SYSCTL_SYSDIV_8 | SYSCTL_USE_PLL | SYSCTAL_16MHz | SYSCTL_OSC_MAIN);
    
    
    ConfigureUART ();//函数用于初始化 UART 协议
    
    外设使能(SYSCTL_Periph_SSI2);
    SysCtl_SysTHRIST_SSIPBLOCK (SSIPB_SSIP2);SysCtl_SSIPB_S (SSIPB_SSIPB_S)
    
    
    
    GPIOPinConfigure (GPIO_PB4_SSI2CLK);
    GPIOPinConfigure (GPIO_PB5_SSI2FSS);
    GPIOPinConfigure (GPIO_PB6_SSI2RX);
    GPIOPinConfigure (GPIO_PB7_SSI2TX);
    
    GPIOPinTypeSSI (GPIO_PORTB_BASE、 GPIO_PIN_7 | GPIO_PIN_6 | GPIO_PIN_4);
    
    SSIConfigSetExpClk (SSI2_base、SysCtlClockGet ()、SSI_FRF_MOTO_MODE_2、
    SSI_MODE_MASTER、1000000、8);
    
    GPIOPinTypeGPIOOutput (GPIO_PORTB_BASE、GPIO_PIN_5);
    GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_5、GPIO_PIN_5);
    
    SSIEnable (SSI2_base);
    
    GPIOPinWrite (GPIO_PORTB_BASE、 GPIO_PIN_5、0);
    
    SPIWrite (0x60、0x34);
    
    //SPIWrite (0x60、0xF0);
    
    SysCtlDelay (4000);
    
    SPIRead (0x70);
    
    GPIOPinWrite (GPIO_PORTB_BASE、GPIO_PIN_5、GPIO_PIN_5);
    
    SSIDisable (SSI2_base);
    UARTprintf ("\n 程序的编码...");
    
    } 

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

    [引用 USER="Jordon Rolley"]我将 AIN0+连接到输入电压,AIN0-连接到接地,所有其他模拟输入(1-4)完全断开连接。

    AIN0 (±)的存在(两者均存在)表明将向您的(外部) ADC 施加差分电压。   这通常会强制您满足两个要求: 1)这2个输入中的任何一个或两个都不能扩展到 ADC 的"全轨电压" (这是需要考虑的" AIN0 (-)接地")和2) ADC 的设置/配置代码可以指定不同的编码、以从"单端"切换到"差分"。   我相信、今天的帖子将为您首次提及"差分"模拟输入。

    您建议断开所有其他 ADC 输入(因此可能会"悬空")、这不是普遍接受的做法、即 ADC 输入。   应查看 ADC 规格表以了解正确的处理和端接-我怀疑"正确"的处理会看到每个 ADC 输入 -而不是保留为"浮动"-连接到安全的"中电平电压" (居中)(在 ADC 的输入电压规格中)。

    所有这些"dummy SPIPuts()"都增加了风险(同时"使用无意义的数据严重地覆盖范围上限"!)    其他 ADC 输入是否应该驻留在(更接近) ADC 数据寄存器位"0-15"-您是否会向(即位"0-15") ADC 引脚中引入(适当)电压而不是 AIN0变得更加简单(更安全)?    (由于 AIN0驻留在"数据寄存器位链高电平- AIN4是否不可能位于(更可取)位0-15寄存器空间附近?)    您(适当)的模拟输入电压与该"AINx"引脚(驻留位0-15)的简单"重新连接"消除了虚拟 SPIPuts ()的"冲击"-因此证明是值得的-不是吗?

    Silent 是指您使用正式评估板、定制板或(禁止使用)"试验板"、并确认您的 MCU 板和此外部器件之间具有足够的功率和互连。   在(任何)此类新的 "板对板"调试练习中、"一切"都"可疑!    (即怀疑"有罪/过失"直至(经证明)"无辜/适当")

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

    您好、Jordon、

     在 CB1基础上做一些简短的评论。  

     1.你确定 SysCtlDelay (4000)足以覆盖转换时间吗? 为什么不使用 DRDYDOUT 向 MCU 发送可读取的转换数据?

     2.配置 SSI 进行8位传输。 如果您需要从 Maxim 读取96位数据,是否需要创建12个虚拟 SSIDataPut()。 但是,在执行 SSIDataGet 之前,您有10个 SSIDataPut()。

     SSI FIFO 深度为8单元。 因此我认为您在执行 SSIDataGet 之前需要执行8个 SSIDataPut (),然后再继续执行4个 SSIDataPut (),然后再执行 SSIDataGet ()。 您也可以尝试6 SSIDataPut()->SSIDataGet ()->6 SSIDataPut()。 关键是确保接收 FIFO 不会溢出。

     4.是的,请使用范围来验证 Maxim 发出的内容。  

     您将与 CB1和 Bob 保持良好的合作关系。 我有一架飞机在一个小时内就能赶上。  

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

    您好、Charles、

    海报只有在他"挑选赢家"并"大赌注"时才会"好手"。 这个地方现在已经割让给了 Bob -(薄荷花和柔和的太阳礼服-(两种都是-(理想情况下都是))不可能抗拒)。