The motivation behind interfacing is universal. This howto will focus on synchronous as well as asynchronous schemes, specifically RS-232, SPI, and I2C. These schemes are used to communicate with a multitude of devices such as PCs, FPUs, RAMs, and a variety of sensors.
Older PCs and instruments sometimes have RS-232 standard serial ports. Although the full RS-232 standard has multiple control signal lines, any MCU that has a UART (such as a PIC) can communicate with such serial port easily via only two lines -- TX and RX. Notice that the UART on MCUs usually uses TTL logic, which is far different from the RS-232 logic. To resolve the gap, we can use a MAX232 chips to convert between the level standards. Since it uses internal charge bumps to generate negative voltages, a single 5V supply is sufficient.
After successfully establish the hardware link, all you need to do is to unify the data format, including baud rate, word length, parity bit, and stop bit. Since UART / RS-232 are asynchronous interface, all the above parameters have to be set to exactly the same value in order to perform correct transmissions. A common PC RS-232 setting is 9800 8 N 1 (9800bps, 8-bit data, no parity bit, 1 stop bit). Note that because the MCU side baud rate are typically prescaled from the processor clock, it has limited choices. Nonetheless, an error less than 0.2% in baud rate should be tolerable.
logic adopted by RS-232
5V TTL logic
Here are some sample schematics:
Here are some code samples:
- PC Serial Interface - Perl
- PC Serial Interface - VB.NET (© Corrado Cavalli)
- PC Serial Port Monitor - Visual C++ (© Dan Pilat)
When using a PIC, this scheme is easily implemented by using the #RS232 PIC-C directive.
For a multi-drop (many receivers on the same line) serial connection, check out RS-422.
For a multi-point (many transmitters and receivers on the same line) serial connection, check out RS-485.
The SPI (Serial Peripheral Interface) bus is typically used to stream data from/to a device or to program configuration registers. For example, an ADC may allow programming registers to set the number of bits and the speed, or a temperature sensor may stream data out via SPI.
SPI works almost exactly how you would want a serial bus to work -- there is a MOSI line (master out slave in), an MISO line (master in slave out), and a clock line. Most SPI devices also have a chip select, which can be multiplexed to select which slave device the master is communicating with. When a slave is not selected, it switches its MISO port to high impedance mode so that it does not interfere with other slaves on the line.
In addition, SPI is usually the fastest interface in a typical MCU. It's clock speed can sometimes reach 1/2 of the processor clock.
SPI Clock and Data signals
The first rule of the IC (Inter-Integrated Circuit) bus is that its pronounced I-squared-C. The IC bus only has two bidirectional wires -- one data and one clock, and they are both pulled-up by resistors. In addition, when attempting to drive the two lines, any device on the bus should configure these two ports as open-drain. This scheme effectively utilizes the wired AND property of open-drain output to perform a bus arbitration function; thus, users are not required to manually prevent races among masters on the bus, though microcontroller programmers still need to handle arbitration lost interrupt or some similar events in their software when encountering such condition. Fortunately, an IC bus consisting of only one master is free from this consideration. An IC packet is made up by one address byte and arbitrary number of data bytes. The address byte packs a 7-bit slave address (or optionally 10-bit in newer standard, which we don't discuss here) and an R/W bit (read = 1, write = 0). The data bytes are always 8-bit. Both the address byte and data bytes have an additional active low ACK (acknowledge) bit appended, which should be cleared by the corresponding slave in the address byte and by the master or slave in a read or write data byte respectively.
Some devices that support SPI may also come in forms that support IC, and vice versa. Although the bus was initially designed to connect low-speed devices, it has evolved over the years to support fast devices as well.
To capture waveforms from these schemes on one of the oscilloscopes in lab, hit the Mode/Coupling button. Choose Mode Auto and switch to Mode Normal. Press the Trigger button. Most newer oscilloscopes in the lab support I2C triggering. You must choose the channels that are SDA and SCL, and each channel's trigger voltage must be set. They will not automatically be set to the same voltage. Triggering can be done on a start signal, stop signal, restart, write address, read address, raw data transmitted, or missing acknowledge bit. On the LCD screen oscilloscopes in the Senior Design Lab, a 14 day free trial can be applied so that the Hex bits of the signal can be viewed on screen in real time.
The time/division should be set between 10 us and 500us, and the voltage/div should be between 2 V and 5 V.
All the Agilent oscilloscopes in the senior design lab, and in the communications lab next door support I2C triggering. However, many of them (as of Spring 2013) require a floppy drive, not a USB drive, to save the data if you would like to add it to your report. Be sure to check this before you start if you plan on including this data in your report.
A word on pullup resistors: most microcontrollers will have a recommended value for a pullup resistor, but some do not provide that value, and depending on the number of sensors, it may change. A normal value is 10k, but values up to 100k are not uncommon.