LPC2xxx SPI Master Code Example

Microcontroller Applications
ABSTRACT
This technical note gives an example of how to use the SPI interface
(master mode and interrupt driven) of the Philips Semiconductors
LPC2000 microcontroller family.
Disclaimer
Described applications are for illustrative purposes only. Philips Semiconductors makes
no representation or warranty that such applications will be suitable for the specified use
without further testing or modification.
MACC-06001
LPC2xxx SPI master code example
Author: Paul Seerden
Philips
Semiconductors
2006 January 20
Philips Semiconductors
Technical note
LPC2xxx SPI master code example
MACC-06001
SPI MASTER DEMO
DS1722
The software example below configures the on-chip
LPC2138 SPI block (SPI0) to interface as a master to
a DS1722 digital thermometer. A simplified block diagram of the used hardware is shown in figure 1.
SDI
P0.6 / MOSI
SDO
P0.5 / MISO
P0.4 / SCK
SCLK
The code repeatedly reads the actual temperature in
8-bit mode. This digital 8-bit temperature value is
simply displayed on eight LEDs connected to port
P1.16-23 of the LPC2138.
CE
P0.7
8x
P1.23
The peripheral (VPB) clock is set equal to the system
clock (12 MHz) and SPI bit rate is programmed to 1
Mb/s (SPCCR=12). The driver software is interrupt
driven (VIC channel 0 irq).
LPC213x
Figure 2 and table 1 show the SPI timing parameters
measured in this example and are only indicative.
tCLKH
Fig 1. Simplified block diagram
tCLKL
1
SPICLK
VCC
P1.16
tFall
2
8
tRise
tLDV
MOSI
(output)
tOH
tDVE
Master MSB/LSB out
Fig 2. SPI master timing (CPOL=0)
Table 1: Measured timing characteristics
Symbol
Parameter
Conditions
tCLKH
SPI clock high time
tCLKL
tRise
tFall
tLDV
tDVE
tOH
Typical (measured)
Unit
See figure 2, PCLK = 12 MHz
CCR = 12, SCK = 1MHz
500
ns
See figure 2, PCLK = 12 MHz
CCR = 12, SCK = 1MHz
500
ns
See figure 2
SCK0 and MOSI0
20
ns
See figure 2
SCK0 and MOSI0
20
ns
SPI Leading data valid
See figure 2
560
ns
SPI Data valid from enable
See figure 2
180
ns
SPI Output data hold time
See figure 2
150
ns
SPI clock low time
SPI outputs Rise time
SPI outputs Fall time
Philips Semiconductors
Technical note
LPC2xxx SPI master code example
#include <LPC21xx.H>
// LPC21xx definitions
#define SPI_OK
#define SPI_BUSY
#define SPI_ERROR
0
1
2
// transfer ended No Errors
// transfer busy
// SPI error
static
static
static
static
state;
spiBuf[4];
*msg;
count;
//
//
//
//
unsigned
unsigned
unsigned
unsigned
char
char
char
char
MACC-06001
void SPI_Isr(void) __irq
{
if ((S0SPSR & 0xF8) == 0x80)
{
*msg++ = S0SPDR;
if (--count > 0)
S0SPDR = *msg;
else
state = SPI_OK;
}
else
{
*msg = S0SPDR;
state = SPI_ERROR;
}
S0SPINT = 0x01;
VICVectAddr = 0;
}
State of SPI driver
SPI data buffer
pointer to SPI data buffer
nr of bytes send/received
// read byte from slave
// sent next byte
// transfer completed
// SPI error
// dummy read to clear flags
// reset interrupt flag
// reset VIC
static void DS1722_Write(unsigned char add, unsigned char val)
{
spiBuf[0] = add;
// DS1722 address
spiBuf[1] = val;
msg = spiBuf;
count = 2;
// nr of bytes
state = SPI_BUSY;
// Status of driver
IOSET0 = 0x00000080;
S0SPDR = *msg;
while (state == SPI_BUSY) ;
IOCLR0 = 0x00000080;
//
//
//
//
SS_DS1722 = 1
sent first byte
wait for end of transfer
SS_DS1722 = 0
}
static void SPI_Init(void)
{
VICVectAddr0 = (unsigned int) &SPI_Isr;
VICVectCntl0 = 0x2A;
// Channel0 on Source#10 ... enabled
VICIntEnable |= 0x400;
// 10th bit is the SPI
IODIR0 |= 0x00000080;
IOCLR0
= 0x00000080;
PINSEL0 |= 0x00001500;
// P0.7 defined as SS_DS1722
// SS_DS1722 = 0
// configure SPI0 pins (except SSEL0)
S0SPCCR = 12;
S0SPCR = 0xA8;
// SCK = 1 MHz, counter > 8 and even
// CPHA=1, CPOL=0, master mode, MSB first, interrupt enabled
}
int main (void)
{
IODIR1 |= 0x00FF0000;
IOCLR1 = 0x00FF0000;
SPI_Init();
DS1722_Write(0x80,0xE0);
// P1.16-23 defined as output
// All LEDs off
// initialize DS1722
while(1)
{
DS1722_Write(0x02,0x02);
// read temperature
if (state == SPI_OK)
// no error ?
{
IOCLR1 = 0x00FF0000;
IOSET1 = spiBuf[1] << 16;
}
}
}