Академический Документы
Профессиональный Документы
Культура Документы
INTRODUCTION
PID (proportional, integral, derivative) compensation is one of the most common forms of closed-loop control. Control of closed-loop systems that require compensation is a growing area of application for embedded microprocessors. In these systems, analog signals must be converted into discrete digital samples before compensation or filtering can take place. Loop performance dictates the sampling rate, and calculations must be complete before the next sample time begins. These loop-related constraints and the Nyquist frequency requirement place an upper bound on digital control of closed systems with feedback error. If the controlled system has a resonance or other behavior with a time constant shorter than the sample and calculation time, chaos is the most likely outcome. Despite these limitations, increases in microprocessor clock rates and the addition of on-chip control-oriented hardware are expanding the number of medium performance control applications handled by 8-bit machines. While an expensive DSP-class processor is the correct choice for the most demanding applications, several members of the M68HC11 family have the speed and resources to control multiple PWM channels. This note provides two working examples of PID control-loop software. The first example, written primarily in C, shows a PID algorithm in a straightforward way using floating-point math. Key features of the C environment are covered for readers who are more used to assembly language. The second example implements a PID algorithm in assembly language. It uses the MC68HC11N4 on-chip math coprocessor to speed up arithmetic operations. Both examples are complete and ready to run on a Freescale M68HC11EVS evaluation board. External interfacing is identical for both examples an 8-bit analog to digital converter is used for input, and an 8-bit PWM waveform is output. Because the code in both examples carries more than 16 bits of precision, and because both processors support 16-bit PWM, only minor changes are needed to increase precision. Power amplifiers, sensors, and other interface circuitry must be supplied in order to experiment with real-world systems a simple RC circuit is used for software checkout. C and assembly language source code and loadable object code can be obtained from Freescale Freeware Data Systems. Modem access: (512) 891-3733. Internet access: freeware.aus sps.mot.com. Web access: http:///www.freeware.aus.sps.mot.com.
THE MICROCONTROLLERS
The MC68HC11K4 and MC68HC11N4 are 16-MHz devices with nonmultiplexed external address and data buses. Each has 24 Kbytes of on-chip ROM or EPROM. Both devices have multiple PWM channels with programmable period, duty cycle, polarity, and clock source. In both, two 8-bit channels can be concatenated to generate a 16-bit PWM output. The MC68HC11N4 also has two additional 12-bit PWM channels and two digital to analog converter channels with 8-bit resolution.
PID ALGORITHM
The general flow of a controlled system with PID compensation is shown in Figure 1. An informal review of the derivation of the discrete form of each term and how they function follows. REFERENCES 2 and 3 provide a complete analysis of digital PID control.
Kp
e(kT) E(z)
K IT(z + 1) 2(z 1)
u(kT) U(z)
K d (z 1) Tz
Figure 1 PID Flow Diagram There is a desired setpoint in our process (Gd) and a measurement of the actual value G(t) in time. Error is: e(t) = Gd - G(t) Output correction x(t) for the PID controller is: de(t) x(t) = KP e(t) + KI e(t) + KD ----------- |t=T dt where KP, KI, and KD are constants. Now, rewriting the integral: x(t) = KP e(t) + KI
t t=0
To introduce discrete time, let t = kT where k = 1,2,...,n and T = the sampling and control update period. Now, t0 = (k 1)T. The integral evaluated from (k 1)T to kT can be approximated using the trapezoidal integration rule. The derivative of the error term is simply the rate of change of error, but this can be noisy over one period. Using a four-point central-weighted average for the difference term is a practical way to deal with this on a microprocessor.
C LANGUAGE IMPLEMENTATION
This version of the PID control routine illustrates use of high-level language for control applications. Highlevel language offers many conveniences not available in assembly language. Here are a few instances: Memory-mapped registers can be defined in a single file, which can be included in any function. Since C is a strongly-typed language, the compiler can identify data-type mismatches, such as writing a 16-bit integer to an 8-bit port. Most C compilers for the M68HC11 family allow direct vectoring to interrupt service routines. Interrupt functions are usually defined for a special memory segment with a base address and a function name: interrupt [INTVEC_START + 26] void RTI_interrupt(void); When an interrupt service routine is written it can be declared as an interrupt function instead of a normal subroutine: interrupt void RTI_interrupt(void) The function is compiled with a terminating RTI instruction, eliminating the need for a patch between hardware interrupts and C subroutines. The void statements indicate that no arguments are being passed to or from the interrupt routine. One of the most attractive features of contemporary C compilers is the ability to add floating point math with an include math.h statement. Even when the final application can't afford the time or code space for floating point calculations, use of floating point math during debugging provides an excellent means of testing new algorithms. Now to examine the control routine itself (refer to Appendix A for a complete C listing). After necessary files are included and floating point variables are declared, a prototype is given to define an assembly language function that is used later.
MAC
MUL
DIV
FDIV
32 BITS
START FDIV
Figure 2 Coprocessor Registers and Operations AN1215/D For More Information On This Product, Go to: www.freescale.com
$0044
SIG Signed Number Enable 0 = AREG, BREG, and CREG contents are unsigned numbers 1 = AREG, BREG, and CREG contents are signed numbers DIV Division Enable MAC Multiply with Accumulated Product Enable DCC Division Compensation for Concatenated Quotient Enable TRG Function Start Trigger Bit Always reads zero 0 = No effect 1 = Start ALU Bits [2:0] Not implemented Always read zero Table 1 ALUC Bit Function
SIG 0 1 0 1 0 1 1 0 1 1 DIV 0 0 0 0 1 1 1 1 1 1 MAC 0 0 1 1 0 0 0 1 1 1 DCC X X X X X 0 1 X 0 1 FUNCTION Unsigned MUL Signed MUL Unsigned MAC Signed MAC Unsigned IDIV Signed IDIV Signed IDIV DCC Unsigned FDIV Signed FDIV Signed FDIV DCC START TRIGGERS Write BREG or set TRG Write BREG or set TRG Write BREG or set TRG Write BREG or set TRG Write AREG or set TRG Write AREG or set TRG Write AREG or set TRG Set TRG Set TRG Set TRG
The 8-bit ALU status register (ALUF) signals when an operation is complete and indicates the status of the completed operation. ALUF Arithmetic Logic Unit Status Flag Register
Bit 7 NEG RESET: 0 6 RZF 0 5 0 4 0 3 0 2 OVF 0 1 DZF 0 Bit 0 ACF 0
$0049
NEG Negative Result NEG is set if the result is a negative value. This is a read-only-bit. Writes to this bit do not affect the value. RZF Remainder Equals Zero Flag RZF is set if the remainder is zero. Bits [5:3] Not implemented Always read zero AN1215/D For More Information On This Product, Go to: www.freescale.com
Table 2 shows numeric ranges of ALU registers. Table 3 shows signed expression of numbers. Table 4 shows fractional numeric representation. Figure 3 shows typical data register formats.
CREG LOW
INTEGER
-1
FRACTION
32-BIT SIGNED INTEGER AND FRACTION FOLLOWING AN FDIV 15 S INTEGER CREG HIGH 0 -1
CREG LOW RADIX POINT SIGN BIT IS IN INTEGER PART OR NEG FLAG -16 -32768.99998 TO +32767.99998
0.00000 TO 0.99998
FRACTION
CREG LOW RADIX POINT CREG LONG WORD SIGNED RESULT AFTER FDIV FOLLOWING AN IDIV SIGN BIT 31 S CREG HIGH AFTER IDIV 16 15
SIGN BIT 15 S
INTEGER CREG 0 -1
SIGN BIT
HARDWARE PLATFORM
The Freescale M68HC11KMNPEVS Evaluation System can be used to run both versions of the PID routine. With an MC68HC11K4 inserted in the emulator module, only the floating point version will execute. With an MC68HC11N4 inserted, both versions can be executed the floating point version simply does not use the math coprocessor. Both versions of the PID routine utilize special test mode in the EVS system. This means that the M68HC11 processor vectors are mapped from $BFD6 to $BFFF instead of from $FFD6 to $FFFF, and can be placed in user RAM or in emulation RAM, making experimentation with varied processor configuration options easier. Refer to the M68HC11KMNPEVS Evaluation System User's Manual for more information. AN1215/D For More Information On This Product, Go to: www.freescale.com
3.8 M VSS
PERFORMANCE
Since two very different approaches were taken to implement the PID loop algorithm, it is not surprising that the performance and code sizes of the two routines differ significantly. The C language version contains over 1500 bytes, much of which consists of floating point runtime support. Because it carries full floatingpoint precision and does not use math support hardware, the C version takes approximately 6 milliseconds to complete the loop. The assembly version contains approximately 1000 bytes, and could be reduced to about 800 bytes if features added for clarity and experimentation were removed. Because it uses a tailored arithmetic format and gets a hardware assist from the math coprocessor, the assembly version completes the loop in approximately 700 microseconds. In both cases, performance could be improved by precomputing all the results with constant factors.
10
CONCLUSION
With the 16.383 millisecond sampling rate chosen, the floating point C routine cannot service all four MC68HC11K4 PWM channels. It could, however, service one higher-rate channel and several less timecritical processes. The assembly math coprocessor routine can service all the MC68HC11N4 PWM channels (four 8-bit and two 12-bit) in 4.2 milliseconds, leaving 75% of execution time for other tasks. If the MC68HC11N4 D/A channels were also used, six independent PID controllers could be run in 5.6 milliseconds this routine would use less than a third of the allowable processing time and require only half of the twelve MC68HC11N4 A/D input channels. The two approaches to PID control outlined in this note encompass a wide range of useful and cost-effective applications. The simplicity of the coded C algorithm is very appealing. Since the C routine carries virtually no code-space overhead, it is very well-suited to an application where floating-point math is already required, and a sampling rate in the 20-millisecond range is acceptable. Because it uses a number format adapted to the application and to use of on-chip resources, the assembly routine generally yields higher, more cost-effective performance than the C routine. A final word of caution. There is no substitute for thorough mathematical analysis of the system to be controlled in the discrete time domain. References 2 and 3 contain detailed discussions of control systems and analytic techniques.
1. Andrews, Michael. Programming Microprocessor Interfaces for Control and Instrumentation. Prentice Hall; 1982 2. Kuo, Benjamin. Digital Control Systems. Holt, Rinehart and Winston Inc.; 1980 3. 3.Kuo, Benjamin. Automatic Control Systems. Prentice Hall; 1987 4. 4.Freescale MC68HC11K4 Technical Summary, BR751/D 5. 5.Freescale MC68HC11N4 Technical Summary, MC68HC11N4TS/D 6. 6.Freescale M68HC11 Reference Manual, M68HC11RM/AD Rev. 3 7. 7.Freescale M68HC11K4EVS Evaluation System User's Manual, M68HC11K4EVS/D1
REFERENCES
11
extern int
DOIO (void);
void main() { CMNDVX = 1.5; PERDT = 0.016383; KP = 0.18; KI = 6.0; KD = 0.009; OLDDTY = 1.9; PORTA = 0x00; DDRA = 0xFF; PACTL = 0x03; TMSK2 = 0x40; OPTION = 0x90; PWPER1 = 0xFF; PWDTY1 = 0xFF; PWPOL = 0x01; DDRH = 0x00; PWEN = 0x01; TFLG2 = 0x40; enable_interrupt(); wait_for_interrupt(); for (;;) { ; } }
/* main program */ /* RTI and therefore PID loop period = 16.383 ms */ /* kp = .12, ki = 6.0, kd = .006, for 1 M ohm drive */ /* /* /* /* /* /* /* /* start out with pwm set fairly high */ this will be used for a scope trigger */ set PORTA as output */ set RTI to 16.383 ms (E = 4 MHz) */ enable RTI interrupts */ enable A/D charge pump */ set up PWM channel 1 at 15.625 kHz */ with positive polarity */
interrupt void IRQ_interrupt(void) { PORTA = 0xFF; PORTA = 0x00; } interrupt void TO_interrupt(void) { TOFCOUNT++ ; }
12
/* The statement below is the entire floating point PID loop */ NEWDTY = KP*(ERRX) + KI*PERDT*(CMNDVX - (ADRCX + ADRCXM1)/2) + (KD/(6*PERDT))*((ERRX - ERRM3X) + 3*(ERRM1X - ERRM2X)) + OLDDTY; if (NEWDTY > 1.99609) NEWDTY = 1.99609; else if (NEWDTY < 1.0) NEWDTY = 1.0; /* test for result being in usable */ /* limits and set PWM duty cycle if */ /* beyond saturation */ /* clear RTI flag */ /* update A/D result for next cycle */ /* update error pipeline */ /* update old duty cycle for next calculation period */ /* scope strobe */
TFLG2 = 0x40; ADRCXM1 = ADRCX; ERRM3X = ERRM2X; ERRM2X = ERRM1X; ERRM1X = ERRX; OLDDTY = NEWDTY; PORTA = 0x00; }
13
extern int
14
/* /* /* /* /* /*
set PORTA as output */ set RTI to 16.383 ms (E = 4MHz) */ enable RTI interrupts */ enable A/D charge pump */ set up PWM channel 1 at 15.625 kHz */ with positive polarity */
interrupt void IRQ_interrupt(void) { PORTA = 0xFF; PORTA = 0x00; } interrupt void TO_interrupt(void) { TOFCOUNT++ ; } interrupt void RTI_interrupt(void) { PORTA = 0xFF; DOPID(); /*
/* PWM routine */ /* scope strobe */ /*DO THE PID LOOP USING THE MATH COPROCESSOR */
NEWDTY = KP*(ERRX) + KI*PERDT*(CMNDVX - (ADRCX + ADRCXM1)/2) + (KD/(6*PERDT))*((ERRX - ERRM3X) + 3*(ERRM1X - ERRM2X)) + OLDDTY; */ TFLG2 = 0x40; ADRCXM1 = ADRCX; ERRM3X = ERRM2X; ERRM2X = ERRM1X; ERRM1X = ERRX; PORTA = 0x00; /* clear RTI flag */ /* update A/D result for next cycle */ /* update error pipeline */ /* scope strobe */
15
CODE $006c $0030 $0031 $0040 $0041 $0042 $0043 $0044 $0045 $0046 $0047 $0048 $0049
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN EXTERN
ADRCX:ZPAGE ADRCXM1:ZPAGE CMNDVX:ZPAGE ERRX:ZPAGE ERRM1X:ZPAGE ERRM2X:ZPAGE ERRM3X:ZPAGE KPNUM:ZPAGE KPDEN:ZPAGE KINUM:ZPAGE KIDEN:ZPAGE KDNUM:ZPAGE KDDEN:ZPAGE PERDTNUM:ZPAGE PERDTDEN:ZPAGE INT56:ZPAGE FC56:ZPAGE TEMP1:ZPAGE TEMP2:ZPAGE TEMP3:ZPAGE TEMP4:ZPAGE KPTRM:ZPAGE KITRM:ZPAGE KDTRM:ZPAGE LTEMP1:ZPAGE LTEMP2:ZPAGE LTEMP3:ZPAGE LTEMP4:ZPAGE LTEMP5:ZPAGE LTEMP6:ZPAGE
$0084 EXTERNAL VARIABLES $0086 SIGNED INTS $0082 $0088 $008A $008C $008E $0090 $0092 $0094 $0096 $0098 $009A $009C $009E $00A0 $00A2 $00A4 $00A6 $00A8 $00AA $00B4 LONGS $00BC $00B8 $00C0 $00C4 $00C8 $00CC $00D0 $00D4
16
DOPID: ******** OUTPUT LAST PERIOD RESULT AND DO KP TERM ******** 9601 976C 4F D631 DD00 C610 D730 DC00 9300 DD00 2B06 8600 9700 2004 86FF 9700 8680 9744 DC00 DD45 8601 9749 DC00 DD47 134901FC 86C0 DD44 8601 9749 DC00 DD45 134901FC 8601 9749 86E8 DD44 134901FC DC40 DD00 DD00 DC42 DD02 DD02 BD0361 BD007F BD014F DC00 2B0F 1A8300FF 2B10 CC00FF DD00 DD00 2007 CC0000 DD00 DD00 LDAA STAA CLRA LDAB STD LDAB STAB LDD SUBD STD BMI LDAA STAA BRA LDAA STAA LDAA STAA LDD STD LDAA STAA LDD STD BRCLR LDAA STD LDAA STAA LDD STD BRCLR LDAA STAA LDAA STD BRCLR LDD STD STD LDD STD STD JSR JSR JSR LDD BMI CPD BMI LDD STD STD BRA LDD STD STD NEWDTY+1 PWDTY1 ADR1 ADRCX #$10 ADCTL CMNDVX ADRCX ERRX NFLAG1 #$00 TEMP3 NFLGG2 #$FF TEMP3 #$80 ALUC ERRX AREGH #$01 ALUF KPNUM BREGH ALUF,#$01,WPMUL1 #$D0 ALUC #$01 ALUF KPDEN AREGH ALUF,#$01,WPDIV1 #$01 ALUF #$E8 ALUC ALUF,#$01,WPFDV1 CREGH KPTRM LTEMP1 CREGML KPTRM+2 LTEMP1+2 ADLNG DOKIT DOKDT NEWDTY JAMZP #$00FF KXDONE #$00FF NEWDTY OLDDTY KXDONE #$0000 NEWDTY OLDDTY OUTPUT PREVIOUS CALC.
0000 0002 0004 0005 0007 0009 000B 000D 000F 0011 0013 0015 0017 0019 001B 001D 001F 0021 0023 0025 0027 0029 002B 002D 002F 0033 0035 0037 0039 003B 003D 003F 0043 0045 0047 0049 004B 004F 0051 0053 0055 0057 0059 005B 005E 0061 0064 0066 0068 006C 006E 0071 0073 0075 0077 007A 007C
GET CHANNEL 1 A/D RESULT. DO KP TERM FIRST START NEW A/D CONVERSION FORM ERROR TERM SET UP SIGN FLAG IN TEMP3 POS
NFLAG1 NFLGG2
CLEAR ACF
WPMUL1
TRIGGER SMUL WAIT FOR ACF SET ALU FOR SIDIV CLEAR ACF
WPDIV1
TRIGGER SIDIV WAIT FOR ACF CLEAR ACF TRIGGER SFDIV WAIT FOR ACF GET INT PART OF RESULT
WPFDV1
GET FRACTION
NOW ADD TO OLDDTY DO I TERM, ADD TO OLDDTY DO D TERM, ADD TO OLDDTY CHECK LIMITS
JAMZP
17
18
SAVE SIGN FLAG AND USE TEMP3 AS A FLAG FOR LTEMP6 BEING POSITIVE DO LTEMP3*LTEMP4(PERDT*KI) NOW PUT RESULT IN LTEMP5
DO RESULT*LTEMP2
ADD KI TERM INTO NEWDTY KITERM DONE RETURN ********** FORM (ERRX - ERRM3X) + 3*(ERRM1X - ERRM2X)
ROUTINE TO DO KD TERM ERRX ERRM3X TEMP1 ERRM1X ERRM2X AREGH #$80 ALUC #$01 ALUF #$0003 BREGH ALUF,#$01,WDMUL0 CREGML TEMP1 LTEMPA NGFLGS0 POSGN #$FF TEMP3 KDFLGD #$00 TEMP3 #$0000 LTEMPA+2 #$00 ALUC #$01 ALUF #$0006 AREGH PERDTNUM BREGH ALUF,#$01,WDMUL1
19
TRIGGER SIDIV WAIT FOR ACF CLEAR ACF TRIGGER SFDIV WAIT FOR ACF
SET ALU FOR SIDIV TO FORM PERDTDEN/(PERDTNUM*6) CLEAR ACF SET UP PERDTNUM
TRIGGER SIDIV WAIT FOR ACF CLEAR ACF TRIGGER SFDIV WAIT FOR ACF
SAVE SIGN FLAG AND USE TEMP3 AS A FLAG FOR LTEMP6 BEING POSITIVE DO LTEMP8*LTEMP9 NOW PUT RESULT IN LTEMP5
DO RESULT*LTEMPA
20
SUBROUTINE TO MULTIPLY LONGS(INTEGER & FRACTION) LTEMP5*LTEMP6=LTEMP7 ONLY LTEMP6 CAN HAVE A NEGATIVE TERM TO HANDLE. #$80 ALUC LTEMP5 AREGH #$01 ALUF LTEMP6 BREGH ALUF,#$01,WMULL1 CREGML INT56 #$01 ALUF #$80 TEMP3 NEGFRAC LTEMP6+2 BREGH ALUF,#$01,WMULL2 CREGH INTFC56 CREGML INTFC56+2 NXFRAC #$0000 LTEMP6+2 BREGH ALUF,#$01,WMULL3 #$0000 CREGH INTFIX1 INTFIX2 #$0001 INTFC56 #$0000 CREGML INTFC56+2 #$00 LTEMP5+2 AREGH #$01 ALUF #$00 LTEMP6 BREGH ALUF,#$01,WMULL4 #$80 TEMP3 DFXINT #$80 AREGH FXINT DFXINT #$0000 CREGH CREGH CREGH
MULLNG
LDAA STAA LDD STD LDAA STAA LDD STD WMULL1 BRCLR LDD STD LDAA STAA LDAA BITA BMI LDD STD WMULL2 BRCLR LDD STD LDD STD BRA NEGFRAC LDD SUBD STD WMULL3 BRCLR LDD SUBD BMI BRA INTFIX1 ADDD INTFIX2 STD LDD SUBD STD LDAA NXFRAC LDD STD LDAA STAA LDAA LDD STD WMULL4 BRCLR LDAA BITA BPL LDAA BITA BMI BRA FXINT LDD SUBD STD DFXINT LDD
CLEAR ACF
CLEAR ACF AND DO NEXT MULT TEST TEMP3 SIGN SEE IF ERR IS NEG TERM IS NEGATIVE GET FRAC NOT NEG TRIGGER SMUL WAIT FOR ACF SCALE AND STORE
NEGATE FRAC TRIGGER SMUL WAIT FOR ACF NEGATE RESULT SCALE AND STORE
GET FRAC AND MULTIPLY WITH POSSIBLE NEG INT CLEAR ACF
21
NOW DO FRAC*FRAC CLEAR ACF SET UNSIGNED MULT FOR FRACS TEST ERR SIGN SEE IF ERR IS NEG TERM IS NEGATIVE GET FRAC NOT NEG TRIGGER SMUL WAIT FOR ACF SCALE AND STORE
NEGATE FRAC TRIGGER SMUL WAIT FOR ACF NEGATE RESULT SCALE AND STORE NOW SUMM ALL PRODUCTS INTS ARE ALL SIGNED CAN JUST ADD UP TEST ERRX SIGN SEE IF FRACS ARE NEG FRACS ARE NEGATIVE POSITIVE
RETRIEVE SUM
NEGATIVE REMEMBER SIGN BIT!! SAVE SUM ADD BORROW INTO INT
RETRIEVE SUM
22
FCCAR4
SMFCDN
SMFCDP
* SUBROUTINE TO ADD INTEGER AND FRACTION IN LTEMP1 TO OLDDTY * 0361 0363 0365 0367 0369 036B 036D 036F 0371 0373 0375 0377 037A 037C 037E 0380 0382 0384 0386 0388 038A 038C 038E 0391 0393 0395 0397 0399 039B 039D 039E 8680 9500 2B19 DC00 D300 DD00 DC02 D302 DD02 2502 201E CC0001 D300 DD00 2015 DC00 D300 DD00 DC02 D302 DD02 2507 CCFFFF D300 DD00 DC00 DD00 DC02 DD02 39 LDAA BITA BMI LDD ADDD STD LDD ADDD STD BCS BRA INCINT LDD ADDD STD BRA KXNEG LDD ADDD STD LDD ADDD STD BCS DECINT LDD ADDD STD ADDONE LDD STD LDD STD RTS END ######### # DOPID # ######### ADLNG #$80 TEMP3 KXNEG LTEMP1 OLDDTY NEWDTY LTEMP1+2 OLDDTY+2 NEWDTY+2 INCINT ADDONE #$0001 NEWDTY NEWDTY ADDONE LTEMP1 OLDDTY NEWDTY LTEMP1+2 OLDDTY+2 NEWDTY+2 ADDONE #$FFFF NEWDTY NEWDTY NEWDTY OLDDTY NEWDTY+2 OLDDTY+2 TEST ERRX SIGN TERM IS NEGATIVE GET INT PART ADD AND STORE INT GET FRAC PART ADD AND STORE FRAC
GET INT PART ADD AND STORE INT GET FRAC PART ADD AND STORE FRAC ACTUALLY A SUBTRACTION SUBTRACT BORROW FROM FRAC
23
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 which 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 customers 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.