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; } } }