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.

[参考译文] TM4C123GH6PM:不适用

Guru**** 2510095 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1376394/tm4c123gh6pm-n-a

器件型号:TM4C123GH6PM

工具与软件:

我正在尝试实现 SSI0 (TM4C123作为主器件)、以便在 MCU 与 CCS 上的两个 Si834x 隔离式智能开关(作为从器件)之间进行通信。  

在它们之间实施实际的 SPI 协议之前、我尝试观察 SSI0时序图来验证数据字节是否正确发送。 基本上、我要发送10个字节、并使用逻辑分析仪(logic pro 8)来验证要传输的数据。   

不过、每三个字节(第1个、第4个、第7个、第10个字节)似乎就会有一个错误。 导致问题的原因是什么?我应该如何解决?

另外、应说明的是、如果我更改系统时钟频率或比特率、错误位置也会发生变化、但每三个字节仍然会发生一次(EX:在第2、5、8字节或第3、6、9字节...)

代码如下

#include
#include
#include
#include "inc/tm4c123gh6p.h"
#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 "utils/uartstdio.h"

#include "Si834x.h"

#define NUM_SSI_DATA 10 //10个数据字节

void InitSPI (void){
  //启用 SSI0和 GPIO 端口 A 的外设
  SysCtlPeripheralEnable (SYSCTL_PERIPH_SSI0);         //启用 SSI0外设
  SysCtlPeripheralEnable (SYSCTL_PERIPH_GPIOA);         //启用 SSI0的 GPIO 端口 A

  //配置 SSI0管脚
  //   PA2 - SSI0CLK
  //   PA3 - SSI0Fss (手动控制)
  //   PA4 - SSI0Rx (MISO)
  //   PA5 - SSI0Tx (MOSI)
  GPIOPinConfigure (GPIO_PA2_SSI0CLK);
  GPIOPinConfigure (GPIO_PA4_SSI0RX);
  GPIOPinConfigure (GPIO_PA5_SSI0TX);
  GPIOPinTypeSSI (GPIO_PORTA_BASE、GPIO_PIN_2 | GPIO_PIN_4 | GPIO_PIN_5);

  //设置 SSI 引脚的驱动强度和引脚类型(8mA 驱动强度)
  GPIOPadConfigSet (GPIO_PORTA_BASE、GPIO_PIN_5、GPIO_STENCE_8mA、GPIO_PIN_TYPE_STD);


  //配置并启用 SPI 主模式的 SSI 端口
  SSIConfigSetExpClk (SSI0_BASE、SysCtlClockGet ()、SSI_FRF_MOTO_MODE_3、SSI_MODE_MASTER、1000000、 8); //SSI_FRF_MOTO_MODE_3 ->在第二个时钟边沿捕获到数据、并且 SSI0Clk 稳态为高电平、1Mbps、8位
  SSIEnable (SSI0_BASE);                                         //启用 SSI0模块

  //配置 PA3进行手动 CS 控制
  GPIOPinTypeGPIOOutput (GPIO_PORTA_BASE、GPIO_PIN_3);
  GPIOPinWrite (GPIO_PORTA_BASE、GPIO_PIN_3、GPIO_PIN_3);//最初将 CS 设置为高电平
  SysCtlDelay (500);
}

void SPIWrite (uint8_t data){
  GPIOPinWrite (GPIO_PORTA_BASE、GPIO_PIN_3、0);      //将 CS 拉至低电平以开始通信
  SSIDataPut (SSI0_BASE、DATA);              //发送数据
  while (SSIBusy (SSI0_BASE)){}              //等待传输完成
  GPIOPinWrite (GPIO_PORTA_BASE、GPIO_PIN_3、GPIO_PIN_3);//将 CS 拉至高电平以进行端通信
  // SysCtlDelay (10);
}

int main (void){
  uint32_t pui32DataTx[NUM_SSI_DATA];
//  uint32_t pui32Datarx[NUM_SSI_DATA];
  uint32_t ui32Index;

//  SysCtlClockSet (SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHz);//系统时钟:80MHz
  SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHz);//系统时钟:16MHz

  //为 OE 配置 PE2并将其设置为高电平
  SysCtlPeripheralEnable (SYSCTL_PERIPH_GPIOE);
  while (! SysCtlPeripheralReady (SYSCTL_PERIPH_GPIOE)){}
  GPIOPinTypeGPIOOutput (GPIO_Porte _BASE、GPIO_PIN_2);
  GPIOPinWrite (GPIO_Porte _BASE、GPIO_PIN_2、GPIO_PIN_2);

  InitSPI();

  //清除 SSI 端口的所有剩余数据
  //while (SSIDataGetNonBlocking (SSI0_BASE、&pui32DataRx[0]){}

  pui32DataTx[0]= 0x01;
  pu32DataTx[1]= 0x12;
  pu32DataTx[2]= 0x23;
  pu32DataTx[3]= 0x34;
  pu32DataTx[4]= 0x45;
  pu32DataTx[5]= 0x56;
  pu32DataTx[6]= 0x78;
  pu32DataTx[7]= 0x89;
  pu32DataTx[8]= 0x9A;
  pu32DataTx[9]= 0xAB;

  for (ui32Index = 0;ui32Index < NUM_SSI_DATA;ui32Index++){
    SPIWrite (pui32DataTx[ui32Index]);
  }

  返回0;
}

这是时序图(通道4是 CS)

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

    我忘记提到这一点、但该错误仅在我将逻辑分析仪连接到从设备(Si834x)时发生。 如果我将逻辑分析仪连接到微控制器、则传输的数据正确。

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

    您好!

    Unknown 说:
    我忘记提及这一点、但仅当我将逻辑分析仪连接到从器件(Si834x)时才会发生此错误。 如果我将逻辑分析仪连接到微控制器、则传输的数据正确。

     您认为当您将 LA 连接到 MCU 时的波形是正确的。 在这种情况下、MCU 会正确传输数据。  

     您如何在主设备和从设备之间进行连接? 使用长导线时彼此是否相距较远?  

     观察您的波形、您不是每3个字节跳过一个数据、而是 LA 捕获了错误的数据。 例如、您正在移出0x12、0x23、然后移出0x34。 但是、LA 将捕获0x12、0x23和0x38。 这是0x34与0x38、但有一位差异。 接下来、您移位0x45、0x56、然后是0x78。 但这次、LA 捕获到0x45、0x56和0x70。 同样、它是0x78与0x70、但有一位差异。 这暗示了一些时序问题、例如来自 MCU 的数据不符合 LA 捕获边沿的设置时间。 如果您处于模式3、则需要确保 LA 设置为在正确的边沿和相位进行采样。 我建议您使用模式0、这应该是大多数 LA 的默认模式。 无论是否满足时序要求、都可以使用示波器来更好地查看。 同样、如果导线较长、或者 MCU、从器件和 LA 不在共用接地、则可能是无法采样正确数据的原因。  

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

    您好!

    感谢您的建议。 问题是、我是从从从器件的 MOSI_THRU 读取输出、而不是直接从 TM4C 从 MOSI 引脚读取输出。 Si834x 数据表显示 MOSI_THRU 和 MOSI 是两个不同的引脚、并输出不同的信号。