This application note discusses an implementation of the Motorola SPI protocol and illustrates an SPI interface with a Microchip MCP3208 eight channel 12-bit A/D. It also illustrates how the 12-bit A/D may be used with a Motorola MPX4115AP or MPX4115AS to measure atmospheric pressure and convert this to barometric pressure..
Many versions of the PICAXE have ten bit A/D converters which provide 1024 levels over the range of 0.0 to 5.0 VDC, which is more than adequate for measuring temperature or relative humidity. However, in measuring atmospheric pressure which is typically 1013 millibars and even a change of one millibar is significant, one might opt to use a 12-bit A/D so as to resolve pressure to within nominally 0.25 millibars.
The Philips I2C and the Motorola SPI protocol are probably the most widely used standard interfaces in use today. Typical SPI devices include the 25LC640 and many high density EEPROMs, the TI TLC2543 A/D, various speech synthesizers, real time clocks and the MAX7219 7-seg LED Controller.
The SPI interface consists of four signal leads; a chip select (CS) which is used by the processor to select the specific device on the bus, a clock (SCK) which is controlled by the processor, a data out signal, commonly referred to as "master out - slave in" (MOSI), and a data in, "master in - slave out" (MISO). In some cases, there may be no need for one of the data signals. For example, with the MAX6674 K-thermocouple to digital converter, data is simply read and thus there is no MOSI signal lead. For a MAX7219 LED latch, only the MOSI lead may be used as there is no provision to read data for the MAX7219.
Note that the SCK, MOSI and MISO leads may be shared with several devices on a bus. A separate CS is required for each device and only one peripheral device may be active at a time.
A transmission sequence begins by bringing the chip select lead to the active state. In most cases, CS is brought low to select the specific device. However, I recall working with a Dallas RTC with an SPI interface where the active state was high.
Data is then clocked to the slave, beginning with the most significant bit on the MOSI output and at the same time, receiving data bits on the MISO signal lead. This may be thought of as a shift register, which is very simple to implement in hardware and in firmware.
Consider the following;
SPI_IO: For N = 1 to 8 If X > 127 Then SPI_IO_1 ' if most sig bit is a one Low MOSI ' otherwise set MOSI to a zero Goto SPI_IO_2 SPI_IO_1: High MOSI SPI_IO_2: High SCK ' clk high X = X * 2 + MISO ' read MISO Low SCK ' clk low Next ReturnNote that the most significant bit of X is tested and the MOSI output is set to the appropriate state. SCK is then brought high and the slave device then reads the MOSI lead. At the same time, the slave places data on the MISO processor input which is read by the processor, while shifting the data to the left;
X = X * 2 + MISOThus, with the shift, the next to the most significant bit is now in the most significant bit position.
This is repeated for each of the eight bits and thus, X is now the byte which was received from the slave device.
Note that unlike the I2C protocol, the SPI protocol has the capability for full duplex operation. However, just as with a telephone, the full duplex operation may or may not be used. For example, when reading from an SPI EEPROM, a read command is sent and the data which is read is of no consequence, the high and low bytes of the address are sent and again, the data which is read is of no consequence. Any byte is then sent to the EEPROM on the MOSI lead and the meaningful data is read from the EEPROM.
Interfacing with the MCP3208
In performing an A/D conversion using the MCP3208, CS is first brought low to select the device. Three bits are sent using the SPI routine;
%00000XYZwhere X is always a 1 indicating the "start" of data, Y is 1 for single ended measurements and Z is the most significant bit of the channel;
ADMeas: Low SCK Low CS X = Channel / 8 ' most significant bit of three bit channel address X = X | $06 GoSub SPI_IONote that in this case, the SPI routine sends the first byte out on the MOSI lead and although a byte is received on MISO, it is not used.
The processor sends a byte consisting of the low two bits of the channel address in the upper two bits and at the same time, receives the high four bits of the A/D result.
X = Channel * 64 ' get low two channel bits in bit positions 7 and 6 GoSub SPI_IO ADVal = X * 256The processor sends "garbage", that is anything, using the SPI routine and receives the low byte of the A/D result and terminates the transmission sequence by bringing CS high.
GoSub SPI_IO ADVAL = ADVAL + X ADVAL = ADVAL & $0fff ' only the lower 12 bits High CSThe full program for the MCP3208 appears below.
' MCP320x.Bas - PICAXE 18X ' ' Illustrates an interface with a Microchip MCP3208 8-channel 12-bit ' A/D. ' ' Perfroms a single ended A/D measure on each of the eigh channel and ' displays to the terminal. ' ' PICAXE-18X MCP3208 ' ' CS, Pin0 (term 6) ------------ /CS (term 10) ' SCK, Pin1 (term 7) ----------- CLK (term 13) ' MOSI, Pin 2 (term 8) --------- Din (term 11) ' MISO, Input0 (term 17) <------ Dout (term 12) ' ' ' copyright, Peter H. Anderson, Baltimore, MD, Jan, '04 Symbol ADVal = W0 Symbol Channel = B2 Symbol Dig = B3 Symbol X = B6 Symbol N = B7 Symbol CS = Output0 Symbol SCK = Output1 Symbol MOSI = Output2 Symbol MISO = Input0 Top: For Channel = 0 to 7 GoSub ADMeas GoSub DisplayADVal Next Wait 1 GoTo Top DisplayADVal: If ADVAL >= 100 Then DisplayVal_2 SerTxD (#ADVal) ' if one or two digits, just go ahead and display it DisplayADVal_1: SerTxD (13, 10) Return DisplayVal_2: Dig = ADVal / 100 ADVal = ADVal % 100 SerTxD (#Dig) Dig = ADVal / 10 ADVal = ADVal % 10 SerTxD (#Dig) Dig = ADVal SerTxD (#Dig) GoTo DisplayADVal_1 ADMeas: Low SCK Low CS X = Channel / 8 X = X | $06 GoSub SPI_IO X = Channel * 64 GoSub SPI_IO ADVal = X * 256 GoSub SPI_IO ADVAL = ADVAL + X ADVAL = ADVAL & $0fff High CS Return SPI_IO: For N = 1 to 8 If X > 127 Then SPI_IO_1 Low MOSI Goto SPI_IO_2 SPI_IO_1: High MOSI SPI_IO_2: High SCK X = X * 2 + MISO Low SCK Next Return
This section illustrates how to interface a Motorola MPX4115 with the MCP3208 A/D converter to measure atmospheric pressure.
MPX4115 (term 2) ------------------ MCP3208 Ch0 (term 1)
The output of the MPX4115 is proportional to pressure;
(1) VChannel0 = VRef * (P * 0.0009 - 0.095)Where P is the pressure in millibars and VRef is the nominal 5V supply.
The voltage on Channel 0 is calculated as;
(2) VChannel0 = ADVal / 4096 * VRefwhere ADVal is the 12-bit quantity in the range of 0 through 4095 and V_ref is the nominal +5 VDC supply.
Equating expressions (1) and (2)
VRef * (P * 0.0009 - 0.095) = ADVal / 4096 * VRefEliminating VRef and solving for P;
P = (ADVal / 4096 + 0.095) / 0.0009or
(3) P = 0.271 * ADVal + 105.5It is interesting (and pleasing) to observe that VRef does not appear in this calculation.
The pressure is calculated and displayed;
Pressure = ADVal * 2 / 10 Pressure = ADVal * 7 / 100 + Pressure Pressure = ADVal / 1000 + 105 + Pressure GoSub DisplayPressureNote that this is in millibars.
In the United States, we use inches of mercury. One millibar corresponds to 0.02953 inches of mercury.
Thus expression (3) may be modified to calculate the pressure in inches of mercury times 100.
(4) PHg_100 = 0.797 * ADVal + 295This may be calculated using the PICAXE in a manner quite similar to the above as;
PHg_100 = ADVal * 7 / 10 PHg_100 = ADVal * 9 / 100 + PHg_100 PHg_100 = ADVal * 7 / 1000 + 295 + PHg_100Note that in the following routine, the display subroutine was written to display the pressure in millibars. It would be necessary to modify this slightly to display the quantity in a form appropriate for inches of mercury (XX.YY).
' Barometer.Bas - PICAXE 18X ' ' Illustrates an interface with a Microchip MCP3208 12-bit A/D converter ' to measure atmospheric pressure using a Motorola MPX4115AP or MPX4115AS. ' ' Pressure = 0.271 * ADVal + 105.5. Note that this is atmospheric pressure ' and must be adjusted for altitude to determine barometric pressure. ' ' PICAXE-18X MCP3208 ' ' CS, Pin0 (term 6) ------------ /CS (term 10) ' SCK, Pin1 (term 7) ----------- CLK (term 13) ' MOSI, Pin 2 (term 8) --------- Din (term 11) ' MISO, Input0 (term 15) <------ Dout (term 12) ' ' ' copyright, Peter H. Anderson, Baltimore, MD, Jan, '04 Symbol ADVal = W0 Symbol Pressure = W4 Symbol Channel = B2 Symbol Dig = B3 Symbol X = B6 Symbol N = B7 Symbol CS = Output0 Symbol SCK = Output1 Symbol MOSI = Output2 Symbol MISO = Input0 Top: Channel = 0 ' MPX4115 is on this channel GoSub ADMeas Pressure = ADVal * 2 / 10 Pressure = ADVal * 7 / 100 + Pressure Pressure = ADVal / 1000 + 105 + Pressure GoSub DisplayPressure Wait 1 GoTo Top DisplayPressure: If Pressure >= 100 Then DisplayPressure_2 SerTxD (#Pressure) ' if one or two digits, just go ahead and display it DisplayPressure_1: SerTxD (13, 10) Return DisplayPressure_2: Dig = Pressure / 100 Pressure = Pressure % 100 SerTxD (#Dig) Dig = Pressure / 10 Pressure = Pressure % 10 SerTxD (#Dig) Dig = Pressure SerTxD (#Dig) GoTo DisplayPressure_1 ADMeas: Low SCK Low CS X = Channel / 8 X = X | $06 GoSub SPI_IO X = Channel * 64 GoSub SPI_IO ADVal = X * 256 GoSub SPI_IO ADVAL = ADVAL + X ADVAL = ADVAL & $0fff High CS Return SPI_IO: For N = 1 to 8 If X > 127 Then SPI_IO_1 Low MOSI Goto SPI_IO_2 SPI_IO_1: High MOSI SPI_IO_2: High SCK X = X * 2 + MISO Low SCK Next Return
Converting Atmospheric Pressure to Barometric Pressure
Normal atmospheric at sea level is nominally 1013 millibars and this is termed barometric pressure. Relatively small changes indicate drastically different weather conditions. For example, in the eye of a recent category 5 hurricane, the pressure was reported as 960 millibars.
However, atmospheric pressure decreases with altitude and thus if one were to interpret the atmospheric pressure in mile high Denver as being the barometric pressure, the number would suggest a daily catastrophe of biblical proportions. Rather, an expression is used to convert from atmospheric to barometric pressure which takes the altitude into account. Thus, the normal barometric pressure in Denver is reported as if Denver were at sea level.
The simplest technique for converting atmospheric pressure to barometric pressure for your installation is simply to scale the result. For example, assume the MPX4115 is reporting the atmospheric pressure as 861 millibars. However, your local weather reports the barometric pressure as 1010 millibars. Thus, the scaling factor is 1010 / 861 or 1.173. Simply multiply the atmospheric pressure by this altitude scaling factor. In this case;
BaroPress = Pressure BaroPress = Pressure * 1 / 10 + BaroPress BaroPress = Pressure * 7 / 100 + BaroPress BaroPress = Pressure * 3 / 1000 + BaroPress