Chapter 3 More Loops 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: 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) do Loops do { // your code here ... } while ( x); Notice that we are also re-using the while keyword, don’t let it confuse you! Quiz: How many times is the loop below going to be executed? do { // your code here ... } while ( 0); Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) Variables Declarations Signed integer types: // from -128 to +127 // from -32768 to +32767 // from -2,147,483,648 to + Unsigned integer types: char c; int c; long c; 2,147,483,647 unsigned char c; // from 0..255 unsigned int i; // from 0..65,535 unsigned long x; // from 0..4,294,967,295 Floating point types: float f; long double d; // 32-bit single precision // 64-bit double precision Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) for Loops A loop counting from 0 to 4: i = 0; // init the index/counter while ( i<5) { // insert your code here… // it will be executed for i= 0, 1, 2, 3, 4 i = i+1; // increment } Can be expressed more concisely as: for ( i=0; i<5; i=i+1) { // insert your code here … // it will be executed for i=0, 1, 2, 3, 4 } Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) Increment and Decrement Introducing two new operators: Use ++ to increment a variable, i++; is equivalent to: i = i+1; Use -- to decrement a variable, i--; is equivalent to: i = i-1; More on this later... Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) More Loop Examples Use the increment operator: for ( i=0; i<5; i++) { // insert your code here … // it will be executed for i= 0, 1, 2, 3, 4 } Then, a count down from 4 to 0: for ( i=4; i>=0; i--) { // insert your code here … // it will be executed for i= 4, 3, 2, 1, 0 } Use the for loop to code an (infinite) main program loop(!?): main() { // 0. initialization code … // 1. the main application loop for ( ; 1; ) { … } } // main Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) Arrays Declare an array of integers with the following notation: char c[10]; int i[10]; long x[10]; Use // declares c as an array of 10 x 8-bit integers // declares i as an array of 10 x 16-bit integers // declares x as an array of 10 x 32-bit integers the square bracket notation to access elements of an array: a = c[0]; c[1] = 123; i[2] = 12345; x[3] = 123* i[4]; Use // // // // // copy the 1st element of c[] into a assign 123 to the second element of c[] assign 12,345 to the third element of i[] compute 123 x the 5th element of i[] and assign result to the 4th element of x[] a for loop to access sequentially array elements: int a[10]; // declare array of 10 integers: a[0], a[1] … a[9] int i; // the loop index for ( i=0; i<10; i++) { a[ i] = 1; } Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) Sending a Message #include <config.h> // 1. define timing constant #define SHORT_DELAY 100 #define LONG_DELAY 800 // 2. declare and initialize an // array with the message bitmap char bitmap[30] = { 0b11111111, // H 0b00001000, 0b00001000, 0b11111111, 0b00000000, 0b00000000, 0b11111111, // E 0b10001001, 0b10001001, 0b10000001, 0b00000000, 0b00000000, 0b11111111, // L 0b10000000, 0b10000000, 0b10000000, 0b00000000, 0b00000000, 0b11111111, // L 0b10000000, 0b10000000, 0b10000000, 0b00000000, 0b00000000, 0b01111110, // O 0b10000001, 0b10000001, 0b01111110, 0b00000000, 0b00000000 }; Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) // 3. the main program main() { // 3.1 variable declarations int i; // i will serve as the index // 3.2 initialization TRISA = 0; // all PORTA as output T1CON = 0x8030; // TMR1 on, prescale 1:256 Tclk/2 // 3.3 the main loop while( 1) { // 3.3.1 display loop, hand moving to the right for( i=0; i<30; i++) { // 3.3.1.1 update the LEDs PORTA = bitmap[i]; // 3.3.1.2 short pause TMR1 = 0; while ( TMR1 < SHORT_DELAY) { } } // for i // 3.3.2 long pause, hand moving back to the left PORTA = 0; // turn LEDs off TMR1 = 0; while ( TMR1 < LONG_DELAY) { } } // main loop } // main See the Message Now? #include <config.h> // 1. define timing constant #define SHORT_DELAY 100 #define LONG_DELAY 800 // 2. declare and initialize an // array with the message bitmap char bitmap[30] = { 0b11111111, // H 0b00001000, 0b00001000, 0b11111111, 0b00000000, 0b00000000, 0b11111111, // E 0b10001001, 0b10001001, 0b10000001, 0b00000000, 0b00000000, 0b11111111, // L 0b10000000, 0b10000000, 0b10000000, 0b00000000, 0b00000000, 0b11111111, // L 0b10000000, 0b10000000, 0b10000000, 0b00000000, 0b00000000, 0b01111110, // O 0b10000001, 0b10000001, 0b01111110, 0b00000000, 0b00000000 }; Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) // 3. the main program main() { // 3.1 variable declarations int i; // i will serve as the index // 3.2 initialization TRISA = 0; // all PORTA as output T1CON = 0x8030; // TMR1 on, prescale 1:256 Tclk/2 // 3.3 the main loop while( 1) { // 3.3.1 display loop, hand moving to the right for( i=0; i<30; i++) { // 3.3.1.1 update the LEDs PORTA = bitmap[i]; // 3.3.1.2 short pause TMR1 = 0; while ( TMR1 < SHORT_DELAY) { } } // for i // 3.3.2 long pause, hand moving back to the left PORTA = 0; // turn LEDs off TMR1 = 0; while ( TMR1 < LONG_DELAY) { } } // main loop } // main The Message on a Logic Analyzer Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) Notes for the Assembly Experts Most of times the MPLAB XC16 compiler tries to translate ++ and – with inc and dec assembly instructions. This is not always possible though because the two operators are actually much smarter than that: If they are applied to a pointer (which is a variable type that contains a memory address) they actually increase the address by the exact number of bytes required to represent the quantity pointed to. For example: a pointer to 16-bit integers will increment its address by 2, a pointer to a 32-bit long integer will increment its address by 4, and so on. To satisfy your curiosity, switch to the Disassembly Window and see how the MPLAB XC16 compiler chooses the best assembly code depending on the situation. Loops in C can be confusing at first. In some situations the algorithm you are coding will dictate which one to use, but in many situations you will have a degree of freedom and more than one type might do. In case of doubt, choose the one that makes your code more readable! Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) Notes for the PIC MCU Experts Depending on the target microcontroller architecture, and ultimately the Arithmetic Logic Unit (ALU) size, operating on bytes versus operating on word quantities can make a big difference in terms of code compactness and efficiency. While in 8-bit architectures, there is a strong incentive to use byte-sized integers wherever possible, in the PIC24 16-bit architecture word-sized integers can be manipulated just with the same efficiency. Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) Notes for C Experts Even if some 16-bit microcontrollers have a relatively large RAM memory array, embedded control applications will always have to contend with the reality of cost and size limitations. If you learned to program in C on a PC or a workstation, you probably never considered using anything smaller than an int as a loop index. In Embedded Control, shaving one byte at a time off the requirements of your application might, in some cases, mean the ability to select a smaller model of microcontroller, saving fractions of a dollar that when multiplied by the thousands or millions of units (depending on production run rates), can mean real money saved from the bottom line. Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) Tips and Tricks In this last exercise we declared an array called bitmap[] and we asked for it to be pre-filled with a specific series of values. The array, being a data structure, resides in RAM during execution. But since RAM is volatile, the XC16 compiler has to copy the assigned values (in the curly brackets {} notation) from a non volatile memory (FLASH memory) before the main program execution is started. This is the kind of task performed in the crt0 code segment. Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) Configuring the PPS (for GA1 and GB1 users) #include <pps.h> void InitPPS( void) { // SPI1 PPSOutput( PPS_RP15, PPS_SDO1); // SDO1 =RP15 F8/pin 53 // SPI2 PPSInput( PPS_SDI2, PPS_RP26); PPSOutput( PPS_RP22, PPS_SCK2OUT); PPSOutput( PPS_RP21, PPS_SDO2); // SDI2 =RP26 G7/pin 11 // SCK2 =RP21 G6/pin 10 // SDO2 =RP19 G8/pin 12 // UART PPSInput( PPS_U2RX, PPSInput( PPS_U2CTS, PPSOutput( PPS_RP17, PPSOutput( PPS_RP31, PPS_RP10); PPS_RPI32); PPS_U2TX); PPS_U2RTS); // // // // // IC PPSInput( PPS_IC1, PPS_RP2); // IC1 =RP2 // OC PPSOutput( PPS_RP19, PPS_OC1); PPSOutput( PPS_RP11, PPS_OC2); PPSOutput( PPS_RP24, PPS_OC4); } // OC1 // OC2 // OC4 =RP11 D0/pin 72 =RP24 D1/pin 76 =RP22 D3/pin 78 U2RX =RP10 U2CTS=RP32 U2TX =RP17 U2RTS=RP31 Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) F4/pin 49 F12/pin40 F5/pin 50 F13pin 39 D8/pin 68 Special Mapping for GB1 PIM Users // // // // // // // // // GB110 PIM pin-remapping to accomodate additional USB pins GB110 shares usage of D2/pin 77 between SDI1 and OC3 pin 54 SDI1 is remapped to Explorer pin 77/D2 NOTE: we will use it only as OC3 pin 55 SCK1 is remapped to Explorer pin 25/B0 NOTE: pin 55 is input only, connecting it to SCK1 restricts usage to "slave mode" only pin 56 RG3 is remapped to Explorer pin 89/G1 pin 57 RG2 is remapped to Explorer pin 90/G0 #ifdef __PIC24FJ256GB110__ PPSOutput( PPS_RP23, PPS_OC3OUT); #endif Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) // OC3=RP23 D2/pin 77 Intoducing the EX16.c Module /* ** EX16.c */ #include <EX16.h> void InitEX16( void) { // if using a GA1 or GB1 PIM, initialize the PPS module #if defined(__PIC24FJ256GB110__) || defined(__PIC24FJ256GA110__) #include <pps.h> InitPPS(); #endif // prepare Port A for use with LED bar LATA = 0; // all LED off TRISA = 0xFF00; // all output } // InitEX16 Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) EX16.h Header File /* ** EX16.h ** ** Standard definitions for use with the Explorer16 board */ #ifndef _EX16 #define _EX16 #include <p24fxxxx.h> #if defined(__PIC24FJ256GB110__) || defined(__PIC24FJ256GA110__) #include <pps.h> #endif #define FCY 16000000UL // instruction clock 16MHz // prototypes void InitEX16( void); #endif // initialize the Explorer 16 board Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) Additional Configs for GA1/GB1 Add the following lines to the config.h file created in lesson 1: #if defined ( __PIC24FJ128GA010__ ) || defined (__PIC24FJ256GA110__) _CONFIG2( IESO_OFF // two speed start up disabled & FCKSM_CSDCMD // disable clock-swithcing/monitor & FNOSC_PRIPLL // primary oscillator: enable PLL & POSCMOD_XT) // primary oscillator: XT mode #else // GB1 configuration requires additional detail _CONFIG2( & & & & & PLL_96MHZ_ON PLLDIV_DIV2 IESO_OFF FCKSM_CSDCMD FNOSC_PRIPLL POSCMOD_XT) // // // // // // enable USB PLL module 8MHz/2 = 4Mhz input to USB PLL two speed start up disabled disable clock-swithcing/monitor primary oscillator: enable PLL primary oscillator: XT mode #endif Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) Suggested Excercises Improve the display / hand synchronization by waiting for a button to be pressed before the hand sweep is started Add a switch to sense the sweep movement reversal and play the LED sequence backward on the back sweep Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) Recommended Readings Rony, P., Larsen D. & Titus J., 1976, THE 8080A BUGBOOK, MICROCOMPUTER INTERFACING AND PROGRAMMING, Howard W. Sams & Co., Inc., Indianapolis, IN No high level language programming here, just the basics of assembly programming and hardware interfacing. (Too bad this book is already considered museum material, see link below). Shulman, S. (2003), Unlocking the Sky, Glenn Hammond Curtis and the race to invent the Airplane, Harper Collins, New York, NY A beautiful recount of the “struggle to innovate” in the early days of aviation. Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition) Online Resources http://www.bugbookcomputermuseum.com/B ugBook-Titles.html A link to the “Bugbooks museum”. It is 40 years since the introduction of the INTEL 8080 microprocessor and it is like centuries have already passed. Di Jasio – Programming 16-bit Microcontrollers in C (Second Edition)