C in CodeWarrior Microcontroller Architecture and Interfacing Colorado School of Mines Professor William Hoff 1 Example • Start up CodeWarrior and select “New Project” – Select MC9S12C32, and “Full Chip Simulation” as usual • Select “C” and set a project name and location Microcontroller Architecture and Interfacing Colorado School of Mines Professor William Hoff 2 Next screen • Select “Create main.c/main.asm file” Microcontroller Architecture and Interfacing Colorado School of Mines Professor William Hoff 3 Next screen • Choose “none” for device initialization Microcontroller Architecture and Interfacing Colorado School of Mines Professor William Hoff 4 Next screen • Choose: ANSI startup code; small memory model, no floating point support Microcontroller Architecture and Interfacing Colorado School of Mines Professor William Hoff 5 Last screen • Choose “No” for lint tools Microcontroller Architecture and Interfacing Colorado School of Mines Professor William Hoff 6 Template C Program generated by CodeWarrior • Don’t delete any of this #include <hidef.h> /* common defines and macros */ #include "derivative.h" /* derivative-specific definitions */ void main(void) { /* put your own code here */ If you have any functions, put them here. Global variables can also be defined here. Put your data declarations here EnableInterrupts; Infinite loop Put any initialization code you have here Code for your main loop goes here for(;;) { _FEED_COP(); /* feeds the dog */ “COP” means “computer } /* loop forever */ operating properly” – we /* please make sure that you never leave main */ aren’t using this } Microcontroller Architecture and Interfacing Colorado School of Mines Professor William Hoff 7 #include <hidef.h> /* common defines and macros */ #include "derivative.h" /* derivative-specific definitions */ // Initialize Table with Gray codes char Table[] = {0x00,0x01,0x03,0x02,0x06,0x07,0x05,0x04}; int n; void main(void) { EnableInterrupts; DDRT = 0x07; n = 0; Example: Gray Code output //Set up Port T, bits 0..2, for output /* Main loop */ for(;;) { PTT = Table[n]; // Write next value to PortT if (++n >= 8) n = 0; // Optionally delay a short time _FEED_COP(); /* feeds the dog */ } /* loop forever */ } Microcontroller Architecture and Interfacing Colorado School of Mines Professor William Hoff 8 10: 11: 0000 12: 13: 0002 0004 14: 0007 0008 0009 15: 16: 17: 18: 000c 000f 0013 19: 0016 0017 001a 001d 20: 001f 0020 0021 21: 22: 23: 0024 0026 0028 0029 002b 24: 25: void main(void) { EnableInterrupts; 10ef [1] CLI DDRT = 0x07; c607 [1] 7b0000 [3] n = 0; c7 [1] 87 [1] 7c0000 [3] //Set up Port T, bits 0..2, for output LDAB #7 STAB _DDRT CLRB CLRA STD “List” file • Choose Project>Disassemble n /* Main loop */ for(;;) { PTT = Table[n]; // Write next value to PortT fe0000 [3] LDX n e6e20000 [4] LDAB Table,X 7b0000 [3] STAB _PTT if (++n >= 8) 08 [1] INX 7e0000 [3] STX n 8e0008 [2] CPX #8 2d05 [3/1] BLT *+7 ;abs = 0024 n = 0; c7 [1] CLRB 87 [1] CLRA 7c0000 [3] STD n // Optionally delay a short time _FEED_COP(); /* feeds the dog */ c655 [1] LDAB #85 5b3f [2] STAB 63 58 [1] LSLB 5b3f [2] STAB 63 20df [3] BRA *-31 ;abs = 000c } /* loop forever */ Microcontroller Architecture and Interfacing Colorado School of Mines } Professor William Hoff 9 Step one C instruction Step one assembly instruction You can see the assembly language instructions corresponding to the C instructions Microcontroller Architecture and Interfacing Colorado School of Mines Professor William Hoff 10 Analysis • Where in memory are the variables stored? • Where is “Table” initialized, and when? • How fast do the Gray codes come out (# clock cycles between codes)? • Could you write assembly language code that is faster? Microcontroller Architecture and Interfacing Colorado School of Mines Professor William Hoff 11 Mixing Assembly and C Instructions • You can use assembly language instructions inside a C program • Just enclose the assembly instructions inside {} brackets following the “__asm” statement • Example: this module delays 10 microseconds __asm { ; Main loop ldx #10 loop: psha pula psha pula psha pula psha pula nop dbne x,loop } Microcontroller Architecture and Interfacing is 24 cycles, or 1 usec ; 3 additional cycles here ; 2 E cycles ; 3 E cycles ; 2 E cycles ; 3 E cycles ; 2 E cycles ; 3 E cycles ; 2 E cycles ; 3 E cycles ; 1 E cycle ; 3 E cycles Colorado School of Mines Professor William Hoff 12 Passing values to assembly code • The compiler is smart enough to let you access variables defined in C, in your assembly code • Example – this is a function to delay “t” microseconds Microcontroller Architecture and Interfacing /* Subroutine DelayuSec This subroutine delays t microsecs (assuming a 24 MHz E clock). */ void DelayuSec(int t) { __asm { ldx t ; get number of usec to delay ; Main loop is 24 cycles, or 1 usec loop: psha ; 2 E cycles pula ; 3 E cycles psha ; 2 E cycles pula ; 3 E cycles psha ; 2 E cycles pula ; 3 E cycles psha ; 2 E cycles pula ; 3 E cycles nop ; 1 E cycle dbne x,loop ; 3 E cycles } } Colorado School of Mines Professor William Hoff 13 Example - Main program void main(void) { int i; Note – we have to declare the local variable called “i” here before using it below EnableInterrupts; /* Enable PT0 for output */ DDRT = 0x01; for(;;) { PTT = 0x01; // turn on LED // Delay for 1000x1000 us = 1.0 sec for (i=0; i<1000; i++) DelayuSec(1000); PTT = 0x00; // turn off LED // Delay for 1000x1000 us = 1.0 sec for (i=0; i<1000; i++) DelayuSec(1000); _FEED_COP(); /* feeds the dog */ } /* loop forever */ /* please make sure that you never leave main */ } Microcontroller Architecture and Interfacing Colorado School of Mines Professor William Hoff 14