您好!
我是一名学生、正在从事一个利用 Tiva tm4c123gh下午6 ARM 处理器的高级设计项目、并且正在努力使 SPI 从接口正常工作。
到目前为止、我已经使用了此表单文章 https://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/302734?SPI-Slave-problem 中的一个示例
并将其修改为使用 SSI0而不是 SSI2。 在测试代码时,我无法从主器件 Raspberry PI 读取多个字节,在下面显示的函数 SSIDataGet ()中的 Tiva 在无限循环中挂起等待数据之前。 主器件的时钟设置为122kHz。
void
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);
}
示波器输出显示数据已正确发送、但 Tiva 似乎未处理数据、我不确定如何解决此问题。
通道1为 clk、2为 MOSI、3为 MISO、4为 CS。
如果有任何建议、我将非常感激、下面是我的完整代码。
// // //// spi_slave.c -演示如何在 // SPI 从模式中配置 RX 超时中断的示例。 // //版权所有(c) 2013 Texas Instruments Incorporated。 保留所有权利。 // TI 信息-选择性披露 // ********* #include #include #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_ssi.h" #include "inc/hw_types.h" #include "driverlib/ssi.h" #include "driverlib/interrupt.h" #include "driverlib/driverlib"#driverlib/udio.h"#include "driverlib/us.trine.h // //! \addtogroup SSI_examples_list //!SPI 从器件(SPI_SLAVE)
//! //! 此示例将 SSI0配置为 SPI 主器件、将 SSI2配置为 SPI 从器件、位于// ! EK-LM4F232评估板。 为 SSI2配置 RX 超时中断。 //! 在主器件 TX 上发送三个字符、然后 SSI2 RX 超时中断 //! 启用。 然后代码等待中断触发。 一次 //! 触发中断读取从器件 RX FIFO 中的数据并将其与 //! 传输的数据包、并显示相应的状态。 如果一切都好 //! 运行良好您应该会看到"Test Passed"。 终端窗口上的消息。 //! 状态消息通过 UART0以115200波特和8-n-1 //! 模式。 //! //! 此示例使用 EK-LM4F232上的以下外设和 I/O 信号。 //! 您必须查看这些内容并根据自己的板的需要进行更改: //! - SSI0外设 //! - GPIO 端口 A 外设(用于 SSI0引脚)(在 SD 卡插槽附近可用) //! - SSI0CLK - PA2 //! - SSI0Fss - PA3 //! - SSI0Rx - PA4 //! - SSI0Tx - PA5 //! //! - SSI2外设 //! - GPIO 端口 M 外设(用于 SSI2引脚)(在 OLED 的正下方提供) //! - SSI2CLK - PH4 //! - SSI2Fss - PH5 //! - SSI2Rx - PH6 //! - SSI2Tx - pH7 //! //! 为了使该示例正常工作、 //!上需要以下连接 EK-LM4F232评估板。 //! - SSI0CLK (PA2)- SSI2CLK (PH4) //! - SSI0Fss (PA3)- SSI0Fss (PH5) //! - SSI0Rx (PA4)- SSI2Tx (pH7) //! - SSI0Tx (PA5)- SSI2Rx (PH6) //! //! 以下 UART 信号仅配置为显示控制台 //! 消息。 SSI0的运行不需要这些。 //! - UART0外设 //! - GPIO 端口 A 外设(用于 UART0引脚) //! - UART0RX - PA0 //! - UART0TX - PA1 //! //! 此示例使用以下中断处理程序。 要使用此示例 //! 在您自己的应用程序中、您必须将这些中断处理程序添加到 您的//! 矢量表。 //! -SSI2IntHandler。 //! //// ***************** // // //要发送和接收的字节数。 //// ***************** #define NUM_SSI_DATA 7 //********* // ////中断处理程序和主循环中使用的全局变量。 //// ***************** volatile unsigned long g_ulSSI0RXTO = 0; unsigned long g_ulDataRx0[NUM_SSI_DATA]={0}; //********* // //从机模式中 SSI0外设的中断处理程序。 它读取中断 //状态、如果中断由 RX 超时中断触发、它读取 // SSI0 RX FIFO 并递增计数器以告知主循环 已触发 RX 超时//中断。 //// ***************** void SSI0IntHandler (void) { unsigned long ulStatus = 0、ulIndex = 0; // //读取中断状态。 // ulStatus = SSIIntStatus (SSI0_BASE、0); // //检查中断原因。 // IF (ulStatus & SSI_RXTO) { // //中断是因为 RX 超时。 因此、递增计数器会发出指示 //发生 RX 超时中断的主循环。 // G_ulSSI0RXTO++; // //从 SSI2 RX FIFO 读取 NUM_SSI_DATA 数据字节。 // for (int ulIndex = 0;ulIndex < NUM_SSI_DATA;ulIndex++){ SSIDataGet (SSI0_BASE、&g_ulDataRx0[ulIndex]); } } // //清除中断。 // SSIIntClear (SSI0_BASE、ulStatus); } //********* // //此函数将 SPI0设置为在 Freescale 模式下用作主机。 //// ***************** void InitSPI0 (void) { // //必须启用 SSI0外设才能使用。 // SysCtlPeripheralEnable (SYSCTL_Periph_SSI0); // //对于本示例,SSI0与 Porta[5:2]一起使用。 GPIO 端口 A 需要 //因此可以使用这些引脚。 // SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA); // //为端口 A2、A3、A4和 A5上的 SSI0功能配置引脚复用。 //如果您的器件不支持引脚复用、则无需执行此步骤。 // GPIOPinConfigure (GPIO_PA2_SSI0CLK); GPIOPinConfigure (GPIO_PA3_SSI0FSS); GPIOPinConfigure (GPIO_PA4_SSI0RX); GPIOPinConfigure (GPIO_PA5_SSI0TX); // //配置 SSI 引脚的 GPIO 设置。 该函数也会提供 将这些引脚的//控制到 SSI 硬件。 请参阅中的数据表 //查看每个引脚分配的函数。 //引脚分配如下: // PA5 - SSI0Tx // PA4 - SSI0Rx // PA3 - SSI0Fss // PA2 - SSI0CLK // GPIOPinTypeSSI (GPIO_Porta_base、GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2); // //为 SPI 从模式配置和启用 SSI0端口。 // SSIConfigSetExpClk (SSI0_BASE、SysCtlClockGet ()、SSI_FRF_MOTO_MODE_0、 SSI_MODE_SLAVE、122000、8); // //启用 SSI0模块。 // SSIEnable (SSI0_BASE); } int main (void) { SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHz); InitSPI0(); SSIDataPut (SSI0_BASE、0xED); // Rx 中断 SSIIntEnable (SSI0_BASE、SSI_RXTO); IntEnable (INT_SSI0); while (1);//在此处调试暂停并检查缓冲 区}

