chapter 4 numb3rs

19
Chapter 4 Chapter 4 NUMB3RS NUMB3RS

Upload: kelly-mccarty

Post on 01-Jan-2016

31 views

Category:

Documents


0 download

DESCRIPTION

Chapter 4 NUMB3RS. Checklist. The following tools will be used in this lesson: MPLAB X, Integrated Development Environment (v1.8 or later, free) MPLAB XC16, C compiler (v1.11 or later, free) The following pieces of documentation will be used during this lesson: - PowerPoint PPT Presentation

TRANSCRIPT

Chapter 4Chapter 4NUMB3RSNUMB3RS

Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)

ChecklistChecklistThe following tools will be used in this lesson: MPLAB X, Integrated Development Environment

(v1.8 or later, free) MPLAB XC16, C compiler (v1.11 or later, free)

The following pieces of documentation will be used during this lesson:

PIC24FJ128GA010 Datasheet –DS39747 (latest rev.) PIC24 Family Reference Manual - Section 14. Timers

Make sure they are available and/or installed and ready to use on your computer.

You can download them from Microchip web site at: http://www.microchip.com/mplabx

And http://www.microchip.com/xc16

Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)

Integer Data TypesInteger Data Types

Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)

Under the HoodUnder the Hood Type the following few lines of code in a new main.c file:

unsigned int i,j,k; main (){ i = 0x1234; // assign an initial value to i j = 0x5678; // assign an initial value to j k = i * j; // perform product and store the result in k}

Build the project and open the Window>Embedded Memory>Program window to inspect the code produced: i = 0x1234; 212340 MOV #0x1234, W0 // move literal to W0884280 MOV W0, 0x400 // move from W0 to i j = 0x5678;256780 MOV #0x5678, W0 // move literal to W0884290 MOV W0, 0x401 // move from W0 to j k = i * j;804281 MOV 0x400, W1 // move from i to W1804290 MOV 0x401, W0 // move from j to W0B98800 MUL.SS W1, W0, W08842A0 MOV W0, 0x402 // move result to k

Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)

Going “Going “longlong”” Try now with long (32-bit) integer values

unsigned long i,j,k;main (){ i = 0x01234567L; // assign an initial value to i j = 0x89ABCDEFL; // assign an initial value to j k = i * j; // perform product and store the result in k}

And inspect the new code produced for the multiplication: k = i * j;804038 MOV 0x403, W8804049 MOV 0x404, W9804056 MOV 0x405, W6804067 MOV 0x406, W7780088 MOV W8, W1780006 MOV W6, W0B80A00 MUL.UU W1, W0, W4B9C007 MUL.SS W8, W7, W0780105 MOV W5, W2410100 ADD W2, W0, W2B9B009 MUL.SS W6, W9, W0410100 ADD W2, W0, W2780282 MOV W2, W5884074 MOV W4, 0x407884085 MOV W5, 0x408

Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)

““long long”long long” MultiplicationsMultiplications Finally let’s try long long (64-bit) integer values

unsigned long long i,j,k;

main ()

{

i = 0x0123456789ABCDEFLL; // assign an initial value to i

j = 0xFEDCBA9876543210LL; // assign an initial value to j

k = i * j; // perform product and store the result in k

}

And inspect the new code produced for the multiplication: k = i * j;07FDFC RCALL 0x290

Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)

Floating Point TypesFloating Point Types

Notice how the MPLAB XC16 compiler, by default, allocates for both the float and the double types the same number of bits (32), using the single precision floating-point format defined in the IEEE754 standard.

Only the long double data type is treated as a true double precision IEEE754 floating-point type (64-bit).

Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)

Notes for C ExpertsNotes for C Experts If porting existing C code from a PC or workstation project, you

might want to force the XC16 compiler to use the more standard (true) definition of a double as a 64-bit integer.

You can do so by accessing the Project Configuration Dialog and selecting the “Use 64-bit double” option!

Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)

Measuring Integer PerformanceMeasuring Integer Performance/* * Numb3rs.c*/#include <config.h>

int i1, i2, i3;long x1, x2, x3;long long xx1, xx2, xx3;

main(){ T1CON = 0x8000; // enable Timer1 1:1 with main clock i1 = 0x1234; // testing integers (16-bit) i2 = 0x5678; TMR1 = 0; // clear the timer i3 = i1 * i2; x1 = 0x01234567L; // testing long integers (32-bit) x2 = 0x89ABCDEFL; TMR1 = 0; // clear the timer x3 = x1 * x2;  xx1 = 0x0123456789ABCDEFLL; // testing 64-bit integers xx2 = 0xFEDCBA9876543210LL; TMR1 = 0; // clear the timer xx3 = xx1 * xx2;} // main

Single Step, then read TMR1

Single Step, then read TMR1

Single Step, then read TMR1

Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)

Measuring FP PerformanceMeasuring FP Performance/* * Numb3rs.c*/

#include <config.h>

float f1,f2, f3;long double d1, d2, d3;

main(){ T1CON = 0x8000; // enable Timer1 1:1 with main clock f1 = 12.34; // testing single precision floating point f2 = 56.78; TMR1 = 0; // clear the timer f3 = f1 * f2;  d1 = 12.34L; // testing double precision floating point d2 = 56.78L; TMR1 = 0; // clear the timer d3 = d1 * d2;

} // main

Single Step, then read TMR1

Single Step, then read TMR1

Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)

Measuring Performance SummaryMeasuring Performance Summary

Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)

Lessons LearnedLessons Learned

1. Use integers every time you can (i.e. when fractions are not required, or the algorithm can be re-written for integer arithmetic).

2. Use the smallest integer type that will not produce an overflow or underflow.

3. If you have to use a floating-point type (fractions are required), expect an order-of-magnitude reduction in the performance of the compiled program.

4. Double precision floating point (long double) seems to only reduce the performance by a further factor of two.

Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)

Notes for the Assembly ExpertsNotes for the Assembly Experts1. Converting an integer type into a smaller/larger one:

int x; // 16-bit long y; // 32-bity = x; // implicit conversion Explicity Conversion using a “type cast”:

int x; // 16-bit long y; // 32-bit x = (int) y; // type cast

2. Extracting or manipulating one bit out of an integer variable, use “bitfields”Example from the PIC24 peripheral libraries: extern unsigned int T1CON;extern union { struct { unsigned :1; unsigned TCS:1;... unsigned TSIDL:1; unsigned :1; unsigned TON:1; }; struct { unsigned :4; unsigned TCKPS:2; };} T1CONbits; 

Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)

Notes for the PIC MCU ExpertsNotes for the PIC MCU Experts 8-bit users will notice a considerable

improvement in the performance both with integer arithmetic and floating point arithmetic.

The 16-bit ALU available in the PIC24 architecture manipulates twice the number of bits per cycle

Further improvement is due to the use of 8 working registers which make the coding of critical arithmetic routines and makes numerical algorithms more efficient

Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)

Tips and TricksTips and Tricks The MPLAB C compiler supports several

standard ANSI C libraries including: limits.h - contains many useful macros defining

implementation dependent limits, such as, for example, the number of bits composing a char type (CHAR_BIT) or the largest integer value (INT_MAX).

float.h - contains similar implementation dependent limits for floating point data types, such as, for example the largest exponent for a single precision floating point variable (FLT_MAX_EXP).

math.h - contains trigonometric functions, rounding functions, logarithms and exponentials.

Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)

Tips and TricksTips and TricksComplex Data TypesThe XC16 compiler supports complex data types as an extension of both integer and floating point types. Here is an example declaration for a single precision floating point type:

__complex__ float z;Notice the use of a double underscore before and after the keyword complex.The variable z defined so has now a real and an imaginary part that can be individually addressed using the syntax: __real__ z and __imag__ z respectively.Similarly, the next declaration produces a complex variable of 16-bit integer type:

__complex__ int x;Complex constants are easily created adding the suffix i or j as in the following examples:

x = 2 + 3j;z = 2.0f + 3.0fj;

All standard arithmetic operations (+,-,*,/) are performed correctly on complex data types. Additionally the “~” operator produces the complex conjugate.

Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)

Suggested ExcercisesSuggested Excercises

1. Write a program that uses Timer2 and Timer3 joined in the new 32-bit timer mode.

2. Test the relative performance of the division for the various data types.

3. Test the performance of the trigonometric functions relative to standard arithmetic operations.

4. Test the relative performance of the multiplication for complex data types.

Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)

Recommended ReadingsRecommended Readings Gahlinger, P. M. (2000), The cockpit, a flight of escape

and discovery, Sagebrush Press, Salt Lake City, UT

It’s an interesting journey around the world. Follow the author in search of ... his soul.Every instrument in the cockpit triggers a memory and starts a new chapter.

Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)

Online ResourcesOnline Resources http://en.wikipedia.org/wiki/Taylor_series

If you are curious as to how the C compiler can approximate some of the functions in the math library.