Philips Semiconductors Microcontroller Products Application note Airflow measurement using the 83/87C752 and "C" INTRODUCTION This application note describes a low-cost airflow measurement device based on the Philips 83/87C752 microcontroller. Airflow measurement--determining the volume of air transferred per unit time (cubic feet per minute, or cfm)--is intrinsic to a variety of industrial and scientific processes. Airflow computation depends on three simultaneous physical air measurements--velocity, pressure, and temperature. This design includes circuits and sensors allowing the 8XC752 to measure all three parameters. The design also includes seven-segment LED displays, discrete LEDs, and pushbutton switches to allow selective display of airflow, temperature, and pressure. Furthermore, airflow is continuously compared with a programmer-defined setpoint. Should the measured airflow exceed the setpoint, an output relay is energized. In actual application, this relay output could be used to signal the setpoint violation (via lamp or audio annunciator) or otherwise control the overall process (e.g., emergency process shutdown). Of course, the setpoint, comparison criteria (greater, less than, etc.) and violation response (relay on, relay off) are easily changed by program modification to meet actual application requirements. Referring to Figure 1, the overall operation of the airflow device is as follows. Normally the unit continuously displays the airflow (in cfm) on the seven-segment displays. The discrete CFM LED is also lit to confirm the parameter being displayed. Pressing the TEMP pushbutton switches the display to temperature (in degrees C) and lights the TEMP LED. As long as the pushbutton remains pressed, the temperature is displayed. When the pushbutton is released, the display reverts to the default pressure display. Similarly, pressing the PSI pushbutton displays the atmospheric pressure (in pounds per square inch) and lights the PSI LED. The pressure is displayed as long as the pushbutton is pressed, and the default airflow display resumes when the pushbutton is released. Finally, pressing the SET-POINT pushbutton displays the programmed airflow setpoint (in cfm) and lights the SET-POINT LED. Again, releasing the pushbutton causes the display to revert to the default airflow measurement. CONTROL PROGRAMMING IN "C" While, thanks to advanced semiconductor processing, hardware price/performance continues to improve, software development technology has changed little over time. Thus, given ever-rising costs for qualified personnel, software "productivity" is arguably in decline. Indeed, for low-unit cost and/or low-volume applications, software development has emerged as the major portion of total design cost. Furthermore, Seven Segment LED Seven Segment LED AN429 beyond the initial programming cost, "hidden" costs also arise in the form of life-cycle code maintenance and revision and lost revenue/market share due to excessive time-to-market. Traditionally, control applications have been programmed in assembly language to overcome microcontroller resource and performance constraints. Now, thanks to more powerful microcontrollers and advanced compiler technology, it is feasible to program control applications using a High-Level Language (HLL). The primary benefit of using an HLL is obvious--one HLL program "statement" can perform the same function as many lines of assembly language. Furthermore, a well-written HLL program will typically be more "readable" than an assembly language equivalent, resulting in reduced maintenance and revision/upgrade costs. Of the many popular HLLs, the "C" language has emerged as the major contender for control applications. More than other languages, C gives the programmer direct access to, and control of, low-level hardware resources--a requirement for deterministic, real-time I/O applications. Furthermore, C is based on a "minimalist" philosophy in which the language performs only those functions explicitly requested by the programmer. This approach is well-suited for control applications, which are often characterized by strict cost and performance requirements. Seven Segment LED LEDs CFM TEMP PSI SETPOINT Pushbuttons SU00376 Figure 1. Airflow Meter Front Panel December 1990 1 Revision date: June 1993 Philips Semiconductors Microcontroller Products Application note Airflow measurement using the 83/87C752 and "C" 8XC752 OVERVIEW The 83C752/87C752 (ROM/EPROM-based) combine the performance advantages of the 8-bit 80C51 architecture with the low cost, power consumption, and size/pin count of a 4-bit microcontroller. Therefore, the 8XC752 is uniquely capable of bringing high processing speed and HLL programming to even the most cost-sensitive applications such as handheld (battery driven) instruments, automotive distributed processing, "smart" appliances, and sophisticated consumer electronics. Obviously, the 8XC752 can be used for cost-reduced versions of existing 8-bit applications. The device can also replace similarly priced 4-bit devices to achieve benefits of higher performance and, most importantly, easier s/w development including the use of HLL. Indeed, the component and system design costs associated with the 8XC752 are so low that it is a viable candidate for first-time computerization of formerly non-microcontroller-based designs. Figure 2 shows the block diagram of the 8XC752. Major features of the device include the following. Full-Function, High-Speed (to 16MHz) 80C51 CPU Core The popular 80C51 architecture features 8and 16-bit processing and high-speed execution. Most instructions execute in a single machine cycle (the slowest instructions require only two cycles). Though a streamlined architecture, the CPU core, December 1990 AN429 unlike 4-bit devices, includes all the basic capabilities (such as stack, multiply instruction, interrupts, etc.) required to support HLL compilation. The CPU core also includes a unique Boolean processor which is well-suited for the bit-level processing and I/O common to control applications. Another virtue of the CMOS process is superior tolerance to variations in VCC, a requirement inherent in the targeted applications. The EPROM-based device (87C752) operates over a VCC range of 4.5V to 5.5V, while the ROM-based device (83C752) will operate from 4V to 6V. Low-Power CMOS and Power-Saving Operation Modes On-Chip ROM (83C752), EPROM (87C752), and RAM Thanks to the advanced CMOS process, the 8XC752 features extremely low power consumption, which helps to extend battery life in handheld applications and otherwise reduce power supply and thermal dissipation costs and reliability concerns. Low ACTIVE mode (full-speed operation) power consumption--only 11mA typical at 12MHz--is further complemented by two program-initiated power-saving operation modes--IDLE and POWER-DOWN. The 8XC752 integrates 2048 bytes of program ROM/EPROM and 64 bytes of data RAM. This relatively small amount of memory reflects the fact that the targeted applications, though they may require high-speed processing, are typically characterized by simple algorithms and data structures. High code efficiency of the architecture means even this small amount of memory can effectively support the use of C. If necessary, the judicious use of assembly language can help bypass code size (and performance) constraints. In idle mode, CPU instruction processing stops while on-chip I/O and RAM remain powered. Power consumption drops to 1.5A (typical, 12MHz) until processing is restarted by interrupt or reset. Power-down mode cuts power consumption further (to only 10A typical at 12MHz) by stopping both instruction and I/O processing. Return to full-speed operation from power-down mode is via reset. Note that power consumption can be further cut by reducing the clock frequency as much as application performance requirements allow, as shown in Figure 3. 2 Five-Channel 8-Bit A/D Converter Most control applications are characterized by the need to monitor "real-world" (i.e., analog) parameters. To this end, the 8XC752 includes a medium-speed (40 clock cycle conversion) 8-bit analog-to-digital (A/D) converter. Five separate input lines are provided along with multiplexer logic to select an input for conversion. The A/D converters speed, resolution, and accuracy are more than adequate to measure temperature, pressure, and other common environmental parameters. Philips Semiconductors Microcontroller Products Application note Airflow measurement using the 83/87C752 and "C" AN429 P0.0-P0.4 PORT 0 DRIVERS VCC I2C CONTROL PWM VSS RAM ADDR REGISTER PORT 0 LATCH RAM B REGISTER PORT 2 LATCH ROM/ EPROM STACK POINTER ACC PROGRAM ADDRESS REGISTER TMP1 TMP2 ALU PCON I2CFG I2STA I2DAT I2CON IE TH0 TL0 RTH RTL PSW TCON INTERRUPT, SERIAL PORT AND TIMER BLOCKS BUFFER PC INCREMENTER RST TIMING AND CONTROL INSTRUCTION REGISTER PROGRAM COUNTER DPTR PD PORT 1 LATCH PORT 3 LATCH PORT 1 DRIVERS PORT 3 DRIVERS P1.0-P1.7 P3.0-P3.7 OSCILLATOR ADC X1 X2 AVSS AVCC SU00319 Figure 2. Block Diagram of the 8XC752 Timer/Counters Control applications, due to their "real-time" nature, invariably call for a variety of timing and counting capabilities. The 8XC752 meets the need by integrating three separate functions--a 16-bit auto-reload counter/timer, an 8-bit pulse width modulator (PWM) output/timer, and a fixed-rate timer for timebase generation. Together, these timing/counting resources can serve a range of tasks, including waveform generation, external event counting, elapsed time December 1990 calculation, periodic interrupt generation, and watchdog timer. I2C Bus The Inter-Integrated Circuit (I2C) bus is a patented serial peripheral interface. The virtue of I2C is the ability to expand system functionality with acceptable performance and minimum cost. Notably, the pin and interconnect count is radically reduced compared to expansion via a typical microprocessor bus--I2C requires only two 3 lines, while a parallel bus often consumes 20-30 lines and may call for extra glue logic (decoder, address latch, etc.). The 8XC752 I2C port allows easy connection to a wide variety of compatible peripherals such as LCD drivers, A/D and D/A converters, consumer/telecom and special-purpose memory (e.g., EEPROM). I2C can also be used to build distributed processing systems connecting multiple I2C-compatible microcontrollers. Philips Semiconductors Microcontroller Products Application note Airflow measurement using the 83/87C752 and "C" AN429 MAX ACTIVE ICC* 22 20 18 16 14 ICC mA TYP ACTIVE ICC* 12 10 8 6 MAX IDLE ICC** 4 2 TYP IDLE ICC** 4MHz 8MHz 12MHz 16MHz FREQ NOTES: Maximum ICC values taken at VCC = 5.5V and worst case temperature. Typical ICC values taken at VCC = 5.0V and 25oC. * ICC is measured with all output pins disconnected; X1 driven with tCLCH, tCHCL = 5ns, VIL = VSS + 0.5V, VIH = VCC - 0.5V; X2 n.c.; RST = port 0 = VCC. ICC will be slightly higher if a crystal oscillator is used. (This refers to AC Electrical Characteristics.) ** Idle ICC is measured with all output pins disconnected; X1 driven with tCLCH, tCHCL = 5ns, VIL = VSS + 0.5V, VIH = VCC - 0.5V; X2 n.c.; port 0 = VCC; RST = VSS. (This refers to AC Electrical Characteristics.) SU00377 Figure 3. ICC vs. FREQ 8XC752 PIN FUNCTIONS Since the 8XC752 is packaged in a cost/space-saving 28-pin package DIP or PLCC), a flexible mapping of I/O functions to pins is required to ensure the widest possible application coverage. Of the 28 pins, seven pins are allocated to basic functions, including digital power (VCC, VSS), analog reference (AVCC, AVSS), clock oscillator (X1, X2), and reset (RST). Thus, 21 pins, organized into three ports (5-bit port 0, 8-bit ports 1 and 3), are available for user I/O. P0.0 P0.1 P0.2 P0.3 P0.4 TTL IN/OUT (open drain), I2C clock (SCLK) TTL IN/OUT (open drain), I2C data (SDA) TTL IN/OUT (open drain) TTL IN/OUT (internal pull-up) TTL IN/OUT (internal pull-up), PWM output P1.0 P1.1 P1.2 P1.3 P1.4 P1.5 P1.6 P1.7 TTL IN/OUT (internal pull-up), A/D input channel 0 TTL IN/OUT (internal pull-up), A/D input channel 1 TTL IN/OUT (internal pull-up), A/D input channel 2 TTL IN/OUT (internal pull-up), A/D input channel 3 TTL IN/OUT (internal pull-up), A/D input channel 4 TTL IN/OUT (internal pull-up), INT0 interrupt input TTL IN/OUT (internal pull-up), INT1 interrupt input TTL IN/OUT (internal pull-up), TIMER 0 (T0) input Figure 4 shows the alternative uses for these 21 lines. As shown, the mapping is quite versatile, which maximizes the access to on-chip I/O functions and helps ensure full pin utilization. NOTE: P1.0-P1.4 may only be changed as a group, i.e., either all TTL I/O or all A/D inputs. However, when selected as A/D inputs, P1.0-P1.4 may also be used as TTL inputs. P3.0 P3.1 P3.2 P3.3 P3.4 P3.5 P3.6 P3.7 TTL IN/OUT (internal pull-up) TTL IN/OUT (internal pull-up) TTL IN/OUT (internal pull-up) TTL IN/OUT (internal pull-up) TTL IN/OUT (internal pull-up) TTL IN/OUT (internal pull-up) TTL IN/OUT (internal pull-up) TTL IN/OUT (internal pull-up) SU00378 Figure 4. 8XC752 I/O Port Description December 1990 4 Philips Semiconductors Microcontroller Products Application note Airflow measurement using the 83/87C752 and "C" AIRFLOW METER CIRCUIT DESCRIPTION Figure 5 is the schematic diagram of the airflow meter circuit. As shown, the 8XC752 is connected to the following function blocks. Discrete and Seven-Segment LED Display The seven-segment LEDs display the parameter of interest (airflow, temperature, pressure, or setpoint). A discrete LED associated with each parameter is lit when that parameter is being displayed. The seven-segment LEDs are identified as X0.1, X1, and X10, reflecting their decimal position (tenths, ones, and tens, respectively). Each display has eight data inputs (the seven segments and a decimal point) and common terminals which allow the display to be enabled or blanked. The eight data inputs, and the four discrete LEDs, are driven from port 3 of the 8XC752 via high-current driver U2 and current limiting resistors RP1. Since all the segmented and discrete LEDs share common data lines, data display must be time multiplexed. Transistors Q1-Q4 connect to separate output lines of port 0, allowing a particular seven-segment LED or the discrete LEDs (as a group) to be individually enabled for display. This type of LED multiplexing is quite common since, at a fast enough refresh rate, the switching between displays is not perceptible by the operator. The major benefit is the reduction of I/O lines required (without multiplexing, 28, rather than 8, data lines would be required). December 1990 Pushbutton Switch Inputs Three pushbuttons select the parameter to be displayed--temperature, pressure, or setpoint (when no button is pressed, airflow is displayed). The four states (SW1, SW2, SW3, or no button pressed) are effectively encoded onto two port 1 input lines (taking advantage of the capability to use port 1 lines configured as A/D for TTL input) as follows: No button pressed SW1 (TEMP) pressed SW2 (PSI) pressed SW3 (SETPOINT) pressed P1.3 HIGH LOW HIGH LOW P1.4 HIGH HIGH LOW LOW The only impact of this encoding scheme is that SW3 has a higher priority than the other pushbuttons--a factor of no concern in this simple application. Similarly, latching, debouncing, rollover, or other conditioning of the pushbutton inputs is not required. AN429 assumed to be a negative-going pulse train with less than 10% duty cycle. Air Pressure Sensor To determine airflow, the air velocity must be factored by ambient pressure--for a given velocity (and temperature), lower/higher atmospheric pressure will correspond with lower/higher airflow. The pressure sensor, U3, outputs a voltage differential corresponding to the pressure. Amplifier U4 conditions the pressure sensor output to the range of AVSS to AVCC (the analog references for the 8XC752 A/D converter). The conditioned pressure sensor output is presented to A/D input P1.0. To calibrate the pressure sensor, press the PSI pushbutton and adjust the gain pot (R1) until the display matches the local atmospheric pressure in pounds per square inch (14.7 at sea level). Setpoint Control Air Temperature Sensor This is simply a variable resistor voltage divider which serves to establish an analog voltage corresponding to an airflow threshold at which action is taken. It connects to a port 1 A/D input. Similar to pressure, ambient temperature also affects the airflow calculation. For a given air velocity (and pressure), higher/lower temperature will correspond with lower/higher airflow. Temperature sensor U5 outputs an absolute voltage corresponding to temperature. Amplifier U6 conditions the temperature sensor output to the range AVSS to AVCC for connection to A/D input P1.1. Relay Output When an airflow setpoint violation is detected, DPDT relay K1 is energized via P1.6, which is configured as a TTL output, buffered by transistor Q5. Flowmeter Input Measurement of the air velocity is via an air turbine tachometer connected, via optoisolator U7, to P1.5, which is configured as a TTL input. The tachometer input is 5 To calibrate the temperature sensor, adjust the gain pot (R5) so that the display (while pressing the TEMP pushbutton) matches the measured output of U5 (LM35). Figure 6 summarizes the usage of the 8XC752 I/O lines in this application. Philips Semiconductors Microcontroller Products Application note Airflow measurement using the 83/87C752 and "C" SEVEN-SEGMENT NUMERIC DISPLAY X1 X10 CR13 LTS-367P 10 9 8 5 4 2 3 7 C5 U2 UDN2585A 100nF P30 P31 P20 P33 P34 P35 P36 P37 9 1 2 3 4 5 6 7 8 VSS IN1 IN1 IN1 IN1 IN1 IN1 IN1 IN1 RP1 75 18 17 16 15 14 13 12 11 10 OUT1 OUT1 OUT1 OUT1 OUT1 OUT1 OUT1 OUT1 SUB AN429 X0.1 CR14 LTS-367P 10 9 8 5 4 2 3 7 A B C D E F G DP COMS 1 6 CR15 LTS-367P 10 9 8 5 4 2 3 7 A B C D E F G DP COMS 1 6 A B C D E F G DP COMS 1 6 16 15 14 13 12 11 10 9 1 2 3 4 5 6 7 8 CR1 CFM CR2 TEMP CR3 PSI CR4 SETPOINT VCC R17 10k 01 2N7000 R18 VCC R15 10k VCC R16 10k 02 2N7000 03 2N7000 04 2N7000 10k 28 100F C2 11 22pF C3 VCC R19 10k U1 87C752 VCC C1 X1 12MHz 22pF C4 + VCC 10F 10 9 24 23 6 7 8 19 VREF C6 100nF 18 12 VDD P3.7 XTAL1 P3.6 P3.5 P3.4 XTAL2 P3.3 P3.2 RST P3.1 P3.0 PWM P0.3 T0 P0.2 INT1 SDA INT0 SCL ADC4 ADC3 AVCC ADC2 ADC1 AVSS ADC0 VSS R9 4.7k P37 P36 P35 P34 P33 P32 P31 P30 25 26 27 1 2 3 4 5 R10 4.7k R13 10k KP100A UE UT 1 UP+ 2 UP- UG PSI 1N4148 PRESSURE SENSOR SETPOINT 05 2N7000 CR12 R14 10k 1N4148 VCC 4 3 2 1 J3 J3 J3 J3 VCC +8 VOLTS +8 VOLTS +8 VOLTS GROUND VCC R1 100 R2 IN+ V+ RG1 8 RG2 2 IN- 7 OUT 6 REF 5 V- 4 1k 6 100F FLOWMETER INPUT R3 C9 U5 LM35A VDD CR6 1N4148 1 +VS VOUT J2 1 J2 2 6 2 5 3 4 3 1 2 R4 160k IN+ 1k V+ RG1 OUT R5 R6 5k C12 1F VDD C10 U6 AMP-02 VREF GND 8 2 6 REF 5 V- 4 RG2 IN- 7 100F R12 4.7k VREF CR7 1N4148 R7 100 TEMP SENSOR C11 100F VEE Figure 5. Schematic Diagram of the Airflow Meter Circuit December 1990 1 100 100F SETPOINT CONTROL U7 4NB5 R11 220 C8 U4 AMP-02 3 1 K1 TQ2E-5V 1N4148 VDD 3 + R8 10k CR5 1N4002 SW3 CR11 VEE VREF VCC SW2 CR10 J1 J1 J1 J1 J1 J1 SETPOINT SWITCHING TEMP 1N4148 22 21 20 17 16 15 14 13 VDD 4 SW1 CR9 VCC VEE VDD U3 1 4 5 6 2 3 VCC 6 SU00379 Philips Semiconductors Microcontroller Products Application note Airflow measurement using the 83/87C752 and "C" AN429 P0.0 P0.1 P0.2 P0.3 P0.4 TTL OUT--Enables the discrete LEDs TTL OUT--Enables the tenths digit seven-segment LED TTL OUT--Enables the ones digit seven-segment LED Pulled up TTL OUT--Enables the tens digit seven-segment LED P1.0 P1.1 P1.2 P1.3 P1.4 P1.5 P1.6 P1.7 A/D input--Connected to analog air pressure sensor A/D input--Connected to analog air temperature sensor A/D input--Connected to analog setpoint control TTL IN--One of two pushbutton input lines TTL IN--The second pushbutton input line INT0 interrupt input--Air turbine tachometer input TTL OUT--Setpoint relay control Pulled up NOTE: P1.0-P1.4 may only be changed as a group, i.e., either all TTL I/O or all A/D inputs. However, when selected as A/D inputs, P1.0-P1.4 may also be used as TTL inputs. P3.0 P3.1 P3.2 P3.3 P3.4 P3.5 P3.6 P3.7 TTL OUT--Seven-segment LEDs segment A, CFM discrete LED TTL OUT--Seven-segment LEDs segment B, TEMP discrete LED TTL OUT--Seven-segment LEDs segment C, PSI discrete LED TTL OUT--Seven segment LEDs segment D, SETPOINT discrete LED TTL OUT--Seven segment LEDs segment E TTL OUT--Seven segment LEDs segment F TTL OUT--Seven segment LEDs segment G TTL OUT--Seven segment LEDs segment DP SU00380 Figure 6. Airflow Meter I/O Port Usage SOFTWARE DEVELOPMENT PROCEDURE The airflow meter application software is almost entirely written in C using a development package from Franklin Software. The Franklin Software C compiler is a cross-compiler that runs on the IBM PC (and compatibles) while generating code suitable for execution by any 80C51-based product, including the 8XC752. For more information, contact: Franklin Software 888 Saratoga Ave., #2 San Jose, CA 95129 The process of developing a C program using the Franklin package (the process is similar for other third-party cross-compilers) is as follows: 1. The program is entered/edited on the PC using the programmer's preferred text editor. 3. Should compile errors (also known as syntax errors) occur, they are corrected by returning to step 1 until an error-free compile is achieved. 4. Before testing the compiled program, it needs to be combined, using the Franklin-supplied linker, with any required assembly language routines. Besides routines explicitly written by the programmer, every Franklin C program requires an assembly language startup routine (supplied by Franklin and, if necessary, edited by the programmer) which performs basic reset initialization and configuration operations before transferring control to the C program. 5. The compiled object code is tested for correct operation. This can either be accomplished by using an 80C51-family simulator running on the PC or by downloading the object code to an in-circuit emulator. The simulator 2. The program is compiled on the PC with the Franklin C compiler. December 1990 7 approach has the virtues of low cost and consolidation of all work on the PC at the cost of non-real-time operation/debug constraints (the simulator may execute 100-1000 times slower than the microcontroller). The in-circuit emulator provides real-time operation and the additional benefit of assisting hardware design debug at somewhat higher cost. 6. Should program execution prove faulty (known as semantic errors), return to step 1 until error-free operation is achieved. 7. The error-free (syntax and semantic) and linked object code, in the form of a .HEX file, is transferred to an EPROM programmer. Fitted with a suitable adaptor, the EPROM programmer can "burn" the object file into the targeted EPROM-based 80C51-family device. For ROM-based devices, the object file is transferred to the factory for custom masking. Philips Semiconductors Microcontroller Products Application note Airflow measurement using the 83/87C752 and "C" PROGRAM DESCRIPTION Figure 7 is a flowchart of the program; following the flowchart is the program listing. The flowchart shows the basic processing and flow, while the listing documents the details of the program's implementation. The program consists of four interrupt-driven (i.e., foreground) routines and a main program (i.e., background). The background program is entered at reset and executes forever, interrupted periodically by the foreground interrupts. Communication between the background program and the foreground handlers is via shared variables. The four interrupt routines are as follows. * multiplex () (INT3) Free-running Timer I generates an interrupt at approximately 1000Hz and is used to multiplex the seven-segment and discrete LED display data. In a round-robin manner, at each interrupt, the program turns off the previously enabled display and writes data to, and enables, the next display. Finally, the interrupt routine sets a pointer to the next display--at the next interrupt, that display will be refreshed. Thus, each display (tens, ones, tenths, discrete LEDs) will be refreshed every fourth interrupt, which is more than fast enough for a flicker-free display. December 1990 * read_switch () (INT6) The PWM prescaler is configured to generate a periodic interrupt (INT6) at about 97Hz. The program counts these interrupts, and every 32nd interrupt sets an "update" variable. The main program will change the display data when it detects that "update" is set and clear "update" to prepare for the next display cycle. Thus, display change frequency is about 33Hz (i.e., 33ms), which eliminates display glitches associated with pushbutton switch bounce. * calc_cfm () (INT0) The air velocity turbine tachometer drives the 8XC752 INT0 interrupt pin. At each interrupt, the program reads Timer 0, which keeps track of the elapsed time (the low 16 bits of a 24-bit count in microseconds) between INT0 interrupts. The high-order 8-bit elapsed time count is cleared for possible updating by the following routine. * overflow () (INT1) When Timer 0 overflows (generating an interrupt), the program increments the high-order 8 bits of a 24-bit variable, counting the microseconds between tachometer interrupts (handled by the previous routine). If this 8-bit value becomes too large (i.e., tachometer interrupts stop), a NOFLOW 8 AN429 variable is set, which will cause the main program to display an EEE out-of-range indicator on the seven-segment LEDs. With the interrupt handlers executing the low-level timing and I/O, the main program, which is entered on reset and executes forever, consists of only three major steps. The temperature/pressure compensated airflow is calculated. First, the "base" cfm rate, as tracked by the calc_cfm () tachometer interrupt is adjusted by removing the execution time of the calc_cfm () handler itself. Next, the temperature is determined (A/D channel 1), and airflow is compensated. Similarly, the air pressure is determined (A/D channel 0) and airflow compensated again. Now that the true airflow is calculated, it is compared with the setpoint (adjusted with the variable resistor), which is determined by reading A/D channel 2. If the airflow is greater than the setpoint, the relay is closed. Otherwise, the relay is opened. Finally, the UPDATE flag (set by the 33Hz read_switch () interrupt) is checked. If it is time to update, the data to be displayed is determined based on the pushbutton status and the state of the NOFLOW flag. The updated display data is initialized for later display on the LEDs by the multiplex () display refresh interrupt handler. Philips Semiconductors Microcontroller Products Application note Airflow measurement using the 83/87C752 and "C" AN429 Power-on RESET STARTUP.A51 main() Initialize pin levels and variables 1 Calculate base airflow Read temperature Compensate airflow for temperature Read air pressure Compensate airflow for air pressure Read airflow setpoint setpoint > airflow? N Close relay Y Open relay UPDATE (display) flag set? Y 2 N SU00381 Figure 7. Program Flowchart December 1990 9 Philips Semiconductors Microcontroller Products Application note Airflow measurement using the 83/87C752 and "C" AN429 2 Clear UPDATE flag NOFLOW flag set? Y N Display '0.00' SEL0 flag set? N Y SEL1 flag set? N Y Display overrange ('EEE') Y airflow > 30? N Display airflow (cfm) Display overrange ('EEE') SEL1 flag set? N Y Display air pressure (psi) Display setpoint (cfm) 1 SU00382 Figure 7. Program Flowchart (Continued) December 1990 10 Philips Semiconductors Microcontroller Products Application note Airflow measurement using the 83/87C752 and "C" AN429 multiplex() Timer 1 interrupt (INT3 1000Hz) DISP_PNTR = 0? Y Turn off display CR13 N Set discrete LED data Turn on discrete LEDs DISP_PNTR = 1 DISP_PNTR = 1? Y Turn off discrete LEDs N Set display CR15 data Turn on display CR15 DISP_PNTR = 2 DISP_PNTR = 2? Y Turn off display CR15 N Set display CR14 data Turn on display CR14 DISP_PNTR = 3 DISP_PNTR = 3? Y Turn off display CR14 N Set display CR13 data Turn on display CR13 DISP_PNTR = 0 RETurn SU00383 Figure 7. Program Flowchart (Continued) December 1990 11 Philips Semiconductors Microcontroller Products Application note Airflow measurement using the 83/87C752 and "C" AN429 overflow() read_switch() PWM interrupt (INT6 92Hz) Timer 0 interrupt (INT1) REFRESH REFRESH + 1 TICKS = TICKS + 1 REFRESH = 32? N TICKS > LOWEST_CFM N Y Y Set UPDATE flag CFM = 0 REFRESH = 0 TICKS = 0 Set NOFLOW flag RETurn RETurn calc_cfm() Tach interrupt (INT0) LOW = Timer 0 low byte Timer 0 low byte = 0 MID = Timer 0 high byte Timer 0 high byte = 0 HIGH = TICKS TICKS = 0 RETurn SU00384 Figure 7. Program Flowchart (Continued) December 1990 12 Philips Semiconductors Microcontroller Products Application note Airflow measurement using the 83/87C752 and "C" AN429 /* this program measures the air flow through a rotary flowmeter and displays the calculated cfm. the output of the flowmeter tachometer is a small duty cycle pulse train with period which is proportional to the flow. the flow is compensated for changes in pressure and temperature to maintain calibration. if the flow exceeds an adjustable setpoint it energizes a 2 form c relay for user application. */ */ these pragmas specify compiler command line options */ #pragma CODE #pragma SYMBOLS #pragma PL (60) #pragma PW (120) #pragma OT (3) #pragma ROM (SMALL) /* generate code /* and symbols /* 60 lines per page /* 120 cols per page */ */ */ */ /* single-chip mode */ */ include the 8XC752-specific definitions and the standard i/o library. */ #include #include */ define symbolic names for program constants */ #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define ZERO_K ONE_TENTH_CFM STD_TEMP STD_ATM LOWEST_CFM START_ADC0 START_ADC1 START_ADC2 START_ADC3 START_ADC4 ADCI ADCS FREERUN_I SEG_A CFM SEG_B DEGREES SEG_C PSI SEG_D SETPOINT SEG_E SEG_F SEG_G SEG_DP 2730 4444444L 2980 147 0x40 0x28 0x29 0x2a 0x2b 0x2c 0x10 0x08 0x10 0x01 0x01 0x02 0x02 0x04 0x04 0x08 0x08 0x10 0x20 0x40 0x80 typedef unsigned char byte; /* typedef unsigned int word; /* typedef unsigned long 1_word; /* #define TRUE 1 #define FALSE 0 December 1990 /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* 0 degrees centigrade in 1/10 kelvin 1/10 cfm in microseconds 25 degrees centigrade in 1/10 kelvin one atmosphere in 1/10 psi maximum period from meter 0x400000 commands to start appropriate a/d channel conversion cycle a/d converter status flags P3 P3 P3 P3 P3 P3 P3 P3 P3 P3 P3 P3 position position position position position position position position position position position position for for for for for for for for for for for for display segment 'cfm' led display segment 'degrees' led display segment 'psi' led display segment 'setpoint' led display segment display segment display segment display decimal byte data type is unsigned 8-bit word data type is unsigned 16-bit 1_word data type is unsigned 32-bit /* /* define logical true / false values for bit variables 13 'a' 'b' 'c' 'd' 'e' 'f' 'g' pt. */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ Philips Semiconductors Microcontroller Products Application note Airflow measurement using the 83/87C752 and "C" AN429 /* define look-up table of possible seven segment display characters. the table consists of 11 elements corresponding to the 10 digits ('0'-'9') and error symbol ('E') that can be displayed. Each element is defined by ANDing (|) the bit mask for each segment (SEG_A - SEG_G) comprising the character. the table contents need to be inverted before use to be compatible with U2 (udn2585a). for example, '~segments[3]' specifies the segment mask to display '3'. */ code byte segments [ ] = { SEG_A SEG_A SEG_A SEG_A SEG_A SEG_A SEG_A SEG_A SEG_A | SEG_B SEG_B | SEG_B | SEG_B SEG_B | | | SEG_B | SEG_B | SEG_B | | | | | | SEG_C SEG_C SEG_C SEG_C SEG_C SEG_C | SEG_C | SEG_C | SEG_C | SEG_D | SEG_E | SEG_F SEG_D | SEG_D | | SEG_D | SEG_D | SEG_E | | | SEG_D | SEG_D SEG_D | SEG_E SEG_F | SEG_F | SEG_F SEG_G | SEG_G | SEG_G | SEG_G | SEG_E | | SEG_E | SEG_F SEG_F | SEG_F | SEG_G | SEG_G | SEG_G , , , , , , , , , , /* /* /* /* /* /* /* /* /* /* /* 0 1 2 3 4 5 6 7 8 9 E */ */ */ */ */ */ */ */ */ */ */ } ; /* sbit sbit sbit sbit sbit sbit sbit sbit sbit sbit define the '752 special function bits which control i/o lines. note that i/o line (and constant) names are capitalized RELAY = 0x96; /* active hi to turn on setpoint relay STROBE_0 = 0x80; /* active hi to enable display status led's STROBE_1 = 0x81; /* active hi to enable display cr15 (tenths) STROBE_2 = 0x82; /* active hi to enable display cr14 (ones) NO_FLOW = 0x83; /* flag set when no flow detected STROBE_3 = 0x84; /* active hi to enable display cr13 (tens) SEL_0 = 0x93; /* active low pushbutton inputs used to SEL_1 = 0x94; /* select the display mode INTR = 0x95; /* UPDATE = 0x97; /* flag set when time to update display */ */ */ */ */ */ */ */ */ */ */ /* data data data data data data data data data data data data data data data define memory variables. note memory variable names are lower case word cfm; /* gas flow in tenths of a cfm word setpoint; /* relay setpoint in tenths of a cfm word degree_c /* temperature in tenths centigrade 1_word corr; /* intermediate calculation value word psi; /* pressure in tenths of a psi byte display0; /* variables to hold values for the byte display1; /* displays during refresh. byte display2; /* display0=status LEDs, display1=CR15, byte display3; /* display2=CR14, display3=CR13 byte disp_pntr; /* pointer to next display to enable byte refresh; /* counter determines display updates byte high; /* bits 16 - 23 of flow period byte middle; /* bits 8 - 15 of flow period byte low; /* bits 0 - 7 of flow period byte ticks; /* incremented by timer overflow */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ /* the program consists of four interrupt handlers (multiplex, read_switch, overflow, calc_cfm) and a main program. multiplex - refresh the seven-segment and discrete status LEDs read_switch - signal periodic pushbutton sampling and display update overflow - accumulate high order bits of time between tach pulses calc_cfm - accumulate low order bits of time between tach pulses main - calc airflow, control relay, sample pushbuttons, update display */ /* multiplex - use the free-running I timer to multiplex the seven-segment and discrete leds at approx. 1000 hz. */ December 1990 14 Philips Semiconductors Microcontroller Products Application note Airflow measurement using the 83/87C752 and "C" void multiplex () interrupt 3 { switch(disp_pntr) { case 0x00: STROBE_3 = FALSE; P3 = 0xff; P3 = display0; STROBE_0 = TRUE; disp_pntr = 1; break; case 0x01: STROBE_0 = FALSE; P3 = 0xff; P3 = display1; STROBE_1 = TRUE; disp_pntr = 2; break; case 0x02: STROBE_1 = FALSE; P3 = 0xff; P3 = display2; STROBE_2 = TRUE; disp_pntr = 3; break; case 0x03: STROBE_2 = FALSE; P3 = 0xff; P3 = display3; STROBE_3 = TRUE; disp_pntr = 0; } } /* /* /* /* /* turn off display cr13 */ turn off all segments */ load segments for led's */ turn on status led's */ increment ptr to display /* /* /* /* /* turn off status led's */ turn off all segments */ load segments for tenths turn on display cr15 */ increment ptr to display /* /* /* /* /* turn off display cr15 */ turn off all segments */ load segments for units */ turn on display cr14 */ increment ptr to display */ /* /* /* /* /* turn off display cr14 */ turn off all segments */ load segments for tens */ turn on display cr13 */ increment ptr to display */ /* read_switch - use the free running pwm prescaler to generate interrupts at 92 hz. every 32nd interrupt set the UPDATE flag which causes main () to sample the pushbuttons and update the led displays. */ void read_switch () interrupt 6 { if (refresh++ == 32) { UPDATE = TRUE; refresh = 0; } } /* overflow - whenever time0 overflows (from 0xffff to 0x0000) increment the variable 'ticks' which accumulates the highest order (16 - 23) bits of the gas flow period in microseconds. if the variable 'ticks' is greater than the period corresponding to a flow of < 0.1 cfm then set the NO_FLOW flag which causes main () to display '00.0' */ void overflow () interrupt 1 { if (++ticks > LOWEST_CFM) { cfm = 0; ticks = 0; NO_FLOW = TRUE; } } December 1990 15 AN429 */ */ */ Philips Semiconductors Microcontroller Products Application note Airflow measurement using the 83/87C752 and "C" AN429 /* calc_cfm - an external interrupt (int0) generated by a tach pulse from the flowmeter transfers the current value of timer0 into variables 'low' and 'middle', and then resets the timers. the 'ticks' variable described above is also copied to variable 'high', and then reset to zero. the NO_FLOW flag is cleared to enable display by main () of the calculated cfm. */ void calc_cfm () interrupt 0 { low = TL0; TL0 = 0; middle = TH0; TH0 = 0; high = ticks; ticks = 0; NO_FLOW = FALSE; } /* main - after initializing pins and variables, enter a continuous loop to... - calculate the airflow based on the tach, temp and pressure inputs. - compare the airflow to the setpoint input, and control the relay. - if the UPDATE flag is set (by the read_switch interrupt handler), sample the pushbuttons and update the display data. */ void main () { RELAY INTR UPDATE STROBE_0 STROBE_1 STROBE_2 STROBE_3 NO_FLOW I2CFG RTL RTH PWMP TR IT0 ticks cfm low middle high degree_c psi corr refresh disp_pntr IE = = = = = = = = = = = = = = = = = = = = = = = = = 0; 1; 1; 0; 0; 0; 0; 0; FREERUN_I; 0; 0; 255; 1; 1; 0; 0; 0; 0; 0; 250; 147; 0; 0; 0; 0xab; /* initialize output pins */ /* /* enable I timer to run, no i2c timer 0 period 0x10000 u_seconds */ */ /* /* /* /* pwm timer interrupt at 923 hz enable timer 0 INT0 is edge active initialize variables */ */ */ */ /* /* 25.0 tenths degrees c 14.7 tenths psi */ */ /* enable interrupts */ */ main execution loop, executes forever. */ while(1) { December 1990 16 Philips Semiconductors Microcontroller Products Application note Airflow measurement using the 83/87C752 and "C" */ calculate base cfm rate - first create long word representing flow rate period in microseconds. then subtract the time overhead in servicing the routine 'calc_cfm'. then divide the period into the period for 1/10 cfm, to get flow rate in 1/10 cfm resolution. */ corr corr corr corr corr = high * 0x10000L; += (middle * 0x100L); += low; -= CORRECTION; = ONE_TENTH_CFM / corr; /* read temperature - measure output from the LM35 sensor, scaled by the AMP-02. the scaling results in a range of 0 to 51.0 degrees centigrade, in 0.2 degree steps. */ ADCON = START_ADC1; while (ADCON & ADCS) ; degree_c = ADAT; degree_c *= 2; */ compensate cfm rate for temperature - convert temperature into degrees kelvin, then divide it into the measured flow rate multiplied by the calibration temperature of the flowmeter in degrees kelvin. (nominal 25 degrees centigrade) */ corr *= STD_TEMP; corr /= (ZERO_K + degree_c); */ read pressure - measure output of the KP100A pressure transducer, scaled by the AMP_02. the scaling results in a range of 0 to 25.5 psi, in 1/10 psi steps. */ ADCON = START_ADC0; while (ADCON & ADCS) ; psi = ADAT; */ compensate cfm rate for pressure - multiply measured pressure and the calculated flow rate, and then divide it by the standard atmospheric pressure at sea-level. (nominal 14.7 psi) corr *= psi; corr /= STD_ATM; cfm = corr; */ read setpoint pot to obtain setpoint in the range of 0 - 25.5 cfm in 1/10 cfm steps. */ ADCON = START_ADC2; while (ADCON & ADCS) ; setpoint = ADAT; */ December 1990 17 AN429 Philips Semiconductors Microcontroller Products Application note Airflow measurement using the 83/87C752 and "C" test if cfm rate greater or equal to the setpoint, and if so then energize relay */ if (setpoint > cfm) RELAY = 0; else RELAY = 1; */ test if UPDATE flag has been set, and if so reset flag. */ if (UPDATE) { UPDATE = 0; */ then test is the NO_FLOW flag has been set. if so then display '00.0' cfm */ if (NO_FLOW) { display0 = display1 = display2 = display3 = } ~CFM; ~segments[0]; ~(segments[0] ~segments[0]; | SEG_DP); */ if the NO_FLOW flag was not set then read the display select pushbuttons, and display the appropriate data. */ else if (SEL_0) { if (SEL_1) { */ if no pushbutton is depressed then the default display is the flow rate in cfm. if the flowrate is greater than or equal to 30 cfm then display the overrange message 'EEE', otherwise display the flow in 'XX.X' format. */ if (cfm <= 300) { display0 = ~CFM; display1 = ~segments[cfm % 10]; cfm /= 10; display2 = !(segments[cfm % 10]); cfm /= 10; display3 = ~segments [cfm % 10]; } else { display0 display1 display2 display3 } } December 1990 18 = = = = ~CFM; ~segments[10]; ~segments[10]; ~segments[10]; AN429 Philips Semiconductors Microcontroller Products Application note Airflow measurement using the 83/87C752 and "C" */ if the temp pushbutton (SW1) is pressed then display the air temperature. */ else { display0 display1 degree_c display2 degree_c display3 } = = /= = /= = ~DEGREES; ~segments[degree_c % 10]; 10; ~(segments[degree_c % 10] | SEG_DP); 10 ~segments[degree_c % 10]; } else { */ if the psi pushbutton (SW2) is pressed then display the air pressure. */ if(SEL_1) { display0 = display1 = psi /= 10; display2 = psi /= 10; display3 = } ~PSI; ~segments[psi % 10]; ~(segments[psi % 10] | SEG_DP) ; ~segments[psi % 10] ; */ if the setpoint pushbutton (SW3) is pressed then display the setpoint. */ else { display0 display1 setpoint display2 setpoint display3 } } } } } December 1990 19 = = /= = /= = ~SETPOINT; ~segments[setpoint % 10] ; 10; ~(segments[setpoint % 10] | SEG_DP ; 10; ~segments[setpoint % 10] ; AN429