Chris Mabey
/
LTC1865_adc
Example of how to use the LTC1865 2-Channel SPI 16-bit ADC.
Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Fri Jul 15 2022 14:39:49 by 1.7.2