工具与软件:
我正在尝试实现 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)
