Overview
The Serial Peripheral Interface (SPI) is a high speed serial communication that commonly use three wires, serial clock, serial data and enable (master transmit only). Most of modern micro-controller has this serial communication interface. It is useful for board to board or to device communication due to wiring complexity compare to parallel port data transmission.
SPI is popular among graphical display, Flash memory, I/O expansion chip, SRAM, EEPROM, real time clock chip etc. Its transmission and reception speed could reach up to several Mbits/s. These are some example of SPI devices:
- DS3234 Real Time Clock
- Nokia 5510 graphical LCD module
- MCP23S17 I/O Expansion Chip
- SN74HC595N Serial In Parallel Out Shift Registers
- ILI9341/ST7785 240x320 TFT Display
- ST7735 128x160 TFT Display
- W25Q64JVSSIQ Flash Memory Chip
- SD MMC Card etc.
![]() |
| W25Q64JVSSIQ |
![]() |
| ILI9341/ST7785 240x320 TFT Display |
Some earlier MCU doesn't have an SPI module inside for instance the AT89S52 or PIC16F84A. However the programmer could emulate a software SPI by using the bit-banging technique. This method is popular but it yield a lower speed data transmission and reception.
Typically a system operation contains a master MCU that transmit and receive data from its connected SPI slave devices.
| Single master to single slave: basic SPI wiring |
The pin names of the SPI module in the AVR micro-controller are different from other MCU such as PIC. These pins are:
| Abbr. | Name | Description |
|---|---|---|
SS | Slave Select | Active-low chip select signal from master to enable communication with a specific slave device |
SCLK | Serial Clock | Clock signal from master |
MOSI | Master Out Slave In | Serial data output from master |
MISO | Master In Slave Out | Serial data output from slave |
The master MCU must select any connected SPI slave device via its slave select (SS) pin. One slave device has a unique SS pin. So multiple slave devices have many SS pins.
| A typical hardware setup using two shift registers to form an inter-chip circular buffer |
Its clock polarity is commonly positive (low to high). Somes device use a negative (high to low) clock polarity.
However its clock polarity and phase are configured by user software that requires an understanding of technical detail of an MCU (Dedicated SPI Module).
The master MCU can communicates with many different SPI slave devices (Multidrop SPI bus) on a single bus using additional SS pins.
| Multidrop SPI bus |
If multiple SPI slave devices with the same type connect to a single SPI bus we can use the Daisy chain configuration. For instance the SN74HC595N or SN74HC164 serial in parallel out shift registers.
| Daisy chain configuration |
It is used for expanding a number of output ports for instance driving a dot matrix display.
Currently there are a lot of newer method of SPI data transmission that is precise and high speed.
ATMega644P Serial Peripheral Interface
The SPI module of the ATMega644P has the following features:
• Full-duplex, Three-wire Synchronous Data Transfer
• Master or Slave Operation
• LSB First or MSB First Data Transfer
• Seven Programmable Bit Rates
• End of Transmission Interrupt Flag
• Write Collision Flag Protection
• Wake-up from Idle Mode
• Double Speed (CK/2) Master SPI Mode
Its operation mode and speed are configured in user program via its relevant special function registers.
| SPI Block Diagram |
Its clock generator is divided form the MCU clock up to CK/2. Data is shifted in and out using its internal 8-bit shift register at each clock cycle of the SPI clock generator. It also generate interrupt flag whenever the shift registers is empty.
| SPI Master-slave Interconnection |
These are its relevant registers:
- SPCR – SPI Control Register
| SPCR – SPI Control Register |
- SPSR – SPI Status Register
| SPSR – SPI Status Register |
- SPDR – SPI Data Register
| SPDR – SPI Data Register |
The ATMega644P may operate in master transmit only, slave receive only or even full duplex (synchronous data transfer) depending on these registers. For more detail please see the device datasheet.
ATMega644P SPI Interfacing and Programming
We can configure the SPI module of the ATMega644P to operates in a specific mode depends on the worked application.
SPI Master Transmit Mode
An SPI master transmits only is common. There are many SPI slave device that only need data reception such as the SN74HC595N or 74HC164 shift register chips.
![]() |
| SN74HC595N and SN74HC164N Shift Registers |
These chips is very popular due to its availability, low cost, ease of control etc. The SN74HC595N is commonly found in output expanding application such as relays driving, LED driving especially the dot matrix display driver.
![]() |
| SN74HC595N Pin Diagram |
In this example the ATMega644P operate in master mode to transmit data to the SN74HC595N shifter register chip. The output port of this chip can connects to LED, 7-Segment displays or even a character LCD.
There are sample code of using the SPI transmit in device data sheet in both Assembly and C program.
| Sample Code |
LED Driving
I have a DIY single chip SN74HC595N LED module that is very easy to make. However we can install them together on a single breadboard.
![]() |
| A completed Soldering Board |
![]() |
| Copper Side |
For more information about this DIY PCB see this post.
The program is very simple.
- /*
- * 12-spi_74hc595_led.c
- *
- * Created: 2/14/2026 6:57:01 PM
- * Author : Admin
- */
- #include <avr/io.h>
- #include <util/delay.h>
- #define F_CPU 16000000UL
- #define DDR_SPI DDRB
- #define PRT_SPI PORTB
- #define DD_MOSI 5
- #define DD_SCK 7
- #define DD_SS 4
- void SPI_MasterInit(void)
- {
- /* Set MOSI and SCK output, all others input */
- DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS);
- /* Enable SPI, Master, set clock rate fck/16 */
- SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
- }
- void SPI_MasterTransmit(char cData)
- {
- /* Start transmission */
- SPDR = cData;
- /* Wait for transmission complete */
- while(!(SPSR & (1<<SPIF)))
- ;
- }
- int main(void)
- {
- /* Replace with your application code */
- SPI_MasterInit();
- char i=0;
- while (1)
- {
- SPI_MasterTransmit(1<<i);
- PRT_SPI&=~(1<<DD_SS);
- _delay_us(100);
- PRT_SPI=(1<<DD_SS);
- _delay_us(100);
- i++;
- if(i>8) i=0;
- _delay_ms(100);
- }
- }
Schematic:
| SN74HC595N LED Driving |
AVR Experiment Board:
| SN74HC595N LED Driving |
| SN74HC595N LED Driving |
| SN74HC595N LED Driving |
The program just shift each bits of the SN74HC595N output port.






No comments:
Post a Comment