Note that all routines discussed in the following may be downloaded in zipped format.
Introduction.
The MAX518 is a Dual Rail to Rail D/A which uses the Philips I2C 2-Wire protocol. The high five bits of the address are defined by the manufacturer as 01011. The lower two bits are defined by the strapping on terminals AD1 and AD0 on the MAX518. Thus, up to four MAX518s may be accommodated on the same SDA and SCL bus.
A data sheet for the MAX518 is available at
The D/As are 8-bit and use the local 5.0 VDC supply as Vref. Thus, each band corresponds to 5.0 / 256.0. Therefore to ouput a voltage which is half of Vref, the data output to the MAX518 is 128 producing a voltage of 128 * 5.0 / 256.
The D/A outputs are rail to rail. That is, the output will fall to 0.0 and rise to 5.0. Indeed, when outputting 0 and 255 I did measure 0.0 VDC and 4.98 VDC respectively.
The application which gave rise to developing this material was the control of valves where a control voltage in the range of 0.0 to 10.0 corresponds to the valve being fully open to fully closed. Note that the outputs of the MAX518 are limited to the range of 0.0 to 5.0 VDC. However, the outputs might be buffered with an LM324 quad operational amplifier configured as voltage followers with a gain of 2.0. Note that the LM324 will perform down to the negative rail (0.0) but will rise to only V+ - 1.8. However, if powered with +12.0 VDC, the output will rise as high as 10.0.
Note that the following routines use common low level I2C routines which may be used for all manner of devices; 24LC16, 32, 64, 128 and 256 EEPROM, PCF8574 8-bit I/O expander, DS1621 or DS1624 Temperature Sensor, DS1307 or PCF8583 RTC, DS1803 Dual Potentiometer and many others.
Control of the MAX518 consists of addressing the device in the write mode, followed by a command byte, followed by the data. The specific D/A which is addressed is specified in bit 0.
The device may be placed in a power down mode by addressing the device followed by the command byte with the PD bit (bit 3) set to a one. The device may be reset, which I assume sets both D/A outputs to 0.0 by addressing the device followed by the command byte with the RST bit (bit 4) set to a 1. However, I did not test the reset feature.
Progam MAX518_1.Bas
This program outputs a data value of 128 corresponding to a voltage of 2.5 VDC on D/A 0 and a rising sawtooth on D/A 1. After 20 seconds, the MAX518 is placed in the power down mode
' Program MAX518_1.Bas ' ' Illustrates how to use MAX518 Dual D/A. ' ' Program outputs a constant voltage on D/A 0 and a sawtooth on D/A 1 ' for 20 seconds and then puts MAX518 in power down mode. ' ' BX24 MAX518 ' ' RC6 (term 6) ------------------- SDA (term 4) ----- To Other ' RC7 (term 5) ------------------- SCL (term 3) ----- I2C Devices ' ' Note that the slave address is 0101 1 AD1 AD0 where AD1 and AD0 ' correspond to terminals 6 and 5, respectively. In this program ' they are strapped to ground and thus the slave address is 0x58. ' ' The Maxim data sheet indicates that pullup resistors on the SDA ' and SCL leads are not required. That is, they are internal. However, ' I found external 4.7K resistors were neccessary. ' ' In command byte; ' RST (bit 4) set to 1 resets both D/As ' PD (bit 3) set to one for power down ' A0 (bit 0) identifies whether data is for D/A0 or D/A1 ' ' Compile with I2C_BX24.Bas which includes the low level I2C routines. ' ' copyright, Peter H. Anderson, Baltimore, MD, Jan, '00 Public Const SDA_PIN as Byte = 6 ' terminals 5 and 6 Public Const SCL_PIN as Byte = 5 ' Note that constants must be Public as SDA_PIN and SCL_PIN are used ' in I2C_BX24.Bas Sub Main() ' Generate a sawtooth on D/A 1 and a constant value on D/A 0 for 20.0 secs ' and then power down the MAX518 Dim N as Integer Call OpenSerialPort(1, 19200) ' used for debugging Call PutTime(0, 0, 0.0) ' initialize clock Call Max518DtoAOut(0, 0, 128) ' output a constant 2.50 VDC ' on D/A 0 Do ' output sawtooth on D/A 1 For N = 0 to 255 Call Max518DtoAOut(0, 1, CByte(N)) Next Loop Until (Timer > 20.0) ' output for 20 secs Call Max518PowerDown(0) ' and then power down End Sub Sub Max518DtoAOut(ByVal DevAdr as Byte, _ ByVal DANum as Byte, ByVal Dat as Byte) ' DevAdr is AD1, AD0 strapping (0-3), DANum is either 0 or 1, Dat ' is data to be output. Call I2C_start() Call I2C_out_byte(&H58 OR (DevAdr * 2)) ' address the device Call I2C_nack() Call I2C_out_byte(DANum) ' selects D/A. ' Note that PD Bit is set to zero Call I2C_nack() Call I2C_out_byte(Dat) ' D/A data Call I2C_nack() Call I2C_stop() End Sub Sub Max518PowerDown(ByVal DevAdr as Byte) Call I2C_start() Call I2C_out_byte(&H58 OR (DevAdr * 2)) ' address the device Call I2C_nack() Call I2C_out_byte(&H08) ' sets PD bit of command register to one Call I2C_nack() Call I2C_stop() End Sub
Program MAX518_2.Bas
In this routine, the ouputs of four D/As are set to defined voltages. This can easily be expanded to eight D/As (four MAX518s).
These defined voltages are passed in an array which leads to a bit of confusion in that the D/As lend to being defined as 0 through 7, but an array can only be passed by reference if its lowest element is one. Thus, the array is refered to as elements 1 through 8 which correspond to D/As 0 though 7.
Thus, the specific MAX518 is determined as (N-1)\2 and the D/A on the device as (N-1) MOD 2.
' Program MAX518_2.C ' ' Illustrates how to use up to four MAX518 Dual D/A so as to realize ' up to 8 D/A outputs. ' ' Program sets four outputs (two MAX518s) to constant values. ' ' BX24 MAX518 ' ' RC6 (term 6) ------------------- SDA (term 4) ----- To Other ' RC7 (term 5) ------------------- SCL (term 3) ----- I2C Devices ' ' Note that the slave address is 0101 1 AD1 AD0 where AD1 and AD0 ' correspond to terminals 6 and 5, respectively. In this program it is ' assumed that one MAX518 is strapped for 00 and the second for 01. ' ' In command byte; ' RST (bit 4) set to 1 resets both D/As ' PD (bit 3) set to one for power down ' A0 (bit 0) identifies whether data is for D/A0 or D/A1 ' ' Compile with I2C_BX24.Bas which includes the low level I2C routines. ' ' copyright, Peter H. Anderson, Baltimore, MD, Jan, '00 Public Const SDA_PIN as Byte = 6 ' terminals 5 and 6 Public Const SCL_PIN as Byte = 5 ' Note that constants must be Public as SDA_PIN and SCL_PIN are used ' in I2C_BX24.Bas Sub Main() Dim OutputVoltages(1 to 4) as Single ' set voltage outputs OutputVoltages(1) = 5.00 ' note that this is OUT0 on MAX518 0 OutputVoltages(2) = 3.84 ' OUT1 on MAX518 0 OutputVoltages(3) = 1.02 ' OUT0 on MAX518 1 OutputVoltages(4) = 2.50 ' OUT1 on MAX518 1 ' Call OpenSerialPort(1, 19200) ' used for debugging Call Max518OutputVoltages(OutputVoltages, 4) ' output the four voltages End Sub Sub Max518OutputVoltages(ByRef OutputVoltages() as Single, _ ByVal NumDtoAs as Integer) Dim N as Integer, DevAdr as Byte, DANum as Byte, Dat as Byte Dim BandSize as Single BandSize = 5.0 / 256.0 ' this could alternatively be a constant For N = 1 to NumDtoAs Dat = CByte(OutputVoltages(N) / BandSize) ' compute D/A val DevAdr = CByte((N-1)\2) ' determine adr of MAX518 DANum = CByte((N-1) MOD 2) ' which D/A on that MAX518 Call Max518DtoAOut(DevAdr, DANum, Dat) Next End Sub Sub Max518DtoAOut(ByVal DevAdr as Byte, _ ByVal DANum as Byte, ByVal Dat as Byte) ' DevAdr is AD1, AD0 strapping, DANum is either 0 or 1, Dat is data ' to be output Call I2C_start() Call I2C_out_byte(&H58 OR (DevAdr * 2)) ' address the device Call I2C_nack() Call I2C_out_byte(DANum) ' selects D/A. ' Note that PD Bit is set to zero Call I2C_nack() Call I2C_out_byte(Dat) ' D/A data Call I2C_nack() Call I2C_stop() End Sub