The Stellaris DAC7571 tutorial will show how a LM3S6965 evaluation board is interfaced to the DAC7571 using the I2C bus.
The DAC7571 is manufactured by Texas Instruments, and has the following key features which make it ideal for experimenting with:
- 6 pins IC in a SOT23 package
- 12 bit buffered voltage output, therefore the DAC has a range of 2 to the power of 12 = 4096
- I2C interface
- Supply voltage from +2.7V to +5.5V
The DAC comes in an SMT package, TI supply SMT prototyping boards which allow the DAC to then give the footprint of a standard 8pin DIP package. This method is useful as it allows the DAC to be used in various other projects and easily reused. The image below shows the completed prototyping board, fitted to small veroboard used for testing the I2C bus.
This is not a tutorial on I2C but it is necessary to give a brief decsription of the protocal, as these leads into explaining how to communicate with the DAC7571 correctly. The datasheet for the DAC7571 can be downloaded from here I2C is a 2 wire protocol using a data wire (SDA) and a clock wire (SCL). There is a Master device which initiates contact with up to 127 Slave devices on a single bus, each slave has an individual 7 bit address. There can be more than one Master on a bus, but this is beyond the scope of this project, so will not be covered here. For this project the master will be the LM3S6965 and the DAC is the slave (the DAC can only be a slave). There is a certain sequence of events for any data bus, which is covered briefly in the next few lines.
- The SDA and SCL lines when in idle state naturally sit high or logic level 1. The master initiates contact on the bus by pulling the SDA line low, when the SCL line is still high, this indicates to any slaves on the bus serial data transfer has started.
- After this the master generates the serial clock on the SCL line.
- The master then sends out an address byte of the slave it wants to communicate with.
- After sending out the address byte the master generates a ninth SCL pulse, then monitors the SDA line during the high period of this ninth clock cycle.
- The SDA line should now be pulled low by the receiving slave during the high period of the ninth clock cycle, this is an acknowledge signal and lets the master know the address sent successfully matches a slave on the bus. Further data bytes can be sent to or read from a slave by the master, using the a similar method to the steps explained.
The I2C protocol has fairly strict timing requirements, so it’s important to note while the bit stream is generated, the master ensures the timing for valid data.
The DAC7571 datasheet contains a great deal of information about interfacing, and all the necessary information regarding the I2C interface can be found on page 13 to 18. It is only possible to have 2 of the DAC7571 devices on one I2C bus, this is due to the way the slave address is set on the DAC. Pin 6 is called A0, pending how this pin is connected determines the address of the DAC, if the pin is connected to Gnd the slave address is 1001100 (0x4C), if A0 is connected to Vcc then the slave address will be 1001110 (0x4E). A0 for this project was connected to Gnd. Now that the address is taken care of, it was necessary to understand how to send data to the DAC. The image below is taken from page 17 of the datasheet.
The Stellaris has a library specifically written for the I2C protocol contained within the TI software bundle StellarisWare, this makes interfacing with devices which support I2C and many other protocals much easier, compared to lower end microcontrollers like the MSP430G series. An essential read is the Stellaris Peripheral Driver Library in PDF format, which can be downloaded from here. There are sections dedicated to all the driver libraries, this document was referenced heavily for this project. In order to use I2C on the Stellaris, the peripheral must be enabled (there are two I2C ports on the Stellaris I2C0 and I2C1). Then the port the peripheral is on must also be enabled, followed by the individual pins on that port. The following functions below carry out the port enabling.
// Turn on I2C0 and Reset to a known state SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0); // Configure the PortB pins for I2C0 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); // Enable Port B of GPIO // SCL 0 Bit 2 Output // SDA 0 Bit 3 Output GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3);
Once the ports have been enabled the I2C needs to be initialised, via the following function which also sets the speed of the bus (false indicates 100kHZ).
I2CMasterInitExpClk(I2C0_MASTER_BASE, SysCtlClockGet(), false);
After this the microcontroller can begin it’s duty as master, the code below can be used to test the DAC. Further code was written using a function with all the code below placed inside, then the function was simply passed parameter values to set the DAC output voltage.
// DAC address = 1001100 therefore Hex value = 0x4C I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, 0x4C, false); // Hex value first 4 bits used for CTRL data, last 4 bits forms //the first 4 bits of the 12 bit word to determine DAC voltage I2CMasterDataPut(I2C_MASTER_BASE, 0x05); I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START); while (I2CMasterBusy(I2C0_MASTER_BASE)); // Hex value forms the last 8 bits of the 12 bit word to determine //DAC voltage I2CMasterDataPut(I2C_MASTER_BASE, 0xfC); I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_CONT); while (I2CMasterBusy(I2C0_MASTER_BASE)); I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_STOP); while (I2CMasterBusy(I2C0_MASTER_BASE));
The DAC supply voltage is 3.3V, therefore 3.3V/4096 = 806μV per step, so a value of 1532 for example should be as follows 1532*806μV = 1.235V When the above code was written into a test program, 1.24V was observed on the multimeter. The Hex values of 0x05 as the first byte and 0xFC on the second byte equate to a 12 bit binary value of 010111111100, which is equal to 1532 in decimal.
The link below contains the zip file with the complete C code