The PIC has 13 analog inputs, but no analog outputs. If you need an analog output there are at least three ways to get it:
- Use a PWM output. The duty cycle range of 0% to 100% implies an average output voltage between 0V and 5V. You can use an RC low-pass filter to smooth the output. The smoother you make it, the slower it will be to reflect changes in the duty cycle.
- Connect 8 digital output lines (perhaps the whole D port) to a parallel DAC chip (digital to analog converter) such as the DAC0800. That's a lot of wires, and uses up a lot of your PIC pins, but it's conceptually simple. An instruction such as output_D(ivalue) is then all you need: ivalue=0 becomes 0V and ivalue=255 becomes 5V.
- Use a serial DAC chip such as the MAX517, as described next. This requires only 2 communication wires, and several DAC chips (and other chips) can share the same bus.
2-wire serial communication: the i2c bus
There are a lot of chips available that communicate via a serial protocol called i2c ("i squared c"). This requires only two communication lines: SCL and SDA (plus a common ground of course). SCL refers to a CLock signal and SDA to a stream of DAta bits. Many chips can share this 2-wire bus. The PIC would ordinarily be Bus Master, and select whichever chip it wishes to talk to by sending a one-byte address code. PIC-to-PIC communication can also be set up using i2c.
The 4520 PIC can control the i2c bus lines using a hardware i2c controller, or a software controller. The timing of software-controlled bus signals can be disrupted by interrupts, so hardware is often preferable. The software controller can use any pins for SCL and SDA. The hardware controller can only use RC3 and RC4. Sadly RC3 is just about the only pin that is NOT available at the 4520 board's edge connector, but you can connect to it on the PCB itself near pin 18 of the PIC 4520.
Wiring an i2c bus
We'll illustrate an i2c bus with two MAX517 DAC chips. The SCL and SDA lines need pull-up resistors as shown. (Without them, i2c instructions cause the PIC to wait forever for the bus to clear.)
The i2c bus lines are wired in common to all i2c slave devices; here we have just two MAX517 DAC chips. Each slave must have a different one-byte address. In the case of the MAX517, six of the bits of this address are fixed by the manufacturer and two are selected by you when wiring the chip. In binary the address is 0101 1**0, or in hex 0x58, 0x5A, 0x5C, or 0x5E. The two variable bits are chosen by wiring the AD1 and AD0 pins high or low. So in the circuit shown we can address the two DACs as 0x58 and 0x5A. (The prefix 0x means "this is a hexidecimal number")
The PIC is then responsible to send a series of bytes to control a DAC. It sends an address byte to make the proper chip pay attention, then a command byte which for these simple chips is just zero, and then a data byte containing the value to convert to analog: value 0 becomes 0V and value 255 becomes 5V.
Using the DAC
The DAC has a Vref input, which scales the output voltage. If you tie Vref to +5V, the output voltage ranges 0V to 5V, but also any noise on the 5V rail will become noise on the DAC's output. You can use a cleaner Vref if you wish. See the MAX517 documentation.
To command the DAC, see the code MAX517.c in AnalogOutput. The "#USE" line configures the i2c controller. Subsequent i2c instructions to take control of the bus, send the address byte (0x58), the command byte (0), and the desired data byte (i in this case), and release the bus.
#use i2c(MASTER, FAST, SCL=PIN_C3, SDA=PIN_C4, FORCE_HW) // use hardware i2c controller i2c_start(); // take control of the bus; impose "start" levels i2c_write(0x58); // address. 0101 1000. Red bits are selected by 2 pins high or low on MAX517 i2c_write(0); // command. just zero i2c_write(i); // data. Translated to analog output voltage i2c_stop(); // release the bus