SPI Communication in TM4C123G (Read ADXL345 Device ID Over SPI)
SPI is one of the fastest and most reliable communication protocols used in embedded systems. It works with sensors, displays, memory chips and many other digital devices. In this tutorial, we learn how to use SPI in TM4C123G Tiva C with simple steps and clean code.
To prove that our SPI setup works, we read the Device ID of the ADXL345 accelerometer. We use only one register from the ADXL345. The goal is to understand SPI, not the sensor. This keeps the tutorial simple and easy to follow.
We use TivaWare, because it offers clear APIs for SPI communication. You will learn how to enable the SSI module, configure the SPI pins, set the clock, and exchange data with an SPI slave device. By the end of this guide, you will be ready to use SPI with any sensor or module in your own projects.

Recommended Resources:
I have already covered how to create a project in CCStduio and configure system clock in the previous tutorials. This tutorial is going to be a continuation in this series, so you must read the following tutorials first:
- How to Setup CCStudio and build your first project with TM4C123G
- How to configure system clock in TM4C123G
What Is SPI and How It Works
SPI is a high-speed serial protocol. Before we use it on the TM4C123G, let’s first understand the basics. This will make the later steps easier to follow.
SPI Clock and Data Lines
SPI uses four main lines to transfer data.
- The SCK line carries the clock from the master device.
- The MOSI line sends data from master to slave.
- The MISO line sends data from slave back to the master.
- And the CS or SS line selects which slave is active.
These lines work together to move data in both directions. Because of this, SPI is fast and efficient. The clock keeps everything in sync, so every bit arrives at the right time.
Master and Slave Roles
SPI follows a simple master–slave structure.
- The master controls the clock. It also decides when to start a transfer.
- The slave waits for commands. It responds only when selected through the CS line.
This one-direction control makes SPI stable and predictable. Multiple slaves can also share the same bus, as long as each has its own CS line.
SPI Data Frame Format
SPI transfers data in units called frames. Common frame sizes are 8 bits and 16 bits, but some devices support more.
A frame begins when the master pulls CS low.
Next, the master shifts out bits on MOSI. At the same time, the slave shifts back bits on MISO. This means SPI supports full duplex communication.
Two timing settings define how data is captured:
- Clock Polarity (CPOL) – Defines the idle level of the clock (high or low).
- Clock Phase (CPHA) – Defines which clock edge samples data.
The combination of CPOL and CPHA creates four SPI modes. Different sensors use different modes, so selecting the correct one is important. For example, the ADXL345 uses SPI Mode 3.
Below is a simple and easy-to-understand table of the four SPI modes:
| SPI Mode | CPOL | CPHA | Clock Idle State | Data Sampled On |
|---|---|---|---|---|
| Mode 0 | 0 | 0 | Clock idle low | Rising edge |
| Mode 1 | 0 | 1 | Clock idle low | Falling edge |
| Mode 2 | 1 | 0 | Clock idle high | Falling edge |
| Mode 3 | 1 | 1 | Clock idle high | Rising edge |
Because SPI is flexible, you must match these timing settings with the slave device’s datasheet.
Why Use SPI in Embedded Systems
SPI is widely used because:
- It supports very high speeds (several MHz).
- It offers full-duplex transfer, unlike I2C.
- It needs no complex addressing or acknowledgment mechanism.
- It works well with sensors, memories, ADCs, DACs, and displays.
SPI also has predictable timing because the clock is always controlled by the master. This makes it ideal for real-time embedded applications that require fast and reliable data movement.
SPI Module in TM4C123G Tiva C
The TM4C123G has multiple SSI modules that support SPI mode. In this section, we explore the pins and features. This helps you understand how the hardware inside the microcontroller handles SPI communication.
Overview of SSI0 to SSI3
The TM4C123G Tiva C LaunchPad includes four SSI (Synchronous Serial Interface) modules, SSI0, SSI1, SSI2, and SSI3. Each module supports multiple serial protocols, including SPI, TI synchronous serial, and Microwire. All four SSI modules operate independently, which means you can use multiple SPI buses at the same time without interference.
| SSI Module | Base Address | Function |
|---|---|---|
| SSI0 | 0x4000.8000 | SPI / TI / Microwire |
| SSI1 | 0x4000.9000 | SPI / TI / Microwire |
| SSI2 | 0x4000.A000 | SPI / TI / Microwire |
| SSI3 | 0x4000.B000 | SPI / TI / Microwire |
SSI0 is the most commonly used module because its pins are easily accessible on the LaunchPad headers. SSI1, SSI2, and SSI3 are more useful for complex applications or custom PCBs that need multiple SPI devices running simultaneously.
SPI Pin Mapping on TM4C123G
Each SSI module uses four pins, CLK, FSS (CS), TX, and RX. These pins are multiplexed with GPIO pins, so you must enable their alternate functions before using SPI. Choosing the correct pin mapping is important, because the SPI signals will not work unless the selected pins match the active SSI module configuration.
Here’s a quick reference for commonly used pin mappings:
| SSI Module | CLK Pin | FSS Pin | RX Pin | TX Pin | GPIO Port |
|---|---|---|---|---|---|
| SSI0 | PA2 | PA3 | PA4 | PA5 | Port A |
| SSI1 | PF2 | PF3 | PF0 | PF1 | Port F |
| SSI2 | PB4 / PD3 | PB5 / PD2 | PB6 / PD1 | PB7 / PD0 | Ports B / D |
| SSI3 | PD0 / PF2 | PD1 / PF3 | PD2 | PD3 | Ports D / F |
SSI0 is typically used for quick testing or simple SPI communication. SSI1, SSI2, and SSI3 provide alternate pin options and are ideal when your project layout requires specific routing or when multiple SPI peripherals are connected.
Always confirm the correct mapping using the TM4C123G datasheet or the TivaWare pin_map.h file.
SPI Clock and Mode Options
Each SSI module allows you to configure:
- Clock polarity (CPOL)
- Clock phase (CPHA)
- Bit rate (SPI speed)
- Data size (from 4 to 16 bits)
- Clock prescalers and dividers
Because of this flexibility, the TM4C123G can communicate with almost any SPI device.
You can set the SPI mode to Mode 0, 1, 2, or 3, depending on the sensor or module you are using. For example, the ADXL345 accelerometer works in SPI Mode 3.
The bit rate is also adjustable. In most cases, SPI can operate comfortably in the range of 1–4 MHz for sensors. The exact value depends on your wiring and the slave device’s limits.
Using Pull-ups and Correct Wiring
SPI does not require pull-up resistors like I2C, because the lines are push-pull drivers. However, correct wiring is still very important.
Keep these points in mind:
- Connect all grounds together (MCU and slave device).
- Keep MISO and MOSI lines short to avoid noise.
- The CS pin must be controlled by the master and kept low only during communication.
- If you have long wires or noisy environments, you may add small series resistors (33–100 ohms) to reduce ringing.
For most Tiva C projects, simple and clean wiring is enough. And since the TM4C123G handles the SPI timing internally, communication remains stable as long as the connections are correct.
Hardware Setup for SPI With ADXL345
We use the ADXL345 only to verify SPI communication on the TM4C123G Tiva C. The goal is simple: read its Device ID register (0x00) using SPI Mode 3. Before making the connections, let’s look at the pinout of the ADXL345 so the wiring becomes clear.
ADXL345 Pinout (SPI Focused)
The ADXL345 breakout board supports both I2C and SPI interfaces. Since this tutorial is about SPI, we will use the pins that are required for 4-wire SPI.
The image below shows the ADXL345 Pinout.
The table below explains each pin and what it does.
| Pin | Function | Description |
|---|---|---|
| VCC | Power Input | Connect to 3.3V. The ADXL345 is a 3.3V sensor. |
| GND | Ground | Connect to the system ground. |
| CS | Chip Select | Must be kept LOW to enable SPI mode. |
| SCL | SPI Clock (SCK) | Clock signal driven by the TM4C123G SPI master. |
| SDA | MOSI | Data sent from microcontroller to ADXL345. |
| SDO | MISO | Data sent from ADXL345 to microcontroller. |
| INT1 | Interrupt 1 | Used for motion/threshold interrupts (not used here). |
| INT2 | Interrupt 2 | Optional interrupt output (not used here). |
These pins are common across most ADXL345 boards, so identifying them should be easy.
Connecting TM4C123G to ADXL345
In this tutorial, we use SSI0 on the TM4C123G. This module has a clean pin mapping and is widely used for SPI testing. The default SPI pins for SSI0 are:
- PA2 → SSI0CLK
- PA3 → SSI0FSS (Chip Select)
- PA4 → SSI0RX (MISO)
- PA5 → SSI0TX (MOSI)
The image below shows the wiring connection between TM4C123G and ADXL345.
Based on the pinout above, make the following connections:
| TM4C123G Pin | ADXL345 Pin | Purpose |
|---|---|---|
| PA2 (CLK) | SCL | SPI Clock |
| PA3 (FSS) | CS | Chip Select |
| PA5 (TX) | SDA | MOSI |
| PA4 (RX) | SDO | MISO |
| 3.3V | VCC | Power |
| GND | GND | Ground |
Keep the wires short and avoid mixing them with noisy high-current lines.
Notes About Chip Select (CS) Handling
The CS pin, also called FSS on the TM4C123G, is an important part of SPI communication. It selects the ADXL345 as the active slave device.
- The CS line must be pulled LOW before sending any command/data.
- It is released HIGH after the transfer is complete.
- The SSI peripheral can automatically toggle CS, but you can also drive it manually if needed.
For this simple Device ID read, automatic CS control works perfectly.
SPI Mode Required for ADXL345
The ADXL345 uses SPI Mode 3, which means:
- CPOL = 1 (Clock idle high)
- CPHA = 1 (Data captured on rising edge)
If SPI mode is incorrect, you will not get the correct Device ID. The expected ID is:
- Device ID = 0xE5
This single register read is enough to confirm that your SPI wiring and initialization are correct.
Configuring SPI in TivaWare
TivaWare makes SPI setup simple. It provides clean APIs to enable the SSI module, configure the GPIO pins, and set the SPI clock and mode. In this section, we walk through the essential code needed to prepare the TM4C123G for SPI communication.
Header Files Used
Let’s begin by looking at all the header files required for this SPI project using the TM4C123G and TivaWare. Each file plays an important role in system configuration, GPIO setup, and SPI communication.
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/ssi.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"- <stdint.h> – Provides fixed-width data types such as
uint8_t,uint16_t, anduint32_t. - <stdbool.h> – Adds Boolean support, giving access to
bool,true, andfalse. - “inc/hw_memmap.h” – Contains base addresses for all hardware peripherals (SSI, GPIO, timers, UART, etc.).
- “driverlib/sysctl.h” – Used to configure the system clock and enable peripheral modules such as SSI0 and GPIO.
- “driverlib/ssi.h” – Provides all SPI-related TivaWare APIs, including initialization, configuration, transmit, and receive functions.
- “driverlib/gpio.h” – Required for configuring GPIO directions, enabling alternate functions, and controlling chip-select pins.
- “driverlib/pin_map.h” – Maps GPIO pins to their alternate SPI functions (for example:
PA2 → SSI0CLK,PA5 → SSI0TX).
Enabling SSI Peripheral Clock
The first step is to enable the clock for both the SSI module and the GPIO port used by the SPI pins.
To use SSI0, we enable:
- SSI0 peripheral clock
- Port A clock (because PA2–PA5 are SPI pins)
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
// Wait until ready
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_SSI0));
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA));Without enabling these clocks, the SPI registers and pins will not work.
Configuring GPIO Pins for SPI
Next, we configure the GPIO pins to work in their alternate function mode for SPI.
For SSI0, we need PA2, PA3, PA4, and PA5.
GPIOPinConfigure(GPIO_PA2_SSI0CLK);
GPIOPinConfigure(GPIO_PA3_SSI0FSS);
GPIOPinConfigure(GPIO_PA4_SSI0RX);
GPIOPinConfigure(GPIO_PA5_SSI0TX);
GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_2 | GPIO_PIN_3 |
GPIO_PIN_4 | GPIO_PIN_5);This tells the microcontroller to route the SPI signals to the correct pins.
Initializing SPI Clock, Mode, and Bit Rate
Now we set the SPI speed, mode, and frame format. The ADXL345 requires SPI Mode 3 (CPOL=1, CPHA=1), so we configure the SSI module accordingly.
SSIConfigSetExpClk(SSI0_BASE,
SysCtlClockGet(),
SSI_FRF_MOTO_MODE_3, // SPI Mode 3
SSI_MODE_MASTER,
4000000, // 4 MHz SPI clock
8); // 8-bit dataHere we do the following:
- Use system clock for the SSI timing.
- Choose Motorola SPI Frame Format (MOTO).
- Run the SPI as Master.
- Set the SPI clock to 4 MHz.
- Use 8-bit frame size.
Finally, enable the SSI module:
SSIEnable(SSI0_BASE);Sending and Receiving Data Over SPI
To send a byte, TivaWare offers a simple API:
uint32_t txData = 0x00; // example byte
SSIDataPut(SSI0_BASE, txData);To read data, you must call SSIDataGet():
uint32_t rxData;
SSIDataGet(SSI0_BASE, &rxData);SPI always performs full-duplex transfers.
This means:
- When you send a byte, you also receive a byte.
- When you read a byte, you must also send a dummy byte.
A common pattern for SPI reads is:
uint32_t rx;
SSIDataPut(SSI0_BASE, 0x00); // Send dummy data
SSIDataGet(SSI0_BASE, &rx); // Read the responseThis code is all we need before reading the ADXL345 Device ID.
Complete SPI Initialization Function
Below is a separate block of code that shows the full SPI setup for SSI0 on the TM4C123G. It includes everything: enabling clocks, configuring pins, setting SPI mode, and enabling the SSI module.
void SPI0_Init(void)
{
//
// Enable peripherals
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_SSI0));
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA));
//
// Configure SPI pins: PA2 (CLK), PA3 (FSS), PA4 (RX), PA5 (TX)
//
GPIOPinConfigure(GPIO_PA2_SSI0CLK);
GPIOPinConfigure(GPIO_PA3_SSI0FSS);
GPIOPinConfigure(GPIO_PA4_SSI0RX);
GPIOPinConfigure(GPIO_PA5_SSI0TX);
GPIOPinTypeSSI(GPIO_PORTA_BASE,
GPIO_PIN_2 | GPIO_PIN_3 |
GPIO_PIN_4 | GPIO_PIN_5);
//
// Configure SSI0 in Motorola Mode 3, Master mode
// 4 MHz SPI clock, 8-bit data size
//
SSIConfigSetExpClk(SSI0_BASE,
SysCtlClockGet(),
SSI_FRF_MOTO_MODE_3,
SSI_MODE_MASTER,
4000000,
8);
//
// Enable the SSI module
//
SSIEnable(SSI0_BASE);
//
// Clear receive FIFO (optional but recommended)
//
uint32_t dummy;
while(SSIDataGetNonBlocking(SSI0_BASE, &dummy));
}Reading ADXL345 Device ID Over SPI
To verify that our SPI setup is working, we will read the Device ID register of the ADXL345. This value never changes, so it is a reliable way to confirm that SPI communication between the TM4C123G and the ADXL345 is successful.
ADXL345 Device ID Register (0x00)
The ADXL345 stores its identification value in register 0x00.
This register is read-only and always returns:
- 0xE5: ADXL345 Device ID
If we receive 0xE5, it means:
- SPI wiring is correct
- SPI mode is correct
- Clock and data lines are stable
- The ADXL345 is responding properly
So this simple read is a perfect first test.
SPI Command to Read a Register
The ADXL345 uses a simple command format for SPI reads.
To read one register:
- Set bit7 = 1 (Read operation)
- Leave bit6 = 0 (Single-byte transfer)
- Bits 0–5 contain the register address
For example:
| Operation | Register | Command Byte |
|---|---|---|
| Read | 0x00 | 0x80 |
This is the command we will send using SSI0.
After sending the command, we must send a dummy byte (0x00) to generate clock pulses, and the ADXL345 returns the data.
This follows the SPI full-duplex rule:
every byte sent produces a byte received.
Code Example to Read Device ID
Below is a clean and simple example showing how to read the ADXL345 Device ID using the functions we created earlier.
uint8_t ADXL345_ReadDeviceID(void)
{
uint32_t dummy;
uint32_t rxData;
uint8_t reg = 0x00; // Device ID register
uint8_t command = reg | 0x80; // Read command (bit7 = 1)
//
// Select ADXL345 (CS LOW)
//
GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3, 0x00);
//
// Send the register address with read bit
//
SSIDataPut(SSI0_BASE, command);
// Wait until transmitted
while(SSIBusy(SSI0_BASE));
//
// Clear any received dummy data
//
SSIDataGet(SSI0_BASE, &dummy);
//
// Send dummy byte to generate clock and receive ID
//
SSIDataPut(SSI0_BASE, 0x00);
// Wait until transfer completes
while(SSIBusy(SSI0_BASE));
//
// Read the Device ID returned by ADXL345
//
SSIDataGet(SSI0_BASE, &rxData);
//
// Release ADXL345 (CS HIGH)
//
GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_PIN_3);
return (uint8_t)rxData;
}You can call this function from your main code:
uint8_t id = ADXL345_ReadDeviceID();The expected value is 0xE5.
Testing the SPI Communication
Once the SPI setup and functions are ready, it’s time to test the communication between the TM4C123G Tiva C LaunchPad and the ADXL345.
We’ll perform a simple test:
- Read the ID of ADXL345.
- Verify the ID by printing it on the serial console via UART.
- Confirm the bus signals using a logic analyzer.
Before we start testing the SPI, we first need to first configure some basic setup in Code Composer Studio (CCS).
Creating and Configure a New CCS Project for Tiva C LaunchPad
I have already explained how to create a new project in TM4C123 using CCStudio. You can create a similar project with blinky template and then modify it for this tutorial.
There are only 2 things we need to do to turn the blinky template into a new project:
- Delete everything from the blinky.c file, so it should be completely empty. We will write everything ourselves.
- Rename the following:
- blinky.c → main.c, indicating that this is the main file for the project
- blinky_css.cmd → linker.cmd, indicating that this is the linker file
- blinky (Folder) → projectName (Folder)
The final modified project is shown in the image below.
After creating the project, add basic_conf.c and basic_conf.h files in the project directory. These files will configure the following:
- Configure the System to use Main Oscillator (MOSC) along with PLL to run the MCU at 80MHz. Check out the Clock Configuration in TM4C123G Tutorial.
- Configure the SysTick Timer as the timebase for delay functions. Check out TM4C123G Delay Tutorial.
- Add the
#include "basic_conf.h"to include the basic configuration library file and#include "driverlib/interrupt.h"to include interrupt functions in the main file. - Inside the main function, call
systemClockConfig()to configure the PLL to run the system at 80MHz clock. - After everything else is initialized, call
IntMasterEnable()to enable the master interrupt. This is needed for the SysTick based Delay to work.
UART0 Initialization for Debug printf
UART0 is used in this project to print debug messages. This helps us confirm whether the project is working correctly. The UART0 is connected to the Virtual COM Port (VCP) through the on-board debugger, so no external hardware is required to view the output.
You can check more information about UART on the Tiva C LaunchPad by visiting the following link:
Use UART VCP in TiVa C.
The function below sets up UART0 on pins PA0 (RX) and PA1 (TX) at a baud rate of 115200.
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
void UART0_Init(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
UARTStdioConfig(0, 115200, 16000000);
}Short Explanation
- Enable UART0 and GPIOA clocks.
Required before configuring any pins or UART registers. - Configure PA0 and PA1 for UART.
PA0 → U0RX, PA1 → U0TX using alternate pin functions. - Set pin type to UART.
Activates UART electrical characteristics on these pins. - Select UART clock source.
Uses the 16 MHz PIOSC for stable baud rate generation. - Configure UARTStdio.
Sets baud rate to 115200 and preparesUARTprintf()for debugging.
Important Note
To use UARTprintf() and UARTStdioConfig(), you must add the file:
TivaWare/utils/uartstdio.cto your project.
Create a folder named utils inside your project and copy uartstdio.c into it.
Without this file, the linker will give errors for undefined symbols.
Main Code for Testing
Here’s the complete test code:
int main(void)
{
systemClockConfig();
// Other Initializations
IntMasterEnable();
UART0_Init();
SPI0_Init();
UARTprintf("\n--- ADXL345 SPI Test ---\n");
uint8_t id = ADXL345_ReadDeviceID();
UARTprintf("Device ID = 0x%02X\n", id);
while(1)
{
}
}How the code works
- The
main()function starts by configuring the system clock usingsystemClockConfig(). After that, all required peripherals are initialized, and global interrupts are enabled withIntMasterEnable(). - Next, the program sets up UART0 for debugging messages and initializes SPI0, which we use to communicate with the ADXL345 sensor.
- Once everything is ready, a message is printed to indicate the start of the SPI test. The function
ADXL345_ReadDeviceID()is then called to read the fixed Device ID register of the sensor. The received ID value is printed on the UART console. - Finally, the program enters an infinite loop, keeping the microcontroller running.
Output on the serial console
The image below shows the ID read by the MCU is sent via UART.
Logic Analyzer Output
To visually confirm the communication, connect a logic analyzer to the CS, SCK, MOSI and MISO lines and capture the waveform during the test.
The image below shows the output of logic analyzer when the Command (0x80) is sent by the master and the ID (0xE5) is sent by the slave.
The image shows the SPI communication sequence for reading a register from the ADXL345. The Chip Select (CS) line is pulled LOW to activate the device, after which the master sends the command byte 0x80 over the MOSI line while the clock pulses on SCK. In response, the ADXL345 returns the fixed Device ID value 0xE5 on the MISO line during the next clock cycle. This timing diagram helps visualize how the command is transmitted and how the sensor sends back data during an SPI read operation.
Troubleshooting SPI Issues on TM4C123G
If the ADXL345 does not return the correct Device ID or the SPI lines look inactive, check these common issues first.
1. Verify SPI Pin Mapping
- Make sure PA2 (CLK), PA3 (FSS/CS), PA4 (RX), and PA5 (TX) are used for SSI0.
- Confirm all pins are configured with
GPIOPinConfigure()andGPIOPinTypeSSI(). - Wrong pin mapping is the most common cause of no SPI activity.
2. Check Chip Select (CS) Handling
- Pull CS LOW before sending a command.
- Pull CS HIGH after the transfer is complete.
- If CS is always HIGH or floating, the ADXL345 will never respond.
3. Confirm SPI Mode
- ADXL345 uses SPI Mode 3 (CPOL = 1, CPHA = 1).
- Wrong mode results in incorrect or repeated data.
4. Inspect Wiring and Power
- Power the ADXL345 at 3.3V and ensure proper GND connection.
- Check MOSI, MISO, and SCLK connections.
- Loose jumper wires cause intermittent or no data.
5. Use UART Debug Prints
- Print received values using
UARTprintf(). 0xFF-> no device / open MISO line.0x00-> wrong CS or wrong register address.- Random values → incorrect SPI mode or timing.
Conclusion
In this tutorial, we explored how SPI communication works and how to interface an SPI-based device with a microcontroller. We covered the roles of the SPI pins (MOSI, MISO, SCK, and CS), how full-duplex data transfer happens, and why SPI is preferred for high-speed communication. The provided code examples and explanations make it easier to understand how to initialize the SPI peripheral and read or write data reliably.
We also discussed the most common issues you may encounter when working with SPI, such as incorrect wiring, mismatched SPI modes, faulty grounding, or wrong chip-select handling. To help you debug faster, a focused Troubleshooting section outlined the top causes of communication failures and the exact checks you should perform to fix them quickly.
Overall, this guide helps you build a solid foundation in SPI communication, which is essential when working with sensors, displays, memory chips, and many other peripherals. With the concepts and debugging practices covered in this post, you will be able to interface SPI devices more confidently and integrate them into your embedded projects with ease.
Browse More TM4C123G Tutorials
TM4C123G Clock Setup Tutorial – Configure System Clock with PLL
TM4C123G Delay Tutorial – Using SysCtlDelay and SysTick Timer
TM4C123 GPIO Tutorial – Digital Input and Output using Tiva C LaunchPad
TM4C123 GPIO External Interrupts (Using TivaWare in Code Composer Studio)
TM4C123G UART Tutorial (PART 1) – How to Use UART and Virtual COM Port in Tiva C
TM4C123G UART Tutorial (PART 2): Use Interrupt to Receive Data and Control LEDs
I2C in TM4C123G Tiva C – How to Use I2C Peripheral with TivaWare
TM4C123G SPI Project Download
Info
You can help with the development by DONATING Below.
To download the project, click the DOWNLOAD button.
TM4C123G SPI FAQs
0x00 as the Device ID?This usually happens when the SPI lines are not connected correctly or the CS pin is not toggling properly during the transaction.
The ADXL345 supports SPI Mode 3, and most setups work reliably with this mode.
Yes. The ADXL345 supports up to 5 MHz in 4-wire SPI mode. Lower speeds are better for debugging.
Verify grounding, shorten wires if possible, and reduce SPI speed to confirm stability.
No. SPI does not require pull-ups; just ensure clean connections and stable power.








