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/EK-TM4C1294XL:具有 TM4C1294XL 的 MAX31855PMB1 SPI

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/859633/ccs-ek-tm4c1294xl-max31855pmb1-spi-with-tm4c1294xl

器件型号:EK-TM4C1294XL

工具/软件:Code Composer Studio

您好!

从 MAX31855MPB1 (热电偶)读取温度时出现问题。 我正在使用 SPI 通信、并尝试使用 SSI0端口从 MAX31855进行读取。
但是、它不会从 MAX31855读取任何值。 我使用调试来查看我是否从 SPI 获取任何数据、但它停留在

SSIDataGet (SSI0_BASE、&pui32DataRx[ui32Index]);//代码在此处停止,不会转到任何位置

有人能帮我解决这个问题吗? 我需要在代码中更改什么才能使其读取。 因为这是热电偶。 我只想从传感器读取值。 此操作无需 Tx。

//
//
// spi_slave.c -演示如何在 SPI 从
设备//中配置 SSI0的示例 模式。
//
//版权所有(c) 2010-2017 Texas Instruments Incorporated。 保留所有权利。
//软件许可协议
//
以源代码和二进制形式重新分发和使用,无论是否
进行//修改,只要
满足以下条件//:
//
重新分发源代码必须保留上述版权
//声明、此条件列表和以下免责声明。
//
//二进制形式的再发行必须复制上述版权
//声明、此条件列表和//

分发随附的//文档和/或其他材料中的以下免责声明。
////
未经

事先书面许可,不能使用德州仪器公司的名称或//其贡献者的名称来认可或推广源自此软件的产品//。
////
本软件由版权所有者和贡献者提供
//“按原样”,不

承认任何明示或暗示的保证,包括但不限于//适销性和对//特定用途适用性的暗示保证。 在任何情况下、版权
//所有者或贡献者都不对任何直接、间接、偶然、
//特殊、模范、 或相应的损害(包括但不
限于采购替代产品或服务;丧失使用、
//数据或利润; 或业务中断)、无论

出于何种原因使用
本软件(即使被告知可能会造成此类损坏)、还是出于任何原因而产生的任何//责任理论(无论是合同、严格责任还是侵权行为)//(包括疏忽或其他)。
//
//这是 Tiva 固件开发包的修订版2.1.4.178的一部分。
////
*****************

#include 
#include 

#include 

#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/ssi.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"

#define target_is_TM4C129_RAudio"
#include "mdio/uart.h"#include "#define ROM"





//
//! \addtogroup SSI_examples_list
//! 

SPI 从器件(SPI_SLAVE)

//! //! 此示例展示了如何将 SSI0配置为 SPI 从器件。 代码将 //! 在从器件 Tx 上发送三个字符、然后轮询接收 FIFO、直到 //! 从机 Rx 上接收到3个字符。 //! //! 此示例使用以下外设和 I/O 信号。 您必须 //! 查看这些内容并根据您自己的董事会需要进行更改: //! - SSI0外设 //! - GPIO 端口 A 外设(用于 SSI0引脚) //! SSI0Clk - PA2 //! - SSI0Fss - PA3 //! - SSI0Rx - PA4 //! - SSI0Tx - PA5 //! //! 以下 UART 信号仅配置为显示控制台 //! 消息。 SSI0的运行不需要这些。 //! - UART0外设 //! - GPIO 端口 A 外设(用于 UART0引脚) //! - UART0RX - PA0 //! - UART0TX - PA1 //! //! 此示例使用以下中断处理程序。 要使用此示例 //! 在您自己的应用程序中、您必须将这些中断处理程序添加到 您的//! 矢量表。 //! -无。 //// ***************** // // //要发送和接收的字节数。 //// ***************** #define NUM_SSI_DATA 3 uint32_t ui32SysClock; char str[20]; /* reverse:reverse string s in place */ void reverse (char s[]) { int i、j; 字符 c; 对于(i = 0、j = strlen (s)-1;i '0';="" get="" next="" digit="" while="" ((n="" =="" 10)="">0); /*删除它*/ 如果(符号< 0) S[i++]='-'; S[i]='\0'; 倒车档; } //********* // //此函数将 UART0设置为用于控制台,以便 在示例运行时显示信息//。 //// ***************** void InitConsole (void) { // //启用用于 UART0引脚的 GPIO 端口 A。 // TODO:将其更改为您正在使用的 GPIO 端口。 // SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA); // //为端口 A0和 A1上的 UART0功能配置引脚复用。 //如果您的器件不支持引脚复用、则无需执行此步骤。 // TODO:更改此选项以选择您正在使用的端口/引脚。 // GPIOPinConfigure (GPIO_PA0_U0RX); GPIOPinConfigure (GPIO_PA1_U0TX); // //启用 UART0以便我们可以配置时钟。 // SysCtlPeripheralEnable (SYSCTL_Periph_UART0); // //使用内部16MHz 振荡器作为 UART 时钟源。 // UARTClockSourceSet (UART0_BASE、UART_CLOCK_PIOSC); // //为这些引脚选择替代(UART)功能。 // TODO:更改此选项以选择您正在使用的端口/引脚。 // GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1); // //初始化控制台 I/O 的 UART // UARTStdioConfig (0、115200、16000000); } //********* // //配置从飞思卡尔(SPI)模式中的 SSI0。 此示例将发出 // 3个字节的数据,然后等待3个字节的数据进入。 这将全部由 //使用轮询方法完成。 //// ***************** void SSI_init (void) { uint32_t 初始数据; // //必须启用 SSI0外设才能使用。 // SysCtlPeripheralEnable (SYSCTL_Periph_SSI0); SSIDisable (SSI0_BASE);//禁用 SPI // //对于本示例,SSI0与 Porta[5:2]一起使用。 实际端口和引脚 //您的器件上使用的可能不同、请参阅数据表以了解更多信息 //信息。 GPIO 端口 A 需要启用、以便可以使用这些引脚。 // TODO:将其更改为您正在使用的 GPIO 端口。 // //SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);//已为 UART0启用 // //为端口 A2、A3、A4和 A5上的 SSI0功能配置引脚复用。 //如果您的器件不支持引脚复用、则无需执行此步骤。 // TODO:更改此选项以选择您正在使用的端口/引脚。 // GPIOPinConfigure (GPIO_PA2_SSI0CLK);// SCK GPIOPinConfigure (GPIO_PA3_SSI0FSS);// SS //GPIOPinConfigure (GPIO_PA4_SSI0XDAT0);// MOSI -取消使用 Tx - GPIO_PA4_SSI0XDAT0 GPIOPinConfigure (GPIO_PA5_SSI0XDAT1);// MISO Rx - GPIO_PA5_SSI0XDAT1 // //配置 SSI 引脚的 GPIO 设置。 该函数也会提供 将这些引脚的//控制到 SSI 硬件。 请参阅中的数据表 //查看每个引脚分配的函数。 //引脚分配如下: // PA5 - SSI0Tx // PA4 - SSI0Rx // PA3 - SSI0Fss // PA2 - SSI0CLK // TODO:更改此选项以选择您正在使用的端口/引脚。 // // GPIOPinTypeSSI (GPIO_Porta_base、GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2); GPIOPinTypeSSI (GPIO_Porta_base、GPIO_PIN_5 | GPIO_PIN_3 | GPIO_PIN_2); // //为 SPI 从模式配置和启用 SSI 端口。 使用 SSI0、 //系统时钟电源,空闲时钟低电平和低电平有效时钟输入 //飞思卡尔 SPI 模式、从模式、1MHz SSI 频率和8位数据。 //对于 SPI 模式,可以设置 SSI 时钟的极性 //单元空闲。 您还可以配置所需的时钟边沿 //在上捕获数据。 有关的更多信息、请参阅数据表 //不同的 SPI 模式。 // //为 TI 主控模式配置和启用 SSI 端口。 使用 SSI0系统 //时钟电源、主控模式、1MHz SSI 频率和8位数据。 SSIConfigSetExpClk (SSI0_BASE、ui32SysClock、SSI_FRF_MOTO_MOTO_0、SSI_MODE_MASTER、10000、 16);//SSI_MODE_SLAVE // //启用 SSI0模块。 // SSIEnable (SSI0_BASE); //清除 RX FIFO 中可能存在的任何初始数据 while (SSIDataGetNonBlocking (SSI0_BASE、初始数据)); } int main (void) { // uint32_t data; uint32_t pui32DataRx[NUM_SSI_DATA]; uint32_t ui32Index; // //将时钟设置为直接从外部晶振/振荡器运行。 // TODO:必须更改 SYSCTL_XTAL_VALUE 以匹配的值 板上的//晶体。 // ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、120000000); // //设置用于显示消息的串行控制台。 这是 //仅用于此示例程序,SSI 操作不需要。 // InitConsole(); SSI_init(); for (ui32Index = 0;ui32Index < NUM_SSI_DATA;ui32Index++) { pui32DataRx[ui32Index]= 0; // //使用“阻塞”GET 函数接收数据。 此函数 //将等待接收 FIFO 中有数据后再返回。 // SSIDataGet (SSI0_BASE、&pui32DataRx[ui32Index]); // //由于我们使用的是8位数据,所以屏蔽 MSB。 // pui32DataRx[ui32Index]&= 0x00DF; // //显示 SSI0接收到的数据。 // itoa(pui32DataRx[ui32Index],str); UARTprintf (str); } }

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

    Chuong、您好!

    您能否将示波器连接到 SPI 线路并查看是否正在生成 SPI 时钟? 我不得不说、我从未见过这样的用例、因此如果在未配置 MOSI 的情况下生成 SPI 时钟、我不是肯定的。 从理论上讲、它应该提供您正在做的事情、但我想确保这一点。

    当我回到办公室时、我还会尝试自己运行代码、但同时、如果您可以查看代码、这将让您对这里可能发生的情况有所了解。

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

    Chuong、您好!

    好的、所以您需要使用 SSIDataPut 来触发时钟。

    此外、由于您需要32个时钟而不会发生 SS 中断、因此您需要使用高级模式。

    在 SSIEnable 之前、将其添加到 SSI 配置中:

    SSIAdvFrameHoldEnable (SSI0_BASE);
    SSIAdvModeSet (SSI0_BASE、SSI_ADV_MODE_WRITE); 

    然后使用此代码生成32个时钟、以便数据进入:

    SSIDataPut (SSI0_BASE、0x00);
    SSIDataPut (SSI0_BASE、0x00);
    SSIDataPut (SSI0_BASE、 0x00);
    SSIAdvDataPutFrameEnd (SSI0_BASE、0x00); 

    然后、您应该能够使用 SSIDataGet 读取4个字节。

    无需为此配置 MOSI、该函数不需要通过 MOSI 输出数据、它将触发从器件查找的时钟。

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

    您好、Ralph、

    非常感谢您的回复。 我按照您的建议更改了代码、但不幸运。

    我不确定哪里出错了。 MAX31855的数据以有符号14位 SPI 兼容的形式输出。 我不确定如何将其设为带符号值。  

    我对 Tiva C 非常陌生

    -Chuong Vu

    void SSI_init (void)
    {
    uint32_t 初始数据;
    //
    //必须启用 SSI0外设才能使用。
    //
    SysCtlPeripheralEnable (SYSCTL_Periph_SSI0);
    
    SSIDisable (SSI0_BASE);//禁用 SPI
    
    GPIOPinConfigure (GPIO_PA2_SSI0CLK);// SCK
    GPIOPinConfigure (GPIO_PA3_SSI0FSS);// SS
    //GPIOPinConfigure (GPIO_PA4_SSI0XDAT0);// MOSI -取消使用 Tx - GPIO_PA4_SSI0XDAT0
    GPIOPinConfigure (GPIO_PA5_SSI0XDAT1);// MISO Rx - GPIO_PA5_SSI0XDAT1
    
    
    // PA5 - SSI0Tx
    // PA4 - SSI0Rx
    // PA3 - SSI0Fss
    // PA2 - SSI0CLK
    // TODO:更改此选项以选择您正在使用的端口/引脚。
    //
    
    //GPIOPinTypeSSI (GPIO_Porta_base、GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2);
    GPIOPinTypeSSI (GPIO_Porta_base、GPIO_PIN_5 | GPIO_PIN_3 | GPIO_PIN_2);
    
    //为 TI 主控模式配置和启用 SSI 端口。 使用 SSI0系统
    SSIConfigSetExpClk (SSI0_BASE、ui32SysClock、SSI_FRF_MOTO_MOTO_0、SSI_MODE_MASTER、10000、 16);//SSI_MODE_SLAVE
    
    
    SSIAdvFrameHoldEnable (SSI0_BASE);
    SSIAdvModeSet (SSI0_BASE、SSI_ADV_MODE_WRITE);
    
    //
    //启用 SSI0模块。
    //
    SSIEnable (SSI0_BASE);
    
    //清除 RX FIFO 中可能存在的任何初始数据
    while (SSIDataGetNonBlocking (SSI0_BASE、&initialData));
    
    }
    
    int
    main (void)
    {
    uint32_t pui32DataRx[NUM_SSI_DATA];
    uint32_t ui32Index;
    
    ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、120000000);
    
    InitConsole();//设置 UART
    SSI_init ();//设置 SSI0
    
    while (1)
    {
    SSIDataPut (SSI0_BASE、0x00);
    SSIDataPut (SSI0_BASE、0x00);
    SSIDataPut (SSI0_BASE、0x00);
    SSIAdvDataPutFrameEnd (SSI0_BASE、0x00);
    
    for (ui32Index = 0;ui32Index < NUM_SSI_DATA;ui32Index++)
    {
    
    SSIDataGet (SSI0_BASE、&pui32DataRx[ui32Index]);
    
    pui32DataRx[ui32Index]&= 0x00FF;
    
    //
    //显示 SSI0接收到的数据。
    //
    itoa(pui32DataRx[ui32Index],str);
    UARTprintf (str);
    }
    UARTprintf ("\r\n");
    }
    
    }
    
    

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

    您好 Ralph、

    这里的年轻员工想要、"在这张海报上拍摄照片"-但您的到来表明海报掌握在手中。

    从我们的许多大学(甚至是天赋高中)员工和实习生那里、我们早就注意到、"SPI"要求"放置"而不是"直接"获取"、这证明很多人很麻烦。   我让他们查看 API 的 SPI 源代码-也许这提供了"不太直观、缺少链接"。

    //
    无效
    SSIDataPut (uint32_t ui32Base、uint32_t ui32Data)

    //
    //检查参数。
    //
    assert (_SSIBaseValid (ui32Base));
    Assert (((ui32Data &(0xfffffffe <<)(HWREG (ui32Base + SSI_O_CR0)&
    SSI_CR0_DSS_M))= 0);

    //
    //等待,直至有空格。
    //
    while (!(HWREG (ui32Base + SSI_O_SR)& SSI_SR_TNF))

    //
    //将数据写入 SSI。
    //
    HWREG (ui32Base + SSI_O_DR)= ui32Data;  //这很明显是一个输出函数。   生成 SPI 时钟。

    此函数的前导码注释:"此函数将提供的数据放入 指定 SSI 模块的发送 FIFO 中。"

    对比之下:   

    //
    无效
    SSIDataGet ()(uint32_t ui32Base、uint32_t * pui32Data)

    //
    //检查参数。
    //
    assert (_SSIBaseValid (ui32Base));

    //
    //等待直至有数据要读取。
    //
    while (!(HWREG (ui32Base + SSI_O_SR)& SSI_SR_RNE))

    //
    //从 SSI 读取数据。
    //
    * pui32Data = HWREG (ui32Base + SSI_O_DR);  //这是一个'fetch & read'函数。   不生成 SPI 时钟。

    此函数的前导码注释:"此函数从指定 SSI 模块的接收 FIFO 获取接收数据、并将该数据放置在 pui32Data 参数指定的位置。"

    员工相信(此处的其他人)将受益于此分析...

    ***关于您对本海报的具体指导-由于我们没有也没有使用'129 MCU 系列-我们是否可以避免使用'SSIAdvDataPutFrameEnd()' (我们怀疑它在'123 MCU 中不可用)-而是手动生成帧选择信号?   (以便我们可以在需要时传输"超过16个 SPI 位"。)   非常感谢您的时间和关注...

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

    Chuong、您好!

    您是否查看了 SPI 线路以查看时钟是否立即触发?

    关于有符号值、您需要将接收到的位分隔成不同的变量、并从这些变量中处理。 在解决这一问题之前、我们需要从器件获取数据。

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

    您好 CB1、

    [引用 USER="CB1_MOBITION]]***关于您对本海报的具体指导-我们没有也没有使用'129 MCU 系列-我们是否可以避免使用'SSIAdvDataPutFrameEnd()' (我们怀疑它在'123 MCU 中不可用)-而是手动生成帧选择信号?   (以便我们可以在需要时传输"超过16个 SPI 位"。)   非常感谢您的关注和时间...[/引述]

    对 CS 进行手动控制的挑战是时钟仍然不会连续-在前16个时钟之后、下一组时钟之前会有一小段距离。 我不确定您是否可以在 TM4C123x 上连续执行16个以上的时钟、而不采用(可能是可怕的)"手动"位拆裂方法-我不想排除它、因为我没有深入研究过、 但是从我所知、我不能想到使用 SSI 外设的权变措施。

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

    谢谢你,拉尔夫,一如既往,非常感谢。

    [报价用户="Ralph Jacobi"]头16个时钟之后,下一组时钟之前会有一个小的间隔

    您(或其他供应商代理)是否知道和/或已"制表"此类"缩小差距?"   (理想情况下适用于'123级)

    您能不能知道 、"SSIAdvDataPutFrameEnd ()"是否与'123系列一起使用是'legal'?   (理想情况下是 LPAD (非常基本的)器件)

    我们建议使用多个 SPI 从器件采用这种方法-到目前为止(很少、即从不)使用从器件、"提及和/或定义"、"任何此类"缺陷/延迟"的后果。   现在列出了"感应超时"、但可以肯定的是、"我们的小差距永远不会达到这个维度!"   (员工注意到、"卡斯特将军(同样)-仅报告了一个"印第安人小组"!)

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

    您好、Ralph、

    我看不到来自 CLK 和 MISO 的任何信号。 现在、我只是尝试从 MISO 获取任何数据。  SSIDataGet 确实没有发出和 SPI 时钟、因此没有发回数据。

    我想使用 PWM 为 MAX31855PMB1温度传感器上的串行时钟输入馈电。 但我仍然不确定这会有所帮助。

    谢谢、

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

    Chuong、您好!

    啊、我意识到、现在我还更改了 SPI 时钟的配置、请使用以下 API:

    SSIConfigSetExpClk (SSI0_BASE、ui32SysClock、SSI_FRF_MOTO_MOTO_0、SSI_MODE_MASTER、100000、 8);//SSI_MODE_SLAVE 

    请注意、我还将速度提高到了100kHz、但您也可以使用10kHz。

    如果您看不到时钟的变化、请检查您的示波器连接、因为这是我对您发布的代码所做的唯一更改、它会在 EK-TM4C1294XL LaunchPad 上按预期输出所有内容。

    即使是这样、您仍然应该看到时钟、但它并不是很正确、因此 MISO 数据不返回并不令人惊讶。

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

    您好 CB1、

    我以前没有绘制过图表、但它并不重要。 我*想*说,1-2个 SPI 时钟周期,但是... 这是一个指标、它在 SPI 时钟速度方面有很大的变化。

    [引用 USER="CB1_MOBIST]和-您是否知道与 '123系列一起使用的"SSIAdvDataPutFrameEnd ()"是否为'legal'?   (理想情况下是 LPAD (非常基本的)器件)[/QUERP]

    不是、SSI 的高级模式只是 TM4C129x 功能。

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

    好的、再次感谢 Ralph、在 Tnxgvng 假期后、我们将运行测试和报告。

    我从未遇到过您的"高级模式"-现在-了解原因。   (因此、对于123个用户、我们的"重复16位 SPI 传输"的重要性、每个传输都手动置位 FSS。)

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

    您好、Ralph、

    我将数据位从16位更改为8位、代码仅在 SSIDataGet 处停止。  

    这是我的线配置。  

    LaunchPad ---------- MAX31855MPB1

    PA2 ------------ 引脚1   (SS)

    PA3 ------------ 引脚4   (SCK)

    PA5 ---------------- 引脚3   (MISO)

    3.3V --- 引脚6    (VCC)

    接地--- 引脚5   (GND)

    #include 
    #include 
    
    #include 
    
    #include "inc/hw_memmap.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/ssi.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "driverlib/rom.h"
    
    #define SSI/uarts.h
    
    
    3
    
    uint32_t ui32SysClock;
    char str[8];
    
    
    /* reverse:反向串 s 就地*/
    void reverse (char s[])
    {
    int i、j;
    字符 c;
    
    对于(i = 0、j = strlen (s)-1;i '0';="" get="" next="" digit="" while="" ((n="" =="" 10)="">0); /*删除它*/
    如果(符号< 0)
    S[i++]='-';
    S[i]='\0';
    Reverse;
    }
    
    
    void
    InitConsole (void)
    {
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
    
    GPIOPinConfigure (GPIO_PA0_U0RX);
    GPIOPinConfigure (GPIO_PA1_U0TX);
    
    SysCtlPeripheralEnable (SYSCTL_Periph_UART0);
    
    UARTClockSourceSet (UART0_BASE、UART_CLOCK_PIOSC);
    
    GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);
    
    UARTStdioConfig (0、115200、16000000);
    }
    
    void SSI_init (void)
    {
    uint32_t 初始数据;
    //
    //必须启用 SSI0外设才能使用。
    //
    SysCtlPeripheralEnable (SYSCTL_Periph_SSI0);
    
    SSIDisable (SSI0_BASE);//禁用 SPI
    
    GPIOPinConfigure (GPIO_PA2_SSI0CLK);// SCK
    GPIOPinConfigure (GPIO_PA3_SSI0FSS);// SS
    //GPIOPinConfigure (GPIO_PA4_SSI0XDAT0);// MOSI -取消使用 Tx - GPIO_PA4_SSI0XDAT0
    GPIOPinConfigure (GPIO_PA5_SSI0XDAT1);// MISO Rx - GPIO_PA5_SSI0XDAT1
    
    //GPIOPinTypeSSI (GPIO_Porta_base、GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2);
    GPIOPinTypeSSI (GPIO_Porta_base、GPIO_PIN_5 | GPIO_PIN_3 | GPIO_PIN_2);
    
    //为 TI 主控模式配置和启用 SSI 端口。 使用 SSI0系统
    SSIConfigSetExpClk (SSI0_BASE、ui32SysClock、SSI_FRF_MOTO_MOTO_0、SSI_MODE_MASTER、100000、 8);//SSI_MODE_SLAVE
    
    
    SSIAdvFrameHoldEnable (SSI0_BASE);
    SSIAdvModeSet (SSI0_BASE、SSI_ADV_MODE_WRITE);
    
    //
    //启用 SSI0模块。
    //
    SSIEnable (SSI0_BASE);
    
    //清除 RX FIFO 中可能存在的任何初始数据
    while (SSIDataGetNonBlocking (SSI0_BASE、&initialData));
    
    }
    
    int
    main (void)
    {
    uint32_t pui32DataRx[NUM_SSI_DATA];
    uint32_t ui32Index;
    
    ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、120000000);
    
    InitConsole();//设置 UART
    SSI_init ();//设置 SSI0
    
    while (1)
    {
    SSIDataPut (SSI0_BASE、0x00);
    SSIDataPut (SSI0_BASE、0x00);
    SSIDataPut (SSI0_BASE、0x00);
    SSIAdvDataPutFrameEnd (SSI0_BASE、0x00);
    
    for (ui32Index = 0;ui32Index < NUM_SSI_DATA;ui32Index++)
    {
    
    SSIDataGet (SSI0_BASE、&pui32DataRx[ui32Index]);
    
    pui32DataRx[ui32Index]&= 0x00FF;
    
    //
    //显示 SSI0接收到的数据。
    //
    itoa(pui32DataRx[ui32Index],str);
    UARTprintf (str);
    }
    UARTprintf ("-done");
    }
    
    }
    

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

    Chuong、您好!

    如果从机不发送回数据、那么停止代码就不会令人惊讶。 您需要对 SPI 线路进行范围控制。 如果时钟生成正确、则从器件、时钟极性等可能存在问题 从 TM4C 的角度来看,在这方面,我只能进行大量的指导。 但现在还不清楚时钟是否正确生成、因此请确认您能够观察到我在结尾处看到的内容

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

    您好、Ralph、

    我已检查并且 PA3 (SCK)不生成任何时钟。 CB1_MOBILE 看起来是正确的、只有 SSIDataPut 生成时钟、SSIDataget 不会创建任何 SPI 时钟。

    我正在尝试找到更多有关 SPI 读取的示例、但很难找到。

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

    我的'355PMB1'朋友、

    供应商的 Ralph 确实正确地建议使用"SSIDataPut ()"-在"   创建编号 "SSIDataGet ()"之前。

    他在11月25日18:43 CST 的帖子:

    [引用用户="Ralph Jacobi"]

    然后使用此代码生成32个时钟、以便数据进入:

    SSIDataPut (SSI0_BASE、0x00);
    SSIDataPut (SSI0_BASE、0x00);
    SSIDataPut (SSI0_BASE、0x00);
    SSIAdvDataPutFrameEnd (SSI0_BASE、0x00);

    然后、您应该能够使用  SSIDataGet 读取4个字节。   [/报价]

    正如我的员工在评论中所写的那样、功能"SSIDataGet"只会恢复 SSI FIFO 中"已经存在"的 SSI 数据!    因此、 "SSIDataGet ()"不需要或生产"到外部世界的时钟"。   SPI 是一种与 SPI 时钟协同工作的"全双工"协议、包括发送和接收。   (可能在不同的时钟边沿上...)

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

    非常感谢您的 INfor。

     因此我遇到 了 SSIConfigSetExpClk 的问题。

    当 SSIAdv 启用时、如果我将数据与<=8一起使用、则 SSIDataget 不会运行

    SSIConfigSetExpClk (SSI0_BASE、ui32SysClock、SSI_FRF_MOTO_MOTO_0、SSI_MODE_MASTER、1000000、 8);这将导致 SSIDataget 函数挂起。

    但是、如果数据宽度大于8、则该程序将运行。 MAX31855MPB1具有14位输出。 但我仍然无法从 FIFO 中获取任何内容(FIFO 为空)。

    我读出 SSIAdvModeSet 说明中说过"当使用高级操作模式时、SSI 模块必须配置为八个数据位、并且必须配置 SSI_FRF_MOTO_MODE_0协议。"

    我没有示波器、我使用万用表测量端口 PA2的 Laundpad 的 SCK、并且看不到任何信号发出。

    我仍然不确定我做了什么错误。

    void SSI_init (void)
    {
    uint32_t 初始数据;
    //
    //必须启用 SSI0外设才能使用。
    //
    SysCtlPeripheralEnable (SYSCTL_Periph_SSI0); 
    //SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);//已在 UART 中启用 SSIDisable (SSI0_BASE);//禁用 SPI GPIOPinConfigure (GPIO_PA2_SSI0CLK);// SCK GPIOPinConfigure (GPIO_PA3_SSI0FSS);// SS GPIOPinConfigure (GPIO_PA5_SSI0XDAT1);// MISO Rx - GPIO_PA5_SSI0XDAT1 GPIOPinConfigure (GPIO_PA4_SSI0XDAT0);// MOSI -取消使用 Tx - GPIO_PA4_SSI0XDAT0 GPIOPinTypeSSI (GPIO_Porta_base、GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2); //GPIOPinTypeSSI (GPIO_Porta_base、GPIO_PIN_5 | GPIO_PIN_3 | GPIO_PIN_2); //为 TI 主控模式配置和启用 SSI 端口。 使用 SSI0系统 SSIConfigSetExpClk (SSI0_BASE、ui32SysClock、SSI_FRF_MOTO_MOTO_0、SSI_MODE_MASTER、1000000、 14); SSIAdvFrameHoldEnable (SSI0_BASE); SSIAdvModeSet (SSI0_BASE、SSI_ADV_MODE_WRITE); // //启用 SSI0模块。 // SSIEnable (SSI0_BASE); //清除 RX FIFO 中可能存在的任何初始数据 while (SSIDataGetNonBlocking (SSI0_BASE、&initialData)); } int main (void) { uint32_t 数据; ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、120000000); InitConsole();//设置 UART SSI_init ();//设置 SSI0 while (1) { SSIDataPut (SSI0_BASE、0x00); SSIDataPut (SSI0_BASE、0x00); SSIDataPut (SSI0_BASE、0x00); SSIAdvDataPutFrameEnd (SSI0_BASE、0x00); // while (SSIBusy (SSI0_BASE){} SSIDataGet (SSI0_BASE、&data); itoa(数据、str); UARTprintf (str); UARTprintf ("\r\n"); } }

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

    我的朋友、

    [引用用户="Chuong Vu "]

    但是、如果数据宽度大于8、则该程序将运行。 MAX31855MPB1具有14位输出。 但我仍然无法从 FIFO 中获取任何内容(FIFO 为空)。

    我读出 SSIAdvModeSet 说明中说过"当使用高级操作模式时、SSI 模块必须配置为八个数据位、并且必须配置 SSI_FRF_MOTO_MODE_0协议。"   [/报价]

    这些句子有点冲突-您不同意吗?    这些类型的"CU 问题"最好由熟练的(有过特定设备经验的)供应商代理来处理。

    不过、我可以这样评论:"您是否"确定"在 ADC 的第一个(和早期)"计时"期间显示所需数据(即正在发送)?   您似乎生成了'32 SPI 时钟'(通过4个'SPI 放置'级联)并且如果 ADC 显示其数据、"在时钟序列中的稍后部分"-(可能)解释您为什么注意到 SPI 的 FIFO 为空。"   (即您的数据已存在-但可能需要18个时钟才能(最终)开始显示。   我在这里伸展-但我们的水手因在强烈风暴中寻找"任何港口"而闻名。)

    我可以建议使用改进的数据监控器。   使用高效的 LED (尤其是红色 LED)和适当的限流电阻器-确保响应速度快于 DMM!   (我们以前的实验指出 红色 LED 响应最窄的脉冲- iirc 检测窄至~500µS μ s 的脉冲。   确保调暗实验室和室内照明灯。)   您还可以"通过改进诊断、在开发过程中大幅降低 SPI 时钟的速度"。   (从而扩大 SPI 脉冲-进一步使 LED 能够捕捉(偶数)单独的 SPI 数据字节。)

    还有另一种方法-"将感兴趣的 SPI 引脚捕获到、"其他 MCU GPIO 引脚配置为输入(启用引脚的中断)。"   通过"计算单个 SPI 事务期间发生的 GPIO 引脚中断数量"、您可以深入了解(甚至)信号、这些信号过于简短、以至于您的 LED 无法看到!

    员工注意到,您(以后)在 SSIDataGet ()之后才使用“itoa (data,str)”。   我们希望在(任何)进一步处理之前、先看到您"只读并存储" FIFO 数据-以确认其存在和正确性。   ("早期和过度"处理证明存在"亲吻"违规行为! (笑声) 即可能"污染"您的其他(良好) FIFO 数据!")  

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

    Chuong、您好!

    [引用用户="Chuong Vu "]

    当 SSIAdv 启用时、如果我将数据与<=8一起使用、则 SSIDataget 不会运行

    SSIConfigSetExpClk (SSI0_BASE、ui32SysClock、SSI_FRF_MOTO_MOTO_0、SSI_MODE_MASTER、1000000、 8);这将导致 SSIDataget 函数挂起。

    [/报价]

    是的、对于高级模式、我看到它需要8位、 但是、对于这个应用、8位是可以的、你只需要4个周期即可在一个事务中获得完整的32位-这就是我已经在我的末尾测试过的输出。

    [引用用户="Chuong Vu ]但是,如果数据宽度大于8,则程序将运行。 MAX31855MPB1具有14位输出。 但我仍然无法从 FIFO 中获取任何内容(FIFO 为空)。[/引述]

    该代码设置为读取全部32位数据、这是 MAX 数据表中的数值。

    [引用用户="Chuong Vu "]我没有示波器,我使用万用表来测量端口 PA2的 Laundpad 的 SCK,我看不到任何信号发出。[/quot]

    使用万用表时、您不会看到 SCLK 信号。 它的速度太快、以至于 DMM 无法注册。 您需要使用范围。

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

    [引用用户="Ralph Jacobi">万用表... 它的速度太快、以至于 DMM 无法注册。 您需要使用范围。[/quot]

    或者-很可能(如前所述)"红色" LED。   (至少-这用于确认信号是否存在。)   此外、SPI 交易速度可以(通常也会受益于)"放慢速度"-提高 LED "确定"简短脉冲序列的能力-在没有范围的情况下尤其有用...

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

    您好、Ralph、

    非常感谢您的回答。

    到目前为止、这是对我有效的代码。 它以14位读数运行。

    您能给我一个读取 SSI 中8位的示例吗? "4个周期、在一个事务中获得完整的32位"。 我找不到这方面的任何示例代码。

    这是对我有效的代码。 如果我想读取8位、我必须禁用广播模式。 但它仅为我提供值0。

    void SSI_init (void)
    {
    uint32_t 初始数据;
    //
    //必须启用 SSI0外设才能使用。
    //
    SysCtlPeripheralEnable (SYSCTL_Periph_SSI0);
    
    //SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);//已在 UART 中启用
    
    SSIDisable (SSI0_BASE);//禁用 SPI
    
    GPIOPinConfigure (GPIO_PA2_SSI0CLK);// SCK
    GPIOPinConfigure (GPIO_PA3_SSI0FSS);// SS
    GPIOPinConfigure (GPIO_PA5_SSI0XDAT1);// MISO Rx - GPIO_PA5_SSI0XDAT1
    GPIOPinConfigure (GPIO_PA4_SSI0XDAT0);// MOSI -取消使用 Tx - GPIO_PA4_SSI0XDAT0
    
    GPIOPinTypeSSI (GPIO_Porta_base、GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2);
    
    //为 TI 主控模式配置和启用 SSI 端口。 使用 SSI0系统
    SSIConfigSetExpClk (SSI0_BASE、ui32SysClock、SSI_FRF_MOTO_MOTO_0、SSI_MODE_MASTER、4000000、 14);
    
    
    //SSIAdvFrameHoldEnable (SSI0_BASE);
    //SSIAdvModeSet (SSI0_BASE、SSI_ADV_MODE_WRITE);
    
    //
    //启用 SSI0模块。
    //
    SSIEnable (SSI0_BASE);
    
    //清除 RX FIFO 中可能存在的任何初始数据
    while (SSIDataGetNonBlocking (SSI0_BASE、&initialData));
    
    }
    
    int
    main (void)
    {
    
    uint32_t 数据;
    
    ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、120000000);
    
    InitConsole();//设置 UART
    SSI_init ();//设置 SSI0
    
    while (1)
    {
    
    SSIDataPut (SSI0_BASE、0x0000);
    //SSIDataPut (SSI0_BASE、0x00);
    //SSIDataPut (SSI0_BASE、0x00);
    //SSIAdvDataPutFrameEnd (SSI0_BASE、0x00);
    
    while (SSIBusy (SSI0_BASE)){}
    
    SSIDataGet (SSI0_BASE、&data);
    
    // LSB = 0.25°C
    数据*= 0.25;
    
    itoa(数据、str);
    UARTprintf ("摄氏度:");
    UARTprintf (str);
    UARTprintf ("\r\n");
    
    }
    } 

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

    Chuong、您好!

    读取的位数完全基于 SSIConfigSetExpClk 完成的 SSI 配置:

    SSIConfigSetExpClk (SSI0_BASE、ui32SysClock、SSI_FRF_MOTO_MOTO_0、SSI_MODE_MASTER、4000000、 14); 

    因此、如果您将其设置为14位、您将读取14位、如果您仅需要8位、则需要将其设置为8位。

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

    您好、Ralph、

    因此、如果我想读取32位、但 FIFO 只支持16位。 如何从 SPI 读取32位数据?

    此致、

    Chuong

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

    P/s:我是指如何从 SPI 获得32位的快照、尽管 MAX31855需要14个时钟周期("冷端补偿热电偶温度的完整串行接口读取需要14个时钟周期")

    谢谢、

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

    Chuong、您好!

    详细读取 D/S 基本上可以读取14或32位-当我第一次查看时、我认为它是32位、因为用于读取的寄存器是如何结构的。

    将 CS 驱动为低电平、以输出 SO 引脚上的第一个位。 冷端补偿热电偶温度的完整串行接口读取需要14个时钟周期。 读取热电偶和基准结温都需要三十二个时钟周期

    因此、如果您只需要温度、那么您应该能够使用显示的配置在一个读取命令中获得所有14位。 在这种情况下、您无需担心8位或32位。

    但是、如果您需要32位、则可能需要使用高级模式。 提供的代码方式意味着您将读取8位4x、因此您需要在 SSIDataGet API 中循环四次。 但是、这一切只有在您需要全部32位时才重要。

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

    您好、Ralph、

    在某种程度上、当我使用 Adv 模式时、它会在 SSIDataGet 函数处停止、因为8位读取。 如果我更改为9或更高、则它将只运行一次、其余仅为0。

    是否需要为 Tx 启用 GPIO_PA4_SSI0XDAT0? 在获取数据并为 DataPut 启用前、是否需要禁用 SSI?

    此外、 while (SSIBusy (SSI0_BASE){}不能使用广播模式。  

    以下是我的清理代码、易于遵循。

    int
    main (void)
    {
    uint32_t 初始数据;
    uint32_t ui32SysClock;
    
    uint32_t data[4]、i;
    
    ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、120000000);
    
    InitConsole();//设置 UART
    
    //=========== 设置 SSI0
    SysCtlPeripheralEnable (SYSCTL_Periph_SSI0);
    SSIDisable (SSI0_BASE);//禁用 SPI
    
    GPIOPinConfigure (GPIO_PA2_SSI0CLK);// SCK
    GPIOPinConfigure (GPIO_PA3_SSI0FSS);// SS
    GPIOPinConfigure (GPIO_PA5_SSI0XDAT1);// MISO Rx - GPIO_PA5_SSI0XDAT1
    
    GPIOPinTypeSSI (GPIO_Porta_base、GPIO_PIN_5 | GPIO_PIN_3 | GPIO_PIN_2);
    
    //****为 TI 主控模式配置和启用 SSI 端口。 使用 SSI0系统
    SSIConfigSetExpClk (SSI0_BASE、ui32SysClock、SSI_FRF_MOTO_MOTO_0、SSI_MODE_MASTER、100000、 8);
    
    SSIAdvFrameHoldEnable (SSI0_BASE);
    SSIAdvModeSet (SSI0_BASE、SSI_ADV_MODE_WRITE);
    
    SSIEnable (SSI0_BASE);
    
    //清除 RX FIFO 中可能存在的任何初始数据
    while (SSIDataGetNonBlocking (SSI0_BASE、初始数据));
    
    //=========== 结束 SSI0设置
    
    while (1)
    {
    
    SSIDataPut (SSI0_BASE、0x00);
    SSIDataPut (SSI0_BASE、0x00);
    SSIDataPut (SSI0_BASE、0x00);
    SSIAdvDataPutFrameEnd (SSI0_BASE、0x00);
    
    对于(i=0;i < 4;i++){
    SSIDataGet (SSI0_BASE、&DATA[i]);
    }
    //while (SSIBusy (SSI0_BASE)){}
    
    }
    } 

    此致、

    Chuong

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

    Chuong、您好!

    [引用用户="Chuong Vu "]如果我更改为9或以上,则它只运行一次,其余的只有0。

    正如在高级模式之前所述、只需在8字节模式下使用。 没有其他数量的字节可以用于它。

    [引用用户="Chuong Vu "]我是否需要为 Tx 启用 GPIO_PA4_SSI0XDAT0?

    [引用用户="Chuong Vu "]在获取数据并为 DataPut 启用前,是否需要禁用 SSI?[/quot]

    不需要、您不需要禁用然后重新启用它。 当您使用8字节以外的任何内容时、它只运行一次的问题是因为您没有使用有效的高级模式配置。