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
SET UP 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
HOW TO TRANSFER DATA
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
Result
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
100%
Recent Posts
- Interface WS2812 with STM32 April 16, 2021
- PWM with DMA in STM32 April 8, 2021
- Control Stepper motor using Rotary Angle Sensor March 21, 2021
- External Interrupt using Registers March 17, 2021
- STM32F103 Clock Setup using Registers March 3, 2021
- STM32 I2C Configuration using Registers February 26, 2021