主题中讨论的其他器件: TM4C123
大家好、我正在使用一对 TM4C123G 评估板尝试使 SSI 通道正常工作。 这些电路板具有 TM4C123GH6PM 微控制器。 我正在使用最新版本的 Code Composer Studio 和 TivaWare 2.2.0.295。
在板之间、我们连接了 SSI1时钟、SSI1 RX/TX 交叉-板上1的 RX 连接到板上2的 TX、反之亦然。 我有两个 CCS 项目、一个是 SPI 主设备、另一个是 SPI 从设备。 我只是尝试以每秒两次的频率将"1234"从主设备传输到从设备。 我们看了示波器上的这些行、我们看到了一个1MHz 时钟和2Hz 数据。 从这一点来看、主侧似乎按预期工作。 我遇到的这个问题是在从器件上。 设置完成后、我进入了尝试读取数据的循环、并且对 SSIDataGet 的第一次调用从不返回。 两侧都有源代码。 "我怎么了?"
// SPI master #include <stdint.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" ///////////////////////////////////////////////////////////////////////////// void InitializeSystem() { // Set the clocking to run directly from the crystal. SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); // Initialize UART1 to 115200 baud, N-8-1 // UART1 : GPIO Port B : UART1RX = PB0 : UART1TX = PB1 SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); GPIOPinConfigure(GPIO_PB0_U1RX); GPIOPinConfigure(GPIO_PB1_U1TX); GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1); UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(), 115200, UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE); } ///////////////////////////////////////////////////////////////////////////// void InitializeSSI1() { // Enable the SSI1 peripheral for use. SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1); // We have PD0 (SSI1 Clk), PD2 (SSI1 Rx), and PD3 (SSI1 Tx) connected. // (Odd thing, pins/ports for SSI1 are the same as SSI3 ?!) SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); // Configure the pin muxing for SSI functions GPIOPinConfigure(GPIO_PD0_SSI1CLK); GPIOPinConfigure(GPIO_PD1_SSI1FSS); GPIOPinConfigure(GPIO_PD2_SSI1RX); GPIOPinConfigure(GPIO_PD3_SSI1TX); // Configure the GPIO settings for the SSI pins. This function also gives // control of these pins to the SSI hardware. GPIOPinTypeSSI(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3); // Configure and enable the SSI port for SPI master mode. SSIDisable(SSI1_BASE); SSIConfigSetExpClk(SSI1_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 1000000, 8); // Advance mode settings. Legacy is default. I've seen several mentions // in technical forum discussions that when writing as SSI master, you // need "dummy" reads (in legacy mode)? //SSIAdvModeSet(SSI1_BASE, SSI_ADV_MODE_WRITE); // Enable the SSI module. SSIEnable(SSI1_BASE); // Read residual data from the SSI port so we don't read any junk. uint32_t RxData; while (SSIDataGetNonBlocking(SSI1_BASE, &RxData)) { } } ///////////////////////////////////////////////////////////////////////////// int main(void) { InitializeSystem(); InitializeSSI1(); // A call to SysCtlDelay with a delay count of 1 takes 3 clock cycles unsigned int nDelayOneMillisecond = (SysCtlClockGet() / 3) / 1000; const unsigned int nDelayCount = 500 /* milliseconds */ * nDelayOneMillisecond; const unsigned int Message[4] = { '1', '2', '3', '4' }; uint32_t RxData = 0; while (true) { // Transmit on SPI and UART every <n> milliseconds. SysCtlDelay(nDelayCount); for (unsigned int nByte = 0 ; nByte < 4 ; nByte++) { while (SSIDataGetNonBlocking(SSI1_BASE, &RxData)) {} SSIDataPut(SSI1_BASE, Message[nByte]); // SSIDataGetNonBlocking(SSI1_BASE, &RxData); UARTCharPut(UART1_BASE, (unsigned char)Message[nByte]); } } }
// SPI slave #include <stdint.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" ///////////////////////////////////////////////////////////////////////////// void InitializeSystem() { // Set the clocking to run directly from the crystal. SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); // Initialize UART1 to 115200 baud, N-8-1 // UART1 : GPIO Port B : UART1RX = PB0 : UART1TX = PB1 SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); GPIOPinConfigure(GPIO_PB0_U1RX); GPIOPinConfigure(GPIO_PB1_U1TX); GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1); UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(), 115200, UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE); } ///////////////////////////////////////////////////////////////////////////// void InitializeSSI1() { // Enable the SSI1 peripheral for use. SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1); // We have PD0 (SSI1 Clk), PD2 (SSI1 Rx), and PD3 (SSI1 Tx) connected. // (Odd thing, pins/ports for SSI1 are the same as SSI3 ?!) SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); // Configure the pin muxing for SSI functions GPIOPinConfigure(GPIO_PD0_SSI1CLK); GPIOPinConfigure(GPIO_PD1_SSI1FSS); GPIOPinConfigure(GPIO_PD2_SSI1RX); GPIOPinConfigure(GPIO_PD3_SSI1TX); // Configure the GPIO settings for the SSI pins. This function also gives // control of these pins to the SSI hardware. GPIOPinTypeSSI(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3); // Configure and enable the SSI port for SPI slave mode. SSIDisable(SSI1_BASE); SSIConfigSetExpClk(SSI1_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_SLAVE, 1000000, 8); //SSIConfigSetExpClk(SSI1_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_SLAVE_OD, 1000000, 8); // Advance mode settings. Legacy is default. //SSIAdvModeSet(SSI1_BASE, SSI_ADV_MODE_LEGACY); // Enable the SSI module. SSIEnable(SSI1_BASE); // Read residual data from the SSI port so we don't read any junk. uint32_t RxData; while (SSIDataGetNonBlocking(SSI1_BASE, &RxData)) { } } ///////////////////////////////////////////////////////////////////////////// int main(void) { // Initialize the system InitializeSystem(); InitializeSSI1(); unsigned int nByte = 0; while (true) { // Get next charater on SPI and forward to UART SSIDataPut(SSI1_BASE, 0); // dummy write? SSIDataGet(SSI1_BASE, &nByte); UARTCharPut(UART1_BASE, (unsigned char)nByte); } }