Example of how to use the LTC1865 2-Channel SPI 16-bit ADC.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /***************************************************************************************/
00002 /*                                                                                     */
00003 /* Program:         LTC1865_ADC_Example                                                */
00004 /* Author:          Chris Mabey                                                        */
00005 /* Date:            November 2016                                                      */
00006 /* Target Platform: mbed                                                               */
00007 /* Description:     External LTC1865 16-bit ADC example                                */
00008 /* Version:         1v0                                                                */
00009 /*                                                                                     */
00010 /* Notes: After struggling with the internal LPC1768 ADC noise I decided to use an     */
00011 /*        external ADC. My requirements were 2 channels at 16-bit resolution, single   */
00012 /*        5V supply, input range 0 to 5V (Vcc), high sample rate and using a fast SPI  */
00013 /*        clock frequency.                                                             */
00014 /*        I'm very happy with the LTC1855 and as I've received help from the mbed      */
00015 /*        community thought I'd share an example that may be of help to others.        */
00016 /*                                                                                     */
00017 /*        LTC1865 Datasheet: http://cds.linear.com/docs/en/datasheet/18645fb.pdf       */
00018 /*                                                                                     */
00019 /*        Please don't criticise my coding style, it's 'old school' from when I worked */
00020 /*        with Intel iRMX and the PL/M language 30 or so years ago!                    */
00021 /*                                                                                     */
00022 /***************************************************************************************/
00023 
00024 #include "mbed.h"
00025 
00026 /* ADC (SPI) */
00027 /* ========= */
00028 #define SPI_MOSI_PIN      p5  /* SPI Bus Master Out/Slave In          */
00029 #define SPI_MISO_PIN      p6  /* SPI Bus Master In/Slave Out          */
00030 #define SPI_SCK_PIN       p7  /* SPI Bus Master Clock                 */
00031 #define SPI_CS_ADC_PIN    p8  /* SPI ADC Slave Select                 */
00032 
00033 /* The LTC1864 ADC has two input channels */
00034 #define ADC_CHANNEL_0 0
00035 #define ADC_CHANNEL_1 1
00036 
00037 /* The LTC1864 conversion cycle begins with the rising edge of CONV.  */
00038 /* After a period equal to tCONV, the conversion is finished.         */
00039 /* The maximum conversion time is 3.2uS, so wait for 4uS as wait_us() */
00040 /* accepts an integer value.                                          */ 
00041 #define ADC_CONVERSION_TIME 4
00042 
00043 #define LOW  0
00044 #define HIGH 1
00045 
00046 
00047 /**********************************************************/
00048 /*                                                        */
00049 /* MBED I/O Ports                                         */
00050 /*                                                        */
00051 /**********************************************************/
00052 DigitalOut ADCcsPin(SPI_CS_ADC_PIN);
00053 SPI spi(SPI_MOSI_PIN, SPI_MISO_PIN, SPI_SCK_PIN);
00054 
00055 
00056 /* Holds the last ADC conversion channel */
00057 unsigned char previousADCchannel;
00058 
00059 
00060 /***********************************************************/
00061 /*                                                         */
00062 /* Read_External_ADC                                       */
00063 /*                                                         */
00064 /* Function: Read the latest value from the specified      */
00065 /*           channel of the external LTC1865 ADC.          */
00066 /*                                                         */
00067 /*           Performance: Takes around 15.5uS to execute   */
00068 /*           using 20MHz SPI clock without dummy read for  */
00069 /*           switching channels (measured on NUCLEO-L476RG)*/
00070 /*                                                         */
00071 /* Input Parameters:                                       */
00072 /* unsigned char: the ADC channel (ADC_LP_CHANNEL or       */
00073 /*                ADC_GP_CHANNEL)                          */
00074 /*                                                         */
00075 /* Output Parameters:                                      */
00076 /* unsigned int: the ADC value (range 0 to 65535)          */
00077 /*                                                         */
00078 /***********************************************************/
00079 unsigned int Read_External_ADC(unsigned char channel)
00080 {
00081     unsigned int adcVal;
00082 
00083     /* If changing channel a dummy read is required as the */
00084     /* two bits of the input word (SDI) assign the MUX     */
00085     /* configuration for the next requested conversion.    */
00086     /*                       ----                          */
00087     if (channel != previousADCchannel)
00088     {  
00089         /* The LTC1865 conversion cycle begins with the rising edge of CONV */
00090         ADCcsPin = HIGH;
00091 
00092         /* Wait for the conversion to complete */
00093         wait_us(ADC_CONVERSION_TIME); /* Note: Blocks interrupts! */
00094 
00095         /* Enable the Serial Data Out to allow the data to be shifted out by taking CONV low */
00096         ADCcsPin = LOW;
00097         
00098         /* Send command and read previous selected ADC channel value, whilst */
00099         /* telling the ADC the next conversion is for the new channel        */
00100         adcVal = spi.write(0x8000 | (((unsigned int)channel) << 14)); /* Transmit the Mode (Single-ended MUX Mode),     */
00101                                                                       /* the channel and receive the sixteen bit result */
00102     
00103         /* Save the new ADC channel */
00104         previousADCchannel = channel;        
00105     }
00106     /* endif */
00107 
00108     /* The LTC1865 conversion cycle begins with the rising edge of CONV */
00109     ADCcsPin = HIGH;
00110 
00111     /* Wait for the conversion to complete */
00112     wait_us(ADC_CONVERSION_TIME);
00113 
00114     /* Enable the Serial Data Out to allow the data to be shifted out by taking CONV low */
00115     ADCcsPin = LOW;
00116 
00117     /* Send command and read previous selected ADC channel value, whilst */        
00118     /* telling the ADC the next conversion is for the same channel       */
00119     adcVal = spi.write(0x8000 | (((unsigned int)channel) << 14)); /* Transmit the Mode (Single-ended MUX Mode),     */
00120                                                                   /* the channel and receive the sixteen bit result */
00121 
00122     return(adcVal);  /* Return the 16-bit ADC value */
00123 }
00124 
00125 
00126 int main()
00127 {
00128     /**********************************************************/
00129     /*                                                        */
00130     /* Initialise the SPI interface to the external ADC       */
00131     /*                                                        */
00132     /**********************************************************/
00133     spi.format(16,1);        /* 16-bit data, Mode 1 */
00134     spi.frequency(20000000); /* 20MHz clock rate    */
00135 
00136     ADCcsPin = LOW; /* Deselect the ADC by setting chip select low */
00137 
00138     /* Perform a dummy read to initialise the ADC conversion channel to ADC_CHANNEL_0 */
00139     Read_External_ADC(ADC_CHANNEL_0);
00140 
00141     printf("\n\rLTC1865 External ADC Example\n\r");
00142 
00143     while(1)
00144     {
00145         printf("Channel 0 = %5u   ", Read_External_ADC(ADC_CHANNEL_0));
00146 
00147         wait(0.5f); /* 0.5s */
00148 
00149         printf("Channel 1 = %5u\n\r", Read_External_ADC(ADC_CHANNEL_1));        
00150     }
00151     /* end while */
00152 }
00153