Oliver Broad
/
MAX110
Simple readout code for MAX110/111 14-bit ADC
main.cpp
- Committer:
- oliverb
- Date:
- 2012-07-12
- Revision:
- 2:41e59824652f
- Parent:
- 1:46c26c1de51f
File content as of revision 2:41e59824652f:
#include "mbed.h" // Use SPI port to control MAX110/111 Analog to digital converter // MAX110 is split-supply device, MAX111 single supply. // Devices require 5v for full performance, may be testable at 3.3v // // // Conversion is SLOW. // // Data is clocked in on rising edges so SPI 0,0 or SPI 1,1. Serial pc(USBTX, USBRX); // tx, rx SPI spi(p5, p6, p7); // mosi, miso, sclk DigitalOut max_cs(p22); DigitalIn max_busy(p23); //module libmax110 // //const #define max_12bit 0x9200 #define max_13bit 0x8600 #define max_14bit 0x8c00 #define max_div4 0x0100 #define max_div2 0x0080 #define max_chan1 0x0000 #define max_chan2 0x0010 #define max_full 0x000c //#define max_gain 0b0000000000001000 #define max_ofs 0x0004 // // procedure max_init(dim mode as word, dim byref port as //byte, dim cs,bf as byte) // // mode must be one of max_12bit, max_13bit, max_14bit // mode may be modified by "or-ing" with max_div2 or max_div4 to set clock divider // mode may be modified by "or-ing" with max_chan1 or //max_chan2 to set input channel // mode may be modified by "or-ing" with a calibration type //max_full,max_ofs // // port is the port the busy and cs pins are connected to (doesn't have to be PORTC) // cs is the bit number for the chip select pin // bf is the bit number for the busy flag pin // // function max_read(dim byref data as integer) as boolean // // notes returns true if a value was read, immediately restarts converter // otherwise returns false // // result is integer, valid results are from -16384 through 16383. // values beyond this are overrange // // // MAX110/111 Control register bits // 15 !NOOP Set to 1 for action, 0 for pass-through // 14 NU, set to 0 // 13 NU, set to 0 // CONV 4,3,2,1 // 12 CONV4 1 0 0 1 20ms // 11 CONV3 0 0 1 1 40ms // 10 CONV2 0 1 1 0 160ms // 9 CONV1 0 0 0 0 200ms SPECIAL // SPECIAL = NO INTERNAL GAIN CALIBRATION, FIX IN SOFTWARE // 8 DV4 1=DIVIDE XCLK BY 4 // 7 DV2 1=DIVIDE XCLK BY 2 // // 6 NU, set to 0 // 5 NU, set to 0 // 4 CHS 0:CHANNEL 1 1:CHANNEL2 // // CAL NUL FUNCTION // 1 1 INTERNAL ZERO (PERFORM FIRST) // 3 GAIN CAL 1 0 INTERNAL GAIN (NEXT) // 2 OFFSET NUL 0 1 INPUT NUL (LAST) // 0 0 NORMAL CONVERT // 1 PDX POWER DOWN OSC // 0 PD POWER DOWN ADC // // unsigned int max_mode; // void max_setup(unsigned int mmode) { max_mode=mmode; max_cs=0; spi.write(0); spi.write(0); max_cs=1; // not sure why the above step helps but it seems to improve restarts after random // reset max_cs=0; spi.write((max_mode & 0xff00) >> 8); spi.write(max_mode & 0xff); max_cs=1; } int max_read(int *data) { if (max_busy) { if (max_mode & 0x0c) { max_mode = max_mode - 0x04; max_cs=0; spi.write((max_mode & 0xff00) >> 8); spi.write(max_mode & 0xff); max_cs=1; wait(0.1); return(false); } else { short t; max_cs=0; t =spi.write((max_mode & 0xff00) >> 8); t =spi.write(max_mode & 0xff) | (t<<8); *data= (int) t; max_cs=1; return(true); } } else { return(false); } } int main() { spi.format(8,0); spi.frequency(100000); max_cs=1; // pc.printf("Start converter\r\n"); max_setup(max_14bit | max_full); while(1) { int val; val=0; if (max_read(&val)) { pc.printf("Readout: %d \r\n",val); // optional: force a recalibrate // max_setup(max_14bit | max_full); } } }