How to use SPI in LPC2148

This tutorial will cover how to use SPI (Serial Peripheral Interface) with LPC2148. I will only cover the transmit data part, and the receiving will be covered in upcoming tutorials. I am using keil IDE in this tutorial and the process will remain same for other ARM 7 devices too.

SPI uses 4 pins to communicate between the master and the slave device. The pins used are as follows:

  • SCK -> The Serial Clock
  • MOSI -> Master Out Slave In is to Write the data to the slave
  • MISO -> Master In Slave Out is to Read the data from the slave
  • SSEL -> Slave Select is to Select and Unselect the slave

Registers Used in SPI

Here we will be using the following Registers

  • S0SPCR -> Control Register to setup the SPI
  • S0SPSR -> Status Register to check the status of various things
  • S0SPDR -> Data Register to Write/Receive data
  • S0SPCCR -> Clock Counter Register to set the frequency for the SPI


In order to initialize the SPI, we must configure the pins to be used as the SPI pins. This can be done in the PINSEL registers. Below is the picture of the  PINSEL0  register of the LPC2148

Since I am only transmitting the data, I don’t need the MISO pin, and hence I only need to setup 3 pins.

  • To configure the pin P0.4 as the SCK, we need to write a ‘1’ in the 8th bit
  • To configure the pin P0.6 as the MOSI, we need to write a ‘1‘ in the 12th bit
  • Pin P0.7 is used to select the Slave, so we will just leave it as the GPIO pin
PINSEL0 |= (1<<8)|(1<<12);  // P0.4 = SCK, P0.6 = MOSI
IODIR0 |= (1<<7);  // P0.7 (SSEL) is output

The steps to set up the SPI are provided in the reference manual of LPC2148

In the above picture, the first 2 steps corresponds to setting up the SPI, and we will follow them. Let’s take a look at the  SPI CLOCK COUNTER REGISTER 

Clock Counter Register is responsible for setting up the SPI frequency. The value here must be an even number greater than or equal to 8. Since I always keep the PCLK at 60 MHz, the following is a way to setup the desired frequency for the SPI

S0SPCCR = (60000000/freq);

And finally we will check out the  SPI CONTROL REGISTER 

In the SPI Control Register, I will use the following setup

  • BitEnable (bit 2) = 0 –> SPI will send and receive 8 bits per transfer
  • CPHA (bit 3) and CPOL (bit 4) = 0 –> SPI MODE 0, SCK is active HIGH
  • MSTR (bit 5) = 1 –> SPI operates in Master Mode
  • LSBF (bit 6) = 0 –> MSB first
  • SPIE (bit 7) = 0 –> No interrupts
  • bits 8-11 are not being used (BitEnable = 0)

With the above configuration, the control register setup is shown below

S0SPCR = (1<<5);  // Master mode, 8 bit data, MSB first, CPOL=0 CPHA=0


Before sending the data to the slave, we have to select the slave first. And to do so, we will pull the SSEL pin (P0.7) to LOW

IOCLR0 |= (1<<7);  // P0.7=0 Slave select

In order to transfer the data to the slave, we need to follow the steps 3 and 4 in the picture above

The following is the picture of the  SPI STATUS REGISTER 

SPIF is the bit 7 of the Status Register, and if this bit is one, it indicates that the data transfer is finished

S0SPDR = data;  // write data 
while (!(S0SPSR & (1<<7)));  //  wait for the SPIF bit to set
  • Here we will transfer by writing the data into the SPI DATA REGISTER
  • And then wait for the SPIF (bit 7) in the STATUS REGISTER to set

After the data transfer is finished, we will Unselect the Slave by pulling the SSEL pin HIGH again

IOSET0 |= (1<<7);  // P0.7=1 Slave unselect

The main function

uint8_t data = 0x01;

int main ()
	PLL_Init ();
	VPBDIV = 0x01;  // PCLK = CCLK = 60 MHz
	Timer_Init (60);  // PCLK = 60 MHz
	SPI_Init (5000000);  // SPI clock 5MHz, PR = 12 (PR>=8 and should be even)
	while (1)
		SPI_Write (data++);
		Delay_ms (1000);  // 1 sec delay
  • SPI is initialised with 5 MHz frequency
  • And I am writing the data every 1 second
  • The data is also incrementing after every write


You can see above the data is transferring every 1 second, and it’s incrementing also. You can watch the video to see the full working

Check out the VIDEO Below

Notify of
1 Comment
Oldest Most Voted
Inline Feedbacks
View all comments