Freescale Semiconductor Application Note AN1315 Rev 2, 05/2005 An Evaluation System Interfacing the MPX2000 Series Pressure Sensors to a Microprocessor by: Bill Lucas Discrete Applications Engineering INTRODUCTION PURPOSE Outputs from compensated and calibrated semiconductor pressure sensors such as the MPX2000 series devices are easily amplified and interfaced to a microprocessor. Design considerations and the description of an evaluation board using a simple analog interface connected to a microprocessor is presented here. The evaluation system shown in Figure 1 shows the ease of operating and interfacing the Freescale Semiconductor, Inc. MPX2000 series pressure sensors to a quad operational amplifier, which amplifies the sensor’s output to an acceptable level for an analog-to-digital converter. The output of the op amp is connected to the A/D converter of the microprocessor and that analog value is then converted to engineering units and displayed on a liquid crystal display (LCD). This system may be used to evaluate any of the MPX2000 series pressure sensors for your specific application. Figure 1. DEVB158 2000 Series LCD Pressure Gauge EVB (Board No Longer Available) © Freescale Semiconductor, Inc., 2005. All rights reserved. DESCRIPTION The DEVB158 evaluation system is constructed on a small printed circuit board. Designed to be powered from a 12 Vdc power supply, the system will display the pressure applied to the MPX2000 series sensor in pounds per square inch (PSI) on the liquid crystal display. Table 1 shows the pressure sensors that may be used with the system and the pressure range associated with that particular sensor as well as the jumper configuration required to support that sensor. These jumpers are installed at assembly time to correspond with the supplied sensor. Should the user chose to evaluate a different sensor other than that supplied with the board, the jumpers must be changed to correspond to Table 1 for the new sensor. The displayed pressure is scaled to the full scale (PSI) range of the installed pressure sensor. No potentiometers are used in the system to adjust its span and offset. This function is performed by software. Table 1. Missing Table Head Sensor Type MPX2010 MPX2050 MPX2100 MPX2200 Jumpers Input Pressure PSI J8 J3 0-1.5 0-7.5 0-15.0 0-30 IN OUT OUT OUT IN IN IN IN J2 J1 IN IN IN OUT OUT IN OUT OUT The signal conditioned sensor's zero pressure offset voltage with no pressure applied to the sensor is empirically computed each time power is applied to the system and stored in RAM. The sensitivity of the MPX2000 series pressure sensors is quite repeatable from unit to unit. There is a facility for a small adjustment of the slope constant built into the program. It is accomplished via jumpers J4 through J7, and will be explained in the OPERATION section. Figure 2 shows the printed circuit silkscreen and Figure 3 and Figure 4show the schematic for the system. The analog section of the system can be broken down into two subsections. These sections are the power supply and the amplification section. The power supply section consists of a diode, used to protect the system from input voltage reversal, and two fixed voltage regulators. The 5 volt regulator (U3) is used to power the microprocessor and display. The 8 volt regulator (U4) is used to power the pressure sensor, voltage references and a voltage offset source. The microprocessor section (U5) requires minimal support hardware to function. The MC34064P-5 (U2) provides an under voltage sense function and is used to reset the microprocessor at system power-up. The 4.0 MHz crystal (Y1) provides the external portion of the oscillator function for clocking the microprocessor and providing a stable base for timing functions. The analog section of the system can be broken down into two subsections. These sections are the power supply and the amplification section. The power supply section consists of a diode, used to protect the system from input voltage reversal, and two fixed voltage regulators. The 5 volt regulator (U3) is used to power the microprocessor and display. The 8 volt regulator (U4) is used to power the pressure sensor, voltage references and a voltage offset source. The microprocessor section (U5) requires minimal support hardware to function. The MC34064P-5 (U2) provides an under voltage sense function and is used to reset the microprocessor at system power-up. The 4.0 MHz crystal (Y1) provides the external portion of the oscillator function for clocking the microprocessor and providing a stable base for timing functions. AN1315 2 Sensors Freescale Semiconductor LCD1 U5 RP1 J1 J2 J3 U2 R4 C8 C2 R15 C7 R1 C3 U3 R5 R8 D1 C1 TP1 Y1 D2 U1 R3 R2 R9 R10 R7 C5 R13 C4 R12 U4 R6 R14 J8 XCDR1 Freescale Discrete Applications Engineering C6 P1 +12 GND 5.2” R11 J4 J5 J6 J7 DEVB158 2.9” Figure 2. Printed Circuit Silkscreen AN1315 Sensors Freescale Semiconductor 3 +12 V 5 J8 Is installed for the MPX2010 only – 4 7 6 +U1A +5.0 V +5.0 V 6.98K +8 2 +5.0 V MC33274 R1 10 – 8 9 +U1C R5 3 121 R2 200 R3 D2 R4 12 – 14 13 +U1D 340 +8 976 1K R9 R10 7 x 47K J1 R8 Sensor Type Select U3 78L05 IN 1 µF +12 IN P1 GROUND 1N4002 + IN U4 78L08 1 µF GROUND C1 +5.0 V C2 0.1 J4 C3 J5 +8 OUT GROUND J2 J3 OUT + 1 µF + C5 0.1 3.32K Slope Adj. R12 C4 VRH 2–D4 4.53K J6 R13 VRL 2–D4 402 CPU_Reset 2–B4 +5.0 V R7 23.7 D1 GND R6 2K 2 – 1 3 U1B + 11 OUT MC34064P-5 PD0 2–A2 R11 TP1 2K J8 1 4 XDCR1 1N914 4.7K 4.7K U2 +IN R14 J7 PD1 2–A2 PD2 2–A3 PD3 2–A3 PD4 2–A3 PD5 2–A3 PD6 2–A3 PD7 2–A3 Figure 3. Schematic A AN1315 4 Sensors Freescale Semiconductor Figure 4. Schematic B AN1315 Sensors Freescale Semiconductor 5 PD7 1–E4 PD5 1–E4 PD1 1–E3 PD1 1–E3 PD6 1–E4 PD4 1–E3 PD2 1–E3 PD0 1–C2 3 4 5 9 11 12 13 14 2 0 18 CPU_RESET 1–E2 RESET +5 V 43 0.1 15 C6 VPP6 5 44 10 3 46 VDD 4 45 7 34 35 8 31 32 9 7 6 PORTC 42 IRQ 1 48 6 19 PD7 PD6 PD5 PD4 PD3 PD2 PD1 PD0 47 49 28 37 36 5 41 VSS 0 39 10 22 1 38 TCAP1 2 37 33 23 TCAP2 D/A 21 5 34 U5 MC68HC705B5 7 6 PORTB 32 11 29 30 12 26 27 13 LCD1 3 36 50 52 0 31 2 VRL 1C4 7 VRL 29 30 1 24 15 24 25 16 22 23 17 RDI TDO 4 35 14 25 VRH 1C4 8 27 5 20 3 16 22 pF R15 10M 17 C7 PINS: 2–4, 33, 38–40 OSC1 OSC2 28 1 PLMA 4 26 19 20 21 VRH 7 6 PORTA 18 BLK PLN C8 4.00 MHz Y1 22 pF Table 2. Parts List Designators Quant. Description Rating Manufacturer Part Number C3, C4, C6 3 0.1 µF Ceramic Cap. 50 Vdc Sprague 1C105Z5U104M050B C1, C2, C5 3 1 µF Ceramic Cap. 50 Vdc muRATA ERIE RPE123Z5U105M050V C7, C8 2 22 pF Ceramic Cap. 100 Vdc Mepco/Centralab CN15A220K J1-J3, J8 J4-J7 3 OR 4 1 #22 or #24 AWG Tined Copper As Required Dual Row Straight 4 Pos. Arranged On 0.1″ Grid AMP 87227-2 LCD1 1 Liquid Crystal Display IEE LCD5657 P1 1 Power Connector Phoenix Contact MKDS 1/2-3.81 R1 1 6.98K Ohm resistor 1% R2 1 121 Ohm Resistor 1% R3 1 200 Ohm Resistor 1% R4, R11 2 4.7K Ohm Resistor R7 1 340 Ohm Resistor 1% R5, R6 2 2.0K Ohm Resistor 1% R8 1 23.7 Ohm Resistor 1% R9 1 976 Ohm Resistor 1% R10 1 1K Ohm Resistor 1% R12 1 3.32K Ohm Resistor 1% CTS 770 Series R13 1 4.53K Ohm Resistor 1% R14 1 402 Ohm Resistor 1% R15 1 10 Meg Ohm Resistor RP1 1 47K Ohm x 7 SIP Resistor 2% TP1 1 Test Point Components Corp. TP-104-01-02 U1 1 Quad Operational Amplifier Red Freescale MC33274P U2 1 Under Voltage Detector Freescale MC34064P-5 U3 1 5 Volt Fixed Voltage Regulator Freescale MC78L05ACP U4 1 8 Volt Fixed Voltage Regulator Freescale MC78L08ACP U5 1 Microprocessor Freescale Freescale MC68HC705B5FN or XC68HC705B5FN XDCR 1 Pressure Sensor Freescale MPX2xxxDP Y1 1 Crystal (Low Profile) CTS ATS040SLV No Designator 1 52 Pin PLCC Socket for U5 AMP 821-575-1 No Designator 4 Jumpers For J4 thru J7 Molex 15-29-1025 No Designator 1 Bare Printed Circuit Board No Designator 4 Self Sticking Feet Fastex 5033-01-00-5001 4.0 MHz Notes: All resistors are 1/4 W resistors with a tolerance of 5% unless otherwise noted. All capacitors are 100 volt, ceramic capacitors with a tolerance of 10% unless otherwise noted. AN1315 6 Sensors Freescale Semiconductor OPERATIONAL CHARACTERISTICS The following operational characteristics are included as a guide to operation. Symbol Min Max Unit Power Supply Voltage Characteristic +12 10.75 16 Volts Operating Current ICC 75 mA Full Scale Pressure MPX2010 MPX2050 MPX2100 MPX2200 Pfs 1.5 7.5 15 30 PSI PSI PSI PSI the software to allow the user to adjust the slope constant used for the engineering units calculation (see Table 3). The pressure and vacuum ports on the sensor must be left open to atmosphere anytime the board is powered-up. This is because the zero pressure offset voltage is computed at power-up. When you apply power to the system, the LCD will display CAL for approximately 5 seconds. After that time, pressure or vacuum may be applied to the sensor. The system will then start displaying the applied pressure in PSI. Table 3. Slope Constants J7 J6 J5 J4 IN IN IN IN Pin-by-Pin Description IN IN IN +12 IN IN OUT IN IN OUT OUT Decrease the Slope Approximately 5% Input power is supplied at the +12 terminal. The minimum operating voltage is 10.75 Vdc and the maximum operating voltage is 16 Vdc. GND Action Normal Slope OUT Decrease the Slope Approximately 7% IN IN Decrease the Slope Approximately 6% IN OUT IN IN OUT IN Decrease the Slope Approximately 4% IN OUT OUT IN OUT OUT OUT Decrease the Slope Approximately 1% OUT Decrease the Slope Approximately 3% IN Decrease the Slope Approximately 2% The ground terminal is the power supply return for the system. OUT IN IN OUT IN IN TP1 OUT IN OUT Test point 1 is connected to the final op amp stage. It is the voltage that is applied to the microprocessor's A/D converter. There are two ports on the pressure sensor located at the bottom center of the printed circuit board. The pressure port is on the top left and the vacuum port is on the bottom right of the sensor. OUT IN OUT OUT Increase the Slope Approximately 4% OPERATION Connect the system to a 12 Vdc regulated power supply. (Note the polarity marked on the power terminal P1.) Depending on the particular pressure sensor being used with the system, wire jumpers J1 through J3 and J8 must be installed at board assembly time. If at some later time it is desirable to change the type of sensor that is installed on the board, jumpers J1 through J3 and J8, must be reconfigured for the system to function properly (see Table 1). If an invalid J1 through J3 jumper combination (i.e., not listed in Table 1) is used the LCD will display “SE” to indicate that condition. These jumpers are read by the software and are used to determine which sensor is installed on the board. Wire jumper J8 is installed only when an MPX2010DP pressure sensor is used on the system. The purpose of wire jumper J8 will be explained later in the text. Jumpers J4 through J7 are read by OUT OUT IN OUT OUT IN OUT OUT OUT IN Increase the Slope Approximately 1% OUT Increase the Slope Approximately 2% IN IN Increase the Slope Approximately 3% Increase the Slope Approximately 5% OUT Increase the Slope Approximately 6% IN Increase the Slope Approximately 7% OUT OUT OUT OUT Normal Slope To improve the accuracy of the system, you can change the constant used by the program that determines the span of the sensor and amplifier. You will need an accurate test gauge (using PSI as the reference) to measure the pressure applied to the sensor. Anytime after the display has completed the zero calculation, (after CAL is no longer displayed) apply the sensor's full scale pressure (see Table 1), to the sensor. Make sure that jumpers J4 through J7 are in the “normal” configuration (see Table 3). Referring to Table 3, you can better “calibrate” the system by changing the configuration of J4 through J7. To “calibrate” the system, compare the display reading against that of the test gauge (with J4 through J7 in the “normal slope” configuration). Change the configuration of J4 through J7 according to Table 3 to obtain the best results. The calibration jumpers may be changed while the system is powered up as they are read by the software before each display update. AN1315 Sensors Freescale Semiconductor 7 DESIGN CONSIDERATIONS From a hardware point of view, the microprocessor portion of the system is straight forward. The microprocessor needs power, a clock source (crystal Y1, two capacitors and a resistor), and a reset signal to make it function. As for the A/D converter, external references are required to make it function. In this case, the power source for the sensor is divided to produce the voltage references for the A/D converter. Accurate results will be achieved since the output from the sensor and the A/D references are ratiometric to its power supply voltage. To build a system that will show how to interface an MPX2000 series pressure sensor to a microprocessor, there are two main challenges. The first is to take a small differential signal produced by the sensor and produce a ground referenced signal of sufficient amplitude to drive a microprocessor's A/D input. The second challenge is to understand the microprocessor's operation and to write software that makes the system function. +12 V J8 is installed for the MPX2010 only 5 – 4 7 6 +U1A 6.98K +8 2 +5.0 V R1 MC33274 10 – 8 9 +U1C 3 121 R2 1 4 XDCR1 200 R3 J8 2 – 1 3 +U1B 11 +8 340 R5 2K R6 1N914 4.7K D2 PD0 R4 TP1 2K 12 – 14 13 +U1D 976 R10 R9 1K R7 23.7 R8 Figure 5. Analog Interface The liquid crystal display is driven by Ports A, B and C of the microprocessor. There are enough I/O lines on these ports to provide drive for three full digits, the backplane and two decimal points. Software routines provide the AC waveform necessary to drive the display. The analog portion of the system consists of the pressure sensor, a quad operational amplifier and the voltage references for the microprocessor's A/D converter and signal conditioning circuitry. Figure 5 shows an interface circuit that will provide a single ended signal with sufficient amplitude to drive the microprocessor's A/D input. It uses a quad operational amplifier and several resistors to amplify and level shift the sensor's output. It is necessary to level shift the output from the final amplifier into the A/D. Using single power supplied op amps, the VCE saturation of the output from an op amp cannot be guaranteed to pull down to zero volts. The analog design shown here will provide a signal to the A/D converter with a span of approximately 4 volts when zero to full-scale pressure is applied to the sensor. The final amplifier's output is level shifted to approximately 0.7volts. This will provide a signal that will swing between approximately 0.7 volts and 4.7 volts. The offset of 0.7 volts in this implementation does not have to be trimmed to an exact point. The software will sample the voltage applied to the A/D converter at initial power up time and call that value “zero”. The important thing to remember is that the span of the signal will be approximately 4 volts when zero to full scale pressure is applied to the sensor. The 4 volt swing in signal may vary slightly from sensor to sensor and can also vary due to resistor tolerances in the analog circuitry. Jumpers J4 through J7 may be placed in various configurations to compensate for these variations (see Table 3). Referring to Figure 5, most of the amplification of the voltage from the pressure sensor is provided by U1A which is AN1315 8 Sensors Freescale Semiconductor configured as a differential amplifier. U1B serves as a unity gain buffer in order to keep any current that flows through R2 (and R3) from being fed back into the sensor's negative output. With zero pressure applied to the sensor, the differential voltage from pin 2 to pin 4 of the sensor is zero or very close to zero volts. The common mode, or the voltage measured between pins 2 or 4 to ground, is equal to approximately one half of the voltage applied to the sensor, or 4 volts. The zero pressure output voltage at pin 7 of U1A will then be 4 volts because pin 1 of U1B is also at 4 volts, creating a zero bias between pins 5 and 6 of U1A. The four volt zero pressure output will then be level shifted to the desired zero pressure offset voltage (approximately 0.7 volts) by U1C and U1D. Start Initalize Display I/O Ports Initalize Timer Registers Determine Sensor Type Enable Interrupts Timer Interrupt Service Timer Registers Setup Counter for Next Interrupt Service Liquid Crystal Display Compute Slope Constant Accumulate 100 A/D Conversions Compute Input Pressure Convert to Decimal/Segment Data Place in Result Output Buffer Return Figure 6. DEVB-158 Software Flowchart To further explain the operation of the level shifting circuitry, refer again to Figure 5. Assuming zero pressure is applied to the sensor and the common mode voltage from the sensor is 4 volts, the voltage applied to pin 12 of U1D will be 4 volts, implying pin 13 will be at 4 volts. The gain of amplifier U1D will be (R10/(R8+R9)) +1 or a gain of 2. R7 will inject a Voffset (0.7 volts) into amplifier U1D, thus causing the output at U1D pin 14 to be 7.3 = (4 volts @ U1D pin 12 × 2) - 0.7 volts. The gain of U1C is also set at 2 ((R5/R6)+1). With 4 volts applied to pin 10 of U1C, its output at U1C pin 8 will be 0.7 = ((4 volts @ U1C pin 10 × 2) - 7.3 volts). For this scheme to work properly, amplifiers U1C and U1D must have a gain of 2 and the output of U1D must be shifted down by the Voffset provided by R7. In this system, the 0.7 volts Voffset was arbitrarily picked and could have been any voltage greater than the Vsat of the op amp being used. The system software will take in account any variations of Voffset as it assumes no pressure is applied to the sensor at system power up. The gain of the analog circuit is approximately 117. With the values shown in Figure 5, the gain of 117 will provide a span of approximately 4 volts on U1C pin 8 when the pressure sensor and the 8 volt fixed voltage regulator are at their maximum output voltage tolerance. All of the sensors listed in Table 1 with the exception of the MPX2010DP output approximately 33 mV when full scale pressure is applied. When the MPX2010DP sensor is used, its full scale sensor differential output is approximately 20 mV. J8 must be installed to increase the gain of the analog circuit to still provide the 4 volts span out of U1C pin 8 with a 20 mV differential from the sensor. Diode D2 is used to protect the microprocessor's A/D input if the output from U1C exceeds 5.6 volts. R4 is used to provide current limiting into D4 under failure or overvoltage conditions. SOFTWARE The source code, compiled listing, and S-record output for the software used in this system are available on the Freescale Freeware Bulletin Board Service in the MCU directory under the filename DEVB158.ARC. To access the bulletin board, you must have a telephone line, a 300, 1200 or 2400 baud modem and a personal computer. The modem must be compatible with the Bell 212A standard. Call (512) 891-3733 to access the Bulletin Board Service. Figure 6 is a flowchart for the program that controls the system. The software for the system consists of a number of modules. Their functions provide the capability for system calibration as well as displaying the pressure input to the MPX2000 series pressure sensor. AN1315 Sensors Freescale Semiconductor 9 The “C” compiler used in this project was provided by BYTE CRAFT LTD. (519) 888-6911. A compiler listing of the program is included at the end of this document. The following is a brief explanation of the routines: delay() Used to provide a software loop delay. read_a2d() Performs 100 reads on the A/D converter on multiplexer channel 0 and returns the accumulation. fixcompare() Services the internal timer for 15 ms. timer compare interrupts. TIMERCMP() Alternates the data and backplane inputs to the liquid crystal display. initio() Sets up the microprocessor's I/O ports, timer and enables processor interrupts. adzero() This routine is called at powerup time. It delays to let the power supply and the transducer stabilize. It then calls “read_atod()” and saves the returned value as the sensors output voltage with zero pressure applied. cvt_bin_dec(unsigned long arg This routine converts the unsigned binary argument passed in “arg” to a five digit decimal number in an array called “digit.” It then uses the decimal results for each digit as an index into a table that converts the decimal number into a segment pattern for the display. This is then output to the display. display_psi() This routine is called from “main()” never to return. The A/D converter routine is called, the pressure is calculated based on the type sensor detected and the pressure applied to the sensor is displayed. The loop then repeats. sensor_type() This routine determines the type of sensor from reading J1 to J3, setting the full scale pressure for that particular sensor in a variable for use by display_psi(). sensor_slope() This routine determines the slope constant to be used by display_psi() for engineering units output. main() This is the main routine called from reset. It calls “initio()” to setup the system's I/O. “display_psi()” is called to compute and display the pressure applied to the sensor. AN1315 10 Sensors Freescale Semiconductor 6805 'C' COMPILER V3.48 16-Oct-1991 PAGE 1 #pragma option f0; /* THE FOLLOWING 'C' SOURCE CODE IS WRITTEN FOR THE DEVB158 EVALUATION BOARD. IT WAS COMPILED WITH A COMPILER COURTESY OF: BYTE CRAFT LTD. 421 KING ST. WATERLOO, ONTARIO CANADA N2J 4E4 (519)888-6911 SOME SOURCE CODE CHANGES MAY BE NECESSARY FOR COMPILATION WITH OTHER COMPILERS. BILL LUCAS 2/5/92 Freescale, SPS Revision history rev. 1.0 initial release 3/19/92 rev. 1.1 added additional decimal digit to the MPX2010 sensor. Originally resolved the output to .1 PSI. Modified cvt_bin_dec to output PSI resolved to .01 PSI. WLL 9/25/92 0800 1700 0050 0096 */ #pragma memory ROMPROG [5888] #pragma memory RAMPAGE0 [150] 1FFE 1FFC 1FFA 1FF8 1FF6 1FF4 1FF2 /* #pragma #pragma #pragma #pragma #pragma #pragma #pragma @ 0x0800 ; @ 0x0050 ; Vector assignments */ vector __RESET @ 0x1ffe vector __SWI @ 0x1ffc vector IRQ @ 0x1ffa vector TIMERCAP @ 0x1ff8 vector TIMERCMP @ 0x1ff6 vector TIMEROV @ 0x1ff4 vector SCI @ 0x1ff2 ; ; ; ; ; ; ; #pragma has STOP ; #pragma has WAIT ; #pragma has MUL ; 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D /* #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma Register assignments for the 68HC705B5 microcontroller */ portrw porta @ 0x00; /* */ portrw portb @ 0x01; /* */ portrw portc @ 0x02; /* */ portrw portd @ 0x03; /* in ,,SS ,SCK ,MOSI ,MISO,TxD,RxD */ portrw ddra @ 0x04; /* Data direction, Port A */ portrw ddrb @ 0x05; /* Data direction, Port B */ portrw ddrc @ 0x06; /* Data direction, Port C (all output) */ portrw eeclk @ 0x07; /* eeprom/eclk cntl */ portrw addata @ 0x08; /* a/d data register */ portrw adstat @ 0x09; /* a/d stat/control */ portrw plma @ 0x0a; /* pulse length modulation a */ portrw plmb @ 0x0b; /* pulse length modulation b */ portrw misc @ 0x0c; /* miscellaneous register */ portrw scibaud @ 0x0d; /* sci baud rate register */ portrw scicntl1 @ 0x0e; /* sci control 1 */ portrw scicntl2 @ 0x0f; /* sci control 2 */ portrw scistat @ 0x10; /* sci status reg */ portrw scidata @ 0x11; /* SCI Data */ portrw tcr @ 0x12; /* ICIE,OCIE,TOIE,0;0,0,IEGE,OLVL */ portrw tsr @ 0x13; /* ICF,OCF,TOF,0; 0,0,0,0 */ portrw icaphi1 @ 0x14; /* Input Capture Reg (Hi-0x14, Lo-0x15) */ portrw icaplo1 @ 0x15; /* Input Capture Reg (Hi-0x14, Lo-0x15) */ portrw ocmphi1 @ 0x16; /* Output Compare Reg (Hi-0x16, Lo-0x17) */ portrw ocmplo1 @ 0x17; /* Output Compare Reg (Hi-0x16, Lo-0x17) */ portrw tcnthi @ 0x18; /* Timer Count Reg (Hi-0x18, Lo-0x19) */ portrw tcntlo @ 0x19; /* Timer Count Reg (Hi-0x18, Lo-0x19) */ portrw aregnthi @ 0x1A; /* Alternate Count Reg (Hi-$1A, Lo-$1B) */ portrw aregntlo @ 0x1B; /* Alternate Count Reg (Hi-$1A, Lo-$1B) */ portrw icaphi2 @ 0x1c; /* Input Capture Reg (Hi-0x1c, Lo-0x1d) */ portrw icaplo2 @ 0x1d; /* Input Capture Reg (Hi-0x1c, Lo-0x1d) */ AN1315 Sensors Freescale Semiconductor 11 001E 001F #pragma portrw ocmphi2 #pragma portrw ocmplo2 @ 0x1e; @ 0x1f; /* Output Compare Reg (Hi-0x1e, Lo-0x1f) /* Output Compare Reg (Hi-0x1e, Lo-0x1f) */ */ 1EFE 74 #pragma mor @ 0x1efe = 0x74; /* this disables the watchdog counter and does not add pull-down resistors on ports B and C */ /* put constants and variables here...they must be global */ /***************************************************************************/ 0800 FC 30 DA 7A 36 6E E6 38 FE 0809 3E const char lcdtab[]={0xfc,0x30,0xda,0x7a,0x36,0x6e,0xe6,0x38,0xfe,0x3e }; /* lcd pattern table 0 1 2 3 4 5 6 7 8 9 */ 080A 27 10 03 E8 00 64 00 0A const long dectable[] = { 10000, 1000, 100, 10 }; 0050 0005 unsigned int digit[5]; /* buffer to hold results from cvt_bin_dec function */ 0812 00 96 00 4B 00 96 00 1E 00 081B 67 const long type[] = { 150, 75, 150, 30, 103 }; /* MPX2010 MPX2050 MPX2100 MPX2200 MPX2700 The table above will cause the final results of the pressure to engineering units to display the 1.5, 7.3 and 15.0 devices with a decimal place in the tens position. The 30 and 103 psi devices will display in integer units. */ 081C 0825 082E 0837 01 B0 01 DD C2 01 CB 01 01 B4 01 E1 A2 01 CF 01 01 A7 01 AB 01 B9 01 BD 01 C6 01 D4 01 D8 01 C2 const long slope_const[]={ 450,418,423,427,432,436,441,445,454,459, 463,468,472,477,481,450 }; 0000 registera areg; /* processor's A register */ 0055 long atodtemp; /* temp to accumulate 100 a/d readings for smoothing */ 0059 long slope; /* multiplier for adc to engineering units conversion */ 005B int adcnt; /* a/d converter loop counter */ 005C long xdcr_offset; /* initial xdcr offset */ 005E 0060 long sensor_model; /* int sensor_index; /* 0061 0063 unsigned long i,j; /* counter for loops */ 0065 unsigned int k; installed sensor based on J1..J3 */ determine the location of the decimal pt. */ /* misc variable */ struct bothbytes { int hi; int lo; }; union isboth { long l; struct bothbytes b; }; 0066 0002 union isboth q; /* used for timer set-up */ /***************************************************************************/ 0068 0004 006C 0004 0070 0004 /* variables for add32 */ unsigned long SUM[2]; /* unsigned long ADDEND[2]; /* unsigned long AUGEND[2]; /* result one input second input */ */ */ 0074 0004 0078 0004 /* variables for sub32 */ unsigned long MINUE[2]; /* unsigned long SUBTRA[2]; /* minuend subtrahend */ */ AN1315 12 Sensors Freescale Semiconductor 007C 0004 unsigned long DIFF[2]; /* 0080 0004 0084 0004 0088 0004 /* variables for mul32 */ unsigned long MULTP[2]; /* unsigned long MTEMP[2]; /* unsigned long MULCAN[2]; /* multiplier */ high order 4 bytes at return */ multiplicand at input, low 4 bytes at return */ 008C 0004 0090 0004 0094 0004 0098 /* variables for div32 unsigned long DVDND[2]; unsigned long DVSOR[2]; unsigned long QUO[2]; unsigned int CNT; Dividend Divisor Quotient Loop counter */ /* /* /* /* difference */ */ */ */ */ /* The code starts here */ /***************************************************************************/ void add32() { #asm 083C 083E 0840 0842 0844 0846 0848 084A 084C 084E 0850 0852 0854 B6 BB B7 B6 B9 B7 B6 B9 B7 B6 B9 B7 81 6F 73 6B 6E 72 6A 6D 71 69 6C 70 68 0855 81 0856 0858 085A 085C 085E 0860 0862 0864 0866 0868 086A 086C 086E B6 B0 B7 B6 B2 B7 B6 B2 B7 B6 B2 B7 81 RTS 77 7 7F 76 7A 7E 75 79 7D 74 78 7C *----------------------------------------------------------------------------* * Add two 32-bit values. * Inputs: * ADDEND: ADDEND[0..3] HIGH ORDER BYTE IS ADDEND+0 * AUGEND: AUGEND[0..3] HIGH ORDER BYTE IS AUGEND+0 * Output: * SUM: SUM[0..3] HIGH ORDER BYTE IS SUM+0 *----------------------------------------------------------------------------* * LDA ADDEND+3 low byte ADD AUGEND+3 STA SUM+3 LDA ADDEND+2 medium low byte ADC AUGEND+2 STA SUM+2 LDA ADDEND+1 medium high byte ADC AUGEND+1 STA SUM+1 LDA ADDEND high byte ADC AUGEND STA SUM RTS done * #endasm } void sub32() { #asm *----------------------------------------------------------------------------* * Subtract two 32-bit values. * Input: * Minuend: MINUE[0..3] * Subtrahend: SUBTRA[0..3] * Output: * Difference: DIFF[1..0] *----------------------------------------------------------------------------* * LDA MINUE+3 low byte SUB SUBTRA+3 STA DIFF+3 LDA MINUE+2 medium low byte SBC SUBTRA+2 STA DIFF+2 LDA MINUE+1 medium high byte SBC SUBTRA+1 STA DIFF+1 LDA MINUE high byte SBC SUBTRA STA DIFF RTS done * AN1315 Sensors Freescale Semiconductor 13 086F 81 0870 0872 0874 0876 0878 087A 087C 087E 0880 0882 0884 0886 0888 088A 088C 088E 0890 0892 0894 0896 0898 089A 089C 089E 08A0 08A2 08A4 08A6 08A8 08AA 08AC 08AD 08AF AE 3F 3F 3F 3F 36 36 36 36 24 B6 BB B7 B6 B9 B7 B6 B9 B7 B6 B9 B7 36 36 36 36 36 36 36 36 5A 26 81 08B0 81 RTS #endasm } void mul32() { #asm *----------------------------------------------------------------------------* * Multiply 32-bit value by a 32-bit value * * * Input: * Multiplier: MULTP[0..3] * Multiplicand: MULCAN[0..3] * Output: * Product: MTEMP[0..3] AND MULCAN[0..3] MTEMP[0] IS THE HIGH * ORDER BYTE AND MULCAN[3] IS THE LOW ORDER BYTE * * THIS ROUTINE DOES NOT USE THE MUL INSTRUCTION FOR THE SAKE OF USERS NOT * USING THE HC(7)05 SERIES PROCESSORS. *----------------------------------------------------------------------------* * * LDX #32 loop counter CLR MTEMP clean-up for result CLR MTEMP+1 * CLR MTEMP+2 * CLR MTEMP+3 * ROR MULCAN low but to carry, the rest one to the right ROR MULCAN+1 * ROR MULCAN+2 * ROR MULCAN+3 * MNEXT BCC ROTATE if carry is set, do the add LDA MTEMP+3 * ADD MULTP+3 * STA MTEMP+3 * LDA MTEMP+2 * ADC MULTP+2 * STA MTEMP+2 * LDA MTEMP+1 * ADC MULTP+1 * STA MTEMP+1 * LDA MTEMP * ADC MULTP * STA MTEMP * ROTATE ROR MTEMP else: shift low bit to carry, the rest to the right ROR MTEMP+1 * ROR MTEMP+2 * ROR MTEMP+3 * ROR MULCAN * ROR MULCAN+1 * ROR MULCAN+2 * ROR MULCAN+3 * DEX bump the counter down BNE MNEXT done yet ? RTS done 20 84 85 86 87 88 89 8A 8B 18 87 83 87 86 82 86 85 81 85 84 80 84 84 85 86 87 88 89 8A 8B D3 RTS #endasm } void div32() { #asm * *----------------------------------------------------------------------------* * Divide 32 bit by 32 bit unsigned integer routine * * Input: * Dividend: DVDND [+0..+3] HIGH ORDER BYTE IS DVND+0 * Divisor: DVSOR [+0..+3] HIGH ORDER BYTE IS DVSOR+0 * Output: * Quotient: QUO [+0..+3] HIGH ORDER BYTE IS QUO+0 *----------------------------------------------------------------------------* * AN1315 14 Sensors Freescale Semiconductor 08B1 08B3 08B5 08B7 08B9 08BB 08BD 3F 3F 3F 3F A6 3D 2B 08BF 08C0 08C2 08C4 08C6 08C8 08CA 08CC 4C 38 39 39 39 2B A1 26 94 95 96 97 01 90 0F CLR CLR CLR CLR LDA TST BMI * DIV151 INCA bump the loop counter ASL DVSOR+3 now shift the divisor until the high order bit = 1 ROL DVSOR+2 ROL DVSOR+1 * ROL DVSOR * BMI DIV153 done if high order bit = 1 CMP #33 have we shifted all possible bits in the DVSOR yet ? BNE DIV151 no * DIV153 STA CNT save the loop counter so we can do the divide * DIV163 LDA DVDND+3 sub 32 bit divisor from dividend SUB DVSOR+3 * STA DVDND+3 * LDA DVDND+2 * SBC DVSOR+2 * STA DVDND+2 * LDA DVDND+1 * SBC DVSOR+1 * STA DVDND+1 * LDA DVDND * SBC DVSOR * STA DVDND * BCC DIV165 carry is clear if DVSOR was larger than DVDND * LDA DVDND+3 add the divisor back...was larger than the dividend ADD DVSOR+3 * STA DVDND+3 * LDA DVDND+2 * ADC DVSOR+2 * STA DVDND+2 * LDA DVDND+1 * ADC DVSOR+1 * STA DVDND+1 * LDA DVDND * ADC DVSOR * STA DVDND * CLC this will clear the respective bit in QUO due to * the need to add DVSOR back to DVND BRA DIV167 DIV165 SEC this will set the respective bit in QUO DIV167 ROL QUO+3 set or clear the low order bit in QUO based on above ROL QUO+2 * ROL QUO+1 * ROL QUO * LSR DVSOR divide the divisor by 2 ROR DVSOR+1 * ROR DVSOR+2 * ROR DVSOR+3 * DEC CNT bump the loop counter down BNE DIV163 finished yet ? RTSyes * 93 92 91 90 04 21 F1 08CE B7 9 08D0 08D2 08D4 08D6 08D8 08DA 08DC 08DE 08E0 08E2 08E4 08E6 08E8 B6 B0 B7 B6 B2 B7 B6 B2 B7 B6 B2 B7 24 8F 93 8F 8E 92 8E 8D 91 8D 8C 90 8C 1B 08EA 08EC 08EE 08F0 08F2 08F4 08F6 08F8 08FA 08FC 08FE 0900 0902 B6 BB B7 B6 B9 B7 B6 B9 B7 B6 B9 B7 98 8F 93 8F 8E 92 8E 8D 91 8D 8C 90 8C 0903 0905 0906 0908 090A 090C 090E 0910 0912 0914 0916 0918 091A 20 99 39 39 39 39 34 36 36 36 3A 26 81 01 97 96 95 94 90 91 92 93 98 B6 091B 81 QUOzero result registers QUO+1 * QUO+2 * QUO+3 * #1 initial loop count DVSOR if the high order bit is set..no need to shift DVSOR DIV153 RTS #endasm } /***************************************************************************/ /* These interrupts are not used...give them a graceful return if for some reason one occurs */ 1FFC 09 1C 091C 80 1FFA 09 1D __SWI(){} RTI IRQ(){} AN1315 Sensors Freescale Semiconductor 15 091D 1FF8 091E 1FF4 091F 1FF2 0920 80 09 1E 80 09 1F 80 09 20 80 RTI TIMERCAP(){} RTI TIMEROV(){} RTI SCI(){} RTI /***************************************************************************/ 0921 0923 0925 0927 0929 092B 092D B6 A4 B7 34 B6 A1 23 03 0E 65 65 65 04 0C LDA AND STA LSR LDA CMP BLS $03 #$0E $65 $65 $65 #$04 $093B 092F 0931 0933 0935 0937 0939 3F A6 B7 A6 B7 20 02 6E 01 CE 00 FE CLR LDA STA LDA STA BRA $02 #$6E $01 #$CE $00 $0939 093B 093D 093F 0940 0941 0944 0946 0949 094B B6 B7 97 58 D6 B7 D6 B7 81 65 60 LDA STA TAX LSLX 08 12 LDA 5E STA 08 13 LDA 5F STA RTS $65 $60 void sensor_type() { k = portd & 0x0e; /* we only care about bits 1..3 */ k = k >> 1; if ( k > 4 ) /* right justify the variable */ { /* we have a set-up error in wire jumpers J1 - J3 */ portc = 0; /* */ portb = 0x6e; /* S */ porta = 0xce; /* E */ while(1); } sensor_index = k; sensor_model = type[k]; $0812,X $5E $0813,X $5F } /***************************************************************************/ 094C 094E 0950 0952 0954 0956 0958 095A 095C 095D 0960 0962 0965 0967 B6 A4 B7 34 34 34 34 BE 58 D6 B7 D6 B7 81 03 F0 65 65 65 65 65 65 LDA AND STA LSR LSR LSR LSR LDX LSLX 08 1C LDA 59 STA 08 1D LDA 5A STA RTS $03 #$F0 $65 $65 $65 $65 $65 $65 void sensor_slope() { k=portd & 0xf0; /* we only care about bits 4..7 */ k = k >> 4; /* right justify the variable */ slope = slope_const[k]; $081C,X $59 $081D,X $5A } /***************************************************************************/ 0968 096A 096C 096E 0970 0972 0974 0976 0978 097A 097C 097E 3F 3F B6 A0 B6 A2 24 3C 26 3C 20 81 62 61 62 20 61 4E 08 62 0 61 EE CLR CLR LDA SUB LDA SBC BCC INC BNE IN BRA RTS $62 $61 $62 #$20 $61 #$4E $097E $62 $097C $61 $096C void delay(void) /* just hang around for a while */ { for (i=0; i<20000; ++i); } AN1315 16 Sensors Freescale Semiconductor /***************************************************************************/ read_a2d(void) { /* read the a/d converter on channel 5 and accumulate the result in atodtemp */ 097F 0981 0983 0985 0987 0989 098B 3F 3F 3F B6 A8 A1 24 56 55 5B 5B 80 E4 21 CLR CLR CLR LDA EOR CMP BCC $56 $55 $5B $5B #$80 #$E4 $09AE 098D 098F 0991 0994 0996 0998 099A 099C 099E 09A0 09A2 09A4 09A6 09A8 A6 B7 0F B6 3F B7 BB B7 B6 B9 B7 B7 B6 B7 20 LDA #$20 09 STA $09 09 FD BRCLR 7,$09,$0991 08 LDA $08 57 CLR $57 58 STA $58 56 ADD $56 58 STA $58 57 LDA $57 55 ADC $55 57 STA $57 55 STA $55 58 LDA $58 56 STA $56 09AA 09AC 09AE 09B0 09B2 09B4 09B6 09B8 09BA 09BC 09BF 09C2 09C4 09C6 3C 20 B6 B7 B6 B7 3F A6 B7 CD CD BF B7 81 5B INC D7 BRA 56 LDA 58 STA 55 LDA 57 STA 9A CLR 64 LDA 9B STA 0B F1 JSR 0C 22 JSR 55 STX 56 STA RTS atodtemp=0; /* zero for accumulation */ for ( adcnt = 0 ; adcnt<100; ++adcnt) /* do 100 a/d conversions */ { adstat = 0x20; /* convert on channel 0 */ while (!(adstat & 0x80)); /* wait for a/d to complete */ atodtemp = addata + atodtemp; } $5B $0985 $56 $58 $55 $57 $9A #$64 $9B $0BF1 $0C22 $55 $56 atodtemp = atodtemp/100; return atodtemp; } /***************************************************************************/ 09C7 09C9 09CB 09CD 09CF 09D1 09D3 09D5 09D7 09D9 09DB 09DD 09DF 09E1 B6 B7 B6 B7 AB B7 B6 A9 B7 B7 B6 B6 B7 81 18 66 19 67 4C 67 66 1D 66 16 13 67 17 LDA STA LDA STA ADD STA LDA ADC STA STA LDA LDA STA RTS $18 $66 $19 $67 #$4C $67 $66 #$1D $66 $16 $13 $67 $17 void fixcompare (void) { q.b.hi =tcnthi; /* sets-up the timer compare for the next interrupt */ q.b.lo = tcntlo; q.l +=7500; /* ((4mhz xtal/2)/4) = counter period = 2us.*7500 = 15ms. */ ocmphi1 = q.b.hi; areg=tsr; /* dummy read */ ocmplo1 = q.b.lo; } /***************************************************************************/ 1FF6 09E2 09E4 09E6 09 33 33 33 E2 02 01 00 COM COM COM $02 $01 $00 void TIMERCMP (void) { portc =~ portc; portb =~ portb; porta =~ porta; /* timer service module */ /* service the lcd by inverting the ports */ AN1315 Sensors Freescale Semiconductor 17 09E8 AD DD 09EA 80 BSR RTI $09C7 fixcompare(); } /***************************************************************************/ void adzero(void) /* called by initio() to save initial xdcr's zero pressure offset voltage output */ { 09EB 09ED 09EF 09F1 09F3 09F5 09F7 3F 3F B6 A0 B6 A2 24 64 63 64 14 63 00 0B CLR CLR LDA UB LDA SBC BCC $64 $63 $64 #$14 $63 #$00 $0A04 for ( j=0; j<20; ++j) /* give the sensor time to "warm-up" and the power supply time to settle down */ { 09F9 CD 09 68 JSR $0968 delay(); } 09FC 09FE 0A00 0A02 0A04 0A07 0A09 0A0B 3C 26 3C 20 CD 3F B7 81 64 INC 02 BNE 63 INC EB BRA 09 7F JSR 5C CLR 5D STA RTS $64 $0A02 $63 $09EF $097F $5C $5D xdcr_offset = read_a2d(); } /***************************************************************************/ 0A0C 0A0E 0A10 0A12 0A14 0A16 0A18 0A1A 0A1C 0A1E 0A20 0A22 0A24 0A26 0A28 0A2A 0A2C A6 B7 3F 3F 3F A6 B7 B7 B7 B6 3F 3F B6 AD A6 B7 9A 20 09 02 01 00 FF 06 05 04 13 1E 16 1F 9F 40 12 LDA STA CLR CLR CLR LDA STA STA STA LDA CLR CLR LDA BSR LDA STA CLI #$20 $09 $02 $01 $00 #$FF $06 $05 $04 $13 $1E $16 $1F $09C7 #$40 $12 0A2D 0A2F 0A31 0A33 0A35 0A37 0A39 0A3C 0A3E A6 B7 A6 B7 A6 B7 CD AD 81 CC LDA 02 STA BE LDA 01 STA C4 LDA 00 STA 09 21 JSR AD BSR RTS #$CC $02 #$BE $01 #$C4 $00 $0921 $09EB void initio (void) /* setup the I/O */ { adstat = 0x20; /* power-up the A/D */ porta = portb = portc = 0; ddra = ddrb = ddrc = 0xff; areg=tsr; /* dummy read */ ocmphi1 = ocmphi2 = 0; areg = ocmplo2; /* clear out output compare 2 if it happens to be set */ fixcompare(); /* set-up for the first timer interrupt */ tcr = 0x40; CLI; /* let the interrupts begin ! /* write CAL to the display */ portc = 0xcc; /* C */ */ portb = 0xbe; /* A */ porta = 0xc4; /* L */ sensor_type(); /* get the model of the sensor based on J1..J3 */ adzero(); /* auto zero */ } /***************************************************************************/ void cvt_bin_dec(unsigned long arg) /* First converts the argument to a five digit decimal value. The msd is in the lowest address. Then leading zero suppress the value and write it to the display ports. The argument value is 0..65535 decimal. */ 009D 0A3F BF 9D 0A41 B7 9E { STX STA $9D $9E AN1315 18 Sensors Freescale Semiconductor 009F 00A0 0A43 0A45 0A47 0A49 3F B6 A1 24 9F 9F 05 07 CLR LDA CMP BCC $9F $9F #$05 $0A52 0A4B 97 0A4C 6F 50 TAX CL $50,X 0A4E 0A50 0A52 0A54 0A56 0A58 3C 20 3F B6 A1 24 9F F3 9F 9F 04 7A INC BRA CLR LDA CMP BCC $9F $0A45 $9F $9F #$04 $0AD4 0A5A 0A5B 0A5C 0A5F 0A61 0A63 0A65 0A67 0A69 0A6C 0A6E 97 58 D6 B0 B7 B6 A8 B7 D6 A8 B2 TAX LSLX 08 0B LDA 9E SUB 58 STA 9D LDA 80 EOR 57 STA 08 0A LDA 80 EOR 57 SBC char i; unsigned long l; for ( i=0; i < 5; ++i ) { digit[i] = 0x0; /* put blanks in all digit positions */ } for ( i=0; i < 4; ++i ) { if ( arg >= dectable [i] ) $080B,X $9E $58 $9D #$80 $57 $080A,X #$80 $57 0A70 BA 58 0A72 22 5C ORA BHI $58 $0AD0 0A74 0A76 0A77 0A7A 0A7C 0A7F 0A81 0A83 0A85 0A87 0A89 0A8B 0A8D 0A8F 0A91 0A94 0A97 0A99 0A9B 0A9D 0A9F 0AA1 0AA3 0AA5 0AA7 0AA9 0AAB 0AAD 0AAF 0AB2 0AB4 0AB6 0AB8 0ABA 0ABC 0ABE 0AC0 0AC2 0AC4 0AC6 0AC8 0ACA LDX LSLX LDA STA LDA STA LDA STA LDA STA LDA STA LDA STA JSR JSR STX STA LDX STA LDX LDA CLR STA LDA STA LDA STA JSR STX STA COM NEG BNE INC LDA ADD STA LDA ADC STA STA $9F { BE 58 D6 B7 D6 B7 B6 B7 B6 B7 B6 B7 B6 B7 CD CD BF B7 BE E7 BE E6 3F B7 B6 B7 B6 B7 CD BF B7 33 30 26 3C B6 BB B7 B6 B9 B7 B7 9F 08 A0 08 A1 9E 58 9D 57 A0 9A A1 9B 0B 0C 57 58 9F 50 9F 50 57 58 A0 9A A1 9B 0B 57 58 57 58 02 57 58 9E 58 57 9D 57 9D 0A 0B F1 22 D2 $080A,X $A0 $080B,X $A1 $9E $58 $9D $57 $A0 $9A $A1 $9B $0BF1 $0C22 $57 $58 $9F $50,X $9F $50,X $57 $58 $A0 $9A $A1 $9B $0BD2 $57 $58 $57 $58 $0ABE $57 $58 $9E $58 $57 $9D $57 $9D l = dectable[i]; digit[i] = arg / l; arg = arg-(digit[i] * l); AN1315 Sensors Freescale Semiconductor 19 0ACC B6 58 0ACE B7 9E LDA STA $58 $9E } } 0AD0 0AD2 0AD4 0AD6 0AD8 0ADA 0ADC 0ADE 0AE0 3C 20 B6 B7 B6 B7 BE B6 E7 9F 80 9E 58 9D 57 9F 58 50 INC BRA LDA STA LDA STA LDX LDA STA 0AE2 0AE3 0AE5 0AE7 0AE9 0AEB 0AED 0AF0 0AF2 0AF4 0AF6 0AF8 0AFA 0AFC 0AFE 0B00 9B 3D 26 3F 20 BE D6 B7 3D 26 3D 26 3F 20 BE D6 52 04 02 07 52 08 00 02 52 08 53 04 01 07 53 08 00 SEI TST BNE CLR BRA LDX LDA STA TST BNE TST BNE CLR BRA LDX LDA $52 $0AEB $02 $0AF2 $52 $0800,X $02 $52 $0AFE $53 $0AFE $01 $0B05 $53 $0800,X 0B03 0B05 0B07 0B0A B7 BE D6 B7 01 54 08 00 00 STA LDX LDA STA $01 $54 $0800,X $00 0B0C 0B0E 0B10 0B12 0B14 0B16 0B19 0B1A 0B1C 0B1E B6 A8 A1 24 BE D6 4C B7 3D 26 60 80 83 08 54 08 00 LDA EOR CMP BCC LDX LDA INCA STA TST BNE $60 #$80 #$83 $0B1C $54 $0800,X 0B20 0B22 0B25 0B27 0B29 0B2C 0B2D BE D6 B7 BE D6 4C B7 54 08 00 00 53 08 00 LDX LDA STA LDX LDA INCA STA $54 $0800,X $00 $53 $0800,X 00 60 0F 01 $9F $0A54 $9E $58 $9D $57 $9F $58 $50,X digit[i] = arg; /* now zero suppress and send the lcd pattern to the display */ SEI; if ( digit[2] == 0 ) /* leading zero suppression */ portc = 0; else portc = ( lcdtab[digit[2]] ); /* 100's digit */ if ( digit[2] == 0 && digit[3] == 0 ) portb=0; else portb = ( lcdtab[digit[3]] ); porta = ( lcdtab[digit[4]] ); /* 10's digit */ /* 1's digit */ /* place the decimal point only if the sensor is 15 psi or 7.5 psi */ if ( sensor_index < 3 ) porta = ( lcdtab[digit[4]]+1 ); /* add the decimal point to the lsd */ $00 $60 $0B2F if(sensor_index ==0) /* special case */ { porta = ( lcdtab[digit[4]] ); /* get rid of the decimal at lsd */ portb = ( lcdtab[digit[3]]+1 ); /* decimal point at middle digit */ $01 } 0B2F 9A 0B30 CD 09 68 0B33 81 CLI JSR RTS CLI; $0968 delay(); } /****************************************************************/ void display_psi(void) /* At power-up it is assumed that the pressure or vacuum port of the sensor is open to atmosphere. The code in initio() delays for the sensor and power supply to stabilize. One hundred A/D conversions are averaged. That result is called xdcr_offset. This routine calls the A/D routine which performs one hundred conversions, divides the result by 100 and returns the value. If the value returned is less than or equal to the xdcr_offset, the value of xdcr_offset is substituted. If the value returned is greater than xdcr_offset, xdcr_offset is subtracted from the AN1315 20 Sensors Freescale Semiconductor returned value. */ { 0B34 0B37 0B39 0B3B 0B3D 0B3F 0B41 0B43 0B45 0B47 0B49 0B4B 0B4D 0B4F 0B51 0B53 0B55 0B57 0B59 0B5B 0B5D 0B5F 0B61 0B63 0B66 0B68 0B6A 0B6C 0B6E CD 3F B7 B0 B7 B6 A8 B7 B6 A8 B2 BA 22 B6 B7 B6 B7 B6 B0 B7 B6 B2 B7 CD B6 B7 B6 B7 B6 09 7F 55 56 5D 58 5C 80 57 55 80 57 58 08 5C 55 5D 56 56 5D 56 55 5C 55 09 4C 56 58 55 57 5E JSR CLR STA SUB STA LDA EOR STA LDA EOR SBC ORA BHI LDA STA LDA STA LDA SUB STA LDA SBC STA JSR LDA STA LDA STA LDA $097F $55 $56 $5D $58 $5C #$80 $57 $55 #$80 $57 $58 $0B57 $5C $55 $5D $56 $56 $5D $56 $55 $5C $55 $094C $56 $58 $55 $57 $5E 0B70 0B72 0B74 0B76 0B79 0B7B 0B7D 0B7F 0B81 0B83 0B85 0B86 0B88 0B8A 0B8C 0B8E 0B90 0B92 0B94 0B97 0B99 0B9B 0B9D 0B9F 0BA1 0BA3 0BA5 0BA7 0BA9 0BAB 0BAD 0BAF 0BB1 0BB3 0BB5 0BB8 0BBA 0BBC B7 B6 B7 CD BF B7 3F 3F 3F 3F 9F B7 B6 B7 B6 B7 B6 B7 CD 3F A6 B7 A6 B7 A6 B7 B6 B7 B6 B7 B6 B7 B6 B7 CD B6 B7 B6 9A 5F 9B 0B D2 55 56 89 88 81 80 STA LDA STA JSR STX STA CLR CLR CLR CLR TXA STA LDA STA LDA STA LDA STA JSR CLR LDA STA LDA STA LDA STA LDA STA LDA STA LDA STA LDA STA JSR LDA STA LDA $9A $5F $9B $0BD2 $55 $56 $89 $88 $81 $80 82 56 83 59 8A 5A 8B 08 70 90 01 91 86 92 A0 93 88 8C 89 8D 8A 8E 8B 8F 08 B1 96 55 97 while(1) { atodtemp = read_a2d(); /* atodtemp = raw a/d ( 0..255 ) */ if ( atodtemp <= xdcr_offset ) atodtemp = xdcr_offset; atodtemp -= xdcr_offset; /* remove the offset */ sensor_slope(); /* establish the slope constant for this output */ atodtemp *= sensor_model; MULTP[0] = MULCAN[0] = 0; MULTP[1] = atodtemp; $82 $56 $83 $59 $8A $5A $8B $0870 $90 #$01 $91 #$86 $92 #$A0 $93 $88 $8C $89 $8D $8A $8E $8B $8F $08B1 $96 $55 $97 MULCAN[1] = slope; mul32(); /* analog value * slope based on J1 through J3 */ DVSOR[0] = 1; /* now divide by 100000 */ DVSOR[1] = 0x86a0; DVDND[0] = MULCAN[0]; DVDND[1] = MULCAN[1]; div32(); atodtemp = QUO[1]; /* convert to psi */ AN1315 Sensors Freescale Semiconductor 21 0BBE 0BC0 0BC2 0BC5 0BC8 B7 BE CD CC 81 56 55 0A 3F 0B 34 STA LDX JSR JMP RTS $56 $55 $0A3F $0B34 cvt_bin_dec( atodtemp ); /* convert to decimal and display */ } } /***************************************************************************/ 0BC9 0BCC 0BCF 0BD1 0BD2 0BD4 0BD6 0BD7 0BD9 0BDB 0BDD 0BDF 0BE0 0BE2 0BE4 0BE6 0BE8 0BE9 0BEB 0BED 0BEE 0BF0 0BF1 0BF3 0BF4 0BF6 0BF8 0BF9 CD CD 20 81 BE B6 42 B7 BF BE B6 42 BB B7 BE B6 42 BB B7 97 B6 81 3F 5F 3F 3F 5C 38 0A 0C 0B 34 FE 0BFB 0BFD 0BFF 0C01 0C03 0C05 0C07 0C09 0C0B 0C0D 0C0F 0C11 0C13 0C15 0C17 0C19 0C1B 0C1C 0C1D 0C1F 0C21 0C22 0C23 0C24 0C26 0C27 1FFE 39 39 39 B6 B0 B7 B6 B2 B7 24 B6 BB B7 B6 B9 B7 99 59 39 24 81 53 9F BE 53 81 0B 57 A2 A3 A2 9B A2 A3 9A A3 0D 9B A2 A2 9A A3 A3 58 9B A4 A5 57 9B A5 A5 58 9A A5 A5 A4 A4 A2 A3 58 A4 D8 A4 JSR JSR BRA RTS LDX LDA MUL STA STX LDX LDA MUL ADD STA LDX LDA MUL ADD STA TAX LDA RTS CLR CLRX CLR CLR INCX LSL $0A0C $0B34 $0BCF ROL ROL ROL LDA SUB STA LDA SBC STA BCC LDA ADD STA LDA ADC STA SEC ROLX ROL BCC RTS COMX TXA LDX COMX RTS $57 $A2 $A3 $A2 $9B $A2 $A3 $9A $A3 $0C1C $9B $A2 $A2 $9A $A3 $A3 void main() { initio(); /* set-up the processor's i/o */ display_psi(); while(1); /* should never get back to here */ } $58 $9B $A4 $A5 $57 $9B $A5 $A5 $58 $9A $A5 $A5 $A4 $A4 $A2 $A3 $58 $A4 $0BF9 $A4 C9 SYMBOL TABLE LABEL VALUE LABEL VALUE LABEL VALUE LABEL VALUE AN1315 22 Sensors Freescale Semiconductor ADDEND DIV151 DIV167 MINUE MULTP SUBTRA TIMEROV __MUL __STARTUP __longAC adstat arg cvt_bin_dec dectable div32 i icaplo2 k main ocmphi2 plmb portd scicntl1 sensor_index slope tcntlo xdcr_offset 006C 08BF 0906 0074 0080 0078 091F 0000 0000 0057 0009 009D 0A3F 080A 08B1 0061 001D 0065 0BC9 001E 000B 0003 000E 0060 0059 0019 005C | | | | | | | | | | | | | | | | | | | | | | | | | | | AUGEND DIV153 DVDND MNEXT QUO SUM __LDIV __MUL16x16 __STOP adcnt adzero atodtemp ddra delay eeclk icaphi1 initio l misc ocmplo1 porta q scicntl2 sensor_model slope_const tcr 0070 08CE 008C 0882 0094 0068 0BF1 0BD2 0000 005B 09EB 0055 0004 0968 0007 0014 0A0C 0000 000C 0017 0000 0066 000F 005E 081C 0012 | | | | | | | | | | | | | | | | | | | | | | | | | | CNT DIV163 DVSOR MTEMP ROTATE TIMERCAP __LongIX __RDIV __SWI add32 aregnthi b ddrb digit fixcompare icaphi2 isboth lcdtab mul32 ocmplo2 portb read_a2d scidata sensor_slope sub32 tsr 0098 08D0 0090 0084 089C 091E 009A 0C22 091C 083C 001A 0000 0005 0050 09C7 001C 0002 0800 0870 001F 0001 097F 0011 094C 0856 0013 | | | | | | | | | | | | | | | | | | | | | | | | | | DIFF DIV165 IRQ MULCAN SCI TIMERCMP __MAIN __RESET __WAIT addata aregntlo bothbytes ddrc display_psi hi icaplo1 j lo ocmphi1 plma portc scibaud scistat sensor_type tcnthi type 007C 0905 091D 0088 0920 09E2 0BC9 1FFE 0000 0008 001B 0002 0006 0B34 0000 0015 0063 0001 0016 000A 0002 000D 0010 0921 0018 0812 MEMORY USAGE MAP ('X' = Used, '-' = Unused) 0800 0840 0880 08C0 : : : : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0900 0940 0980 09C0 : : : : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0A00 0A40 0A80 0AC0 : : : : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0B00 0B40 0B80 0BC0 : : : : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0C00 0C40 0C80 0CC0 : : : : XXXXXXXXXXXXXXXX ---------------------------------------------- XXXXXXXXXXXXXXXX ---------------------------------------------- XXXXXXXX----------------------------------------------------- ------------------------------------------------------------- 1E00 1E40 1E80 1EC0 : : : : ------------------------------------------------------------- ------------------------------------------------------------- ------------------------------------------------------------- -----------------------------------------------------------X- 1F00 1F40 1F80 1FC0 : : : : ------------------------------------------------------------- ------------------------------------------------------------- ------------------------------------------------------------- -----------------------------------------------XXXXXXXXXXXXXX All other memory blocks unused. Errors Warnings : : 0 0 AN1315 Sensors Freescale Semiconductor 23 How to Reach Us: Home Page: www.freescale.com E-mail: [email protected] USA/Europe or Locations Not Listed: Freescale Semiconductor Technical Information Center, CH370 1300 N. Alma School Road Chandler, Arizona 85224 +1-800-521-6274 or +1-480-768-2130 [email protected] Europe, Middle East, and Africa: Freescale Halbleiter Deutschland GmbH Technical Information Center Schatzbogen 7 81829 Muenchen, Germany +44 1296 380 456 (English) +46 8 52200080 (English) +49 89 92103 559 (German) +33 1 69 35 48 48 (French) [email protected] Japan: Freescale Semiconductor Japan Ltd. Headquarters ARCO Tower 15F 1-8-1, Shimo-Meguro, Meguro-ku, Tokyo 153-0064 Japan 0120 191014 or +81 3 5437 9125 [email protected] Asia/Pacific: Freescale Semiconductor Hong Kong Ltd. Technical Information Center 2 Dai King Street Tai Po Industrial Estate Tai Po, N.T., Hong Kong +800 2666 8080 [email protected] For Literature Requests Only: Freescale Semiconductor Literature Distribution Center P.O. Box 5405 Denver, Colorado 80217 1-800-441-2447 or 303-675-2140 Fax: 303-675-2150 [email protected] AN1315 Rev. 2 05/2005 Information in this document is provided solely to enable system and software implementers to use Freescale Semiconductor products. There are no express or implied copyright licenses granted hereunder to design or fabricate any integrated circuits or integrated circuits based on the information in this document. Freescale Semiconductor reserves the right to make changes without further notice to any products herein. Freescale Semiconductor makes no warranty, representation or guarantee regarding the suitability of its products for any particular purpose, nor does Freescale Semiconductor assume any liability arising out of the application or use of any product or circuit, and specifically disclaims any and all liability, including without limitation consequential or incidental damages. “Typical” parameters that may be provided in Freescale Semiconductor data sheets and/or specifications can and do vary in different applications and actual performance may vary over time. All operating parameters, including “Typicals”, must be validated for each customer application by customer’s technical experts. Freescale Semiconductor does not convey any license under its patent rights nor the rights of others. Freescale Semiconductor products are not designed, intended, or authorized for use as components in systems intended for surgical implant into the body, or other applications intended to support or sustain life, or for any other application in which the failure of the Freescale Semiconductor product could create a situation where personal injury or death may occur. Should Buyer purchase or use Freescale Semiconductor products for any such unintended or unauthorized application, Buyer shall indemnify and hold Freescale Semiconductor and its officers, employees, subsidiaries, affiliates, and distributors harmless against all claims, costs, damages, and expenses, and reasonable attorney fees arising out of, directly or indirectly, any claim of personal injury or death associated with such unintended or unauthorized use, even if such claim alleges that Freescale Semiconductor was negligent regarding the design or manufacture of the part. Freescale™ and the Freescale logo are trademarks of Freescale Semiconductor, Inc. All other product or service names are the property of their respective owners. © Freescale Semiconductor, Inc. 2005. All rights reserved.