The MAX500 is an 8 bit DAC that can output to higher voltages (~12V). The chip has 4 onboard DAC channels.

Dependencies:   DAC

Files at this revision

API Documentation at this revision

Comitter:
JimmyTheHack
Date:
Tue Jul 03 03:22:59 2012 +0000
Child:
1:90b59ae53d25
Commit message:
updated DAC_SPI library to have virtual select function

Changed in this revision

DAC_SPI/DAC_SPI.cpp Show annotated file Show diff for this revision Revisions of this file
DAC_SPI/DAC_SPI.h Show annotated file Show diff for this revision Revisions of this file
MAX500.cpp Show annotated file Show diff for this revision Revisions of this file
MAX500.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DAC_SPI/DAC_SPI.cpp	Tue Jul 03 03:22:59 2012 +0000
@@ -0,0 +1,39 @@
+#ifndef DAC_SPI_CPP
+#define DAC_SPI_CPP
+
+#include "DAC_SPI.h"
+/*SPI Channels */
+                          //since we only have two SPI channels, which must be shared, define them here.  
+SPI SPI_A(p5, NC, p7);    //If using with other serial devices, can pass a pointer to the serial channel.
+SPI SPI_B(p11, NC, p13);
+
+/*Initialize DAC */
+DAC_SPI::DAC_SPI(int SPIchannelNum, PinName _CS, PinName _LDAC) : CS(_CS), LDAC(_LDAC){  
+    if (SPIchannelNum ==1){
+        DACspi = &SPI_B;
+    }  
+    else{
+        DACspi = &SPI_A;
+    }
+    messageBits(16);
+}
+
+/** Manually change the SPI frequency 
+* Must be a value supported by the mbed and DAC
+*/
+void DAC_SPI::frequency(int freq){
+    (*DACspi).frequency(freq);    
+}
+
+
+//specify the number of bits used in message packets to the DAC.
+void DAC_SPI::messageBits(int bits){
+    (*DACspi).format(bits,0);
+}
+
+//select a DACnum for use with chips with multiple onboard DACs.
+void DAC_SPI::select(char DACnum){
+    DACselect=DACnum;
+}
+
+#endif //DAC_SPI_CPP
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DAC_SPI/DAC_SPI.h	Tue Jul 03 03:22:59 2012 +0000
@@ -0,0 +1,33 @@
+#ifndef DAC_SPI_H
+#define DAC_SPI_H
+#include "mbed.h"
+
+/* a basic parent library for use with DACs controlled via SPI.  Individual hardware implementations will need their own libraries.
+This provides basic initialization of common pins and provides a serial channel.   Doesn't provide a lot of added functionality, but serves as an interface for the SPI library.
+*/
+class DAC_SPI
+{
+    public:
+    DAC_SPI(int SPIchannelNum, PinName CS,  PinName LDAC);
+    virtual void select(char DACvalue); //choose the active DAC
+    virtual void write(int DACvalue) =0; //write a value to the Digital Analog Converter    
+    virtual void write_mV(int millivolts) =0; //write a value to the Digital Analog Converter specified in mV (may require appropriate scaling factor)
+    
+    /** Manually change the SPI frequency 
+    * @param freq Desired frequency in hertz: must be a value supported by both the mbed and DAC.  The MCP4922 supports frequencies to 20MHz.
+    */
+    void frequency(int freq);
+    //set the number of bits for DAC
+    void messageBits(int bits);
+    //DigitalOut SCK;
+    /** The currently selected DAC channel.  0 for DAC A, 1 for DAC B, etc*/
+    char DACselect;
+    DigitalOut CS;  //serial chip select pin
+    DigitalOut LDAC; //synchronize pin to update both DACs together    
+    SPI * DACspi;  //SPI channel.  0 for p5-p7, 1 for p11-p13
+};
+
+extern SPI SPI_A;  //channel A SPI (pins 5,7)
+extern SPI SPI_B;  //channel B SPI (pins 11,13)
+
+#endif //DAC_H
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MAX500.cpp	Tue Jul 03 03:22:59 2012 +0000
@@ -0,0 +1,61 @@
+#include "MAX500.h"
+
+MAX500::MAX500(int SPIchannelNum, PinName _LOAD, PinName _LDAC) : DAC_SPI(SPIchannelNum, _LOAD, _LDAC){   //We use the 3 wire serial interface, since the timing is more standardized. 
+    (*DACspi).format(10,2);  //messages use a 10 bit word, and read data on the falling edge with the clock defaulting to HIGH.
+    frequency(5000000);  //set default frequency to 5MHz since unstated   
+    autoUpdate=1;
+    VrefAB=5000; //assume a 5V reference voltage for use with write_mv().  This value can be configured;
+    VrefC=5000; //assume a 5V reference voltage for use with write_mv().  This value can be configured;
+    VrefD=5000; //assume a 5V reference voltage for use with write_mv().  This value can be configured;
+    CS=1; //CS is our LOAD pin
+}
+
+void MAX500::select(char DACnum){
+    DACselect=DACnum & 0x03; //choose between DAC A , B, C or D
+}
+
+void MAX500::write_mV(int mV){
+    int Vref;
+    if (DACselect==0 || DACselect ==1){
+        Vref=VrefAB;
+    }
+    else if (DACselect ==2) {
+        Vref=VrefC;
+    }
+    else{
+        Vref=VrefD;
+    }
+    int DACvalue= mV* 255/Vref ; //scale voltage to a DAC value.
+    write(DACvalue);
+}
+
+void MAX500::write(int value){
+    //valid input values are 0 - 255.   255 should scale to Vref.   
+    //All serial commands are 10 bit words.   The highest 2 bits are control bits, while the last 8 are the data bits for the 8-bit DAC MAX500.
+
+    //bit 9-8: Selection bits for DAC
+    //bit 7-0: Data bits for the DAC.
+    
+    if (value > 0x0FF){
+        value = 0x0FF;  //any out of range values will be truncated to our max value
+    }    
+    value=value & 0x0FF; //limit our value to 8 bits.
+    
+    //SCK=0;  //set the clock low.    
+    LDAC=1;
+    CS=1; //enable the chip to recieve data    
+    
+    int message= (DACselect<<8)+value;
+    (*DACspi).write(message);
+    //wait_us(5);
+    CS=0;  //signal end of message.   The data will be loaded into the internal registers.
+    //wait_us(5);
+    CS=1;
+    if(autoUpdate){ LDAC=0;} //trigger the update of the output voltage.
+      
+}
+void MAX500::update(){
+    //triggers the DAC to update output on command.   Useful if we wish to synchronize the DAC output value with another event.
+    LDAC=0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MAX500.h	Tue Jul 03 03:22:59 2012 +0000
@@ -0,0 +1,78 @@
+#ifndef MAX500_H
+#define MAX500_H
+
+#include "DAC_SPI.h"
+
+/** 
+* The MAX500 is a quad package 8 bit DAC.  We should be able to produce four analog output voltages up to the externally wired voltage references (VrefA/B, VrefC, VrefD).
+ The maximum voltage output is recommended to be about 4V less than the power supply voltage, although getting a 12V output from a 15V power supply is possible.  
+*
+* Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX500.pdf
+*
+* We use the "3-wire" serial interface since it seems to be more compatible with the mbed Serial library timing than the "2-wire" interface.  The 2-wire interface uses a somewhat non-standard timing scheme
+* and may require custom code support.
+*
+* All serial commands are 10 bit words.   The highest 2 bits are control bits, while the last 8 are the data bits for the 8-bit DAC MAX500.   
+*    + bit 13-12: choose which DAC to use
+*    + bit 11-0: Data bits for the DAC.
+*/
+class MAX500: public DAC_SPI
+{    
+    public:
+    
+    /** Initializes the MAX 500 DAC 
+    *
+    * @param SPIchannelNum An int representing the SPI channel used by this DAC
+    * channel 0 for p5 and p7
+    * channel 1 for p11 and p13
+    * @param LOAD The chip select pin (CS) used to identify the device
+    * @param LDAC The LDAC pin used to synchronize updates of multiple devices
+    */
+    MAX500(int SPIchannelNum, PinName LOAD,  PinName LDAC);
+    
+    /** Writes a value between 0-255 to the currently selected DAC output 
+    * @param DACvalue a value from 0-255 to write to the DAC register
+    */
+    virtual void write(int DACvalue);
+    
+    /** Writes a value in mV to the DAC outputs.
+    * The output will only be accurate if Vref is set to the appropriate voltage reference scaling factor. 
+    * @param millivolts The desired voltage output in millivolts
+    */
+    virtual void write_mV(int millivolts); 
+    
+    /** If automatic updating is disabled, this will update the DAC output on command */
+    void update();    
+    
+    /** select whether to use DAC A or DAC B. 
+    * @param DACnum 0 to modify DAC A, 1 to modify DAC B
+    */
+    virtual void select(char DACnum); 
+    
+    /** If true, the DAC output will update as soon as the output value is modified.  If false, it will wait for an update command*/
+    bool autoUpdate;
+    
+    /** The currently selected DAC channel.  0 for DAC A, 1 for DAC B*/
+    char DACselect;
+    
+    /** The output scaling factor in mV for channels A and B.
+    * The voltage wired to Vref will be used as the scaling factor which the DAC will use in producing the output voltage.
+    * If using the write_mV function, it is important that Vref is properly set.  This library uses 5000mV by default.
+    */
+    int VrefAB;
+    /** The output scaling factor in mV for channel C.
+    * The voltage wired to Vref will be used as the scaling factor which the DAC will use in producing the output voltage.
+    * If using the write_mV function, it is important that Vref is properly set.  This library uses 5000mV by default.
+    */
+    int VrefC;
+    /** The output scaling factor in mV for channel D.
+    * The voltage wired to Vref will be used as the scaling factor which the DAC will use in producing the output voltage.
+    * If using the write_mV function, it is important that Vref is properly set.  This library uses 5000mV by default.
+    */    
+    int VrefD;
+    
+    
+    
+};
+
+#endif //MAX500_H
\ No newline at end of file