Programstruktur: C för enchipsdatorer Lektion 2 Programstruktur: C för enchipsdatorer
Dagens Agenda Uppvärmning C preprocessor Villkorssatser Vektorer Exempel och förtydliganden rörande ämnen från Lektion 1 C preprocessor #include #define Villkorssatser if, case, while, for Vektorer Array, string Kompilering och simulering av C program Inför C lab1 Introduktion till funktioner argument, returvärde, variabler
Endianess Big Endian (Motorola 680x0, Sun SPARC, de flesta RISC maskiner) Den mest signifikanta byten är lagrad på den lägsta adressen 0x12345678 sparas som ex. 12 34 56 78 Little Endian (PIC, Intel 80x86, Pentium) Den minst signifikanta byten är lagrad på den lägsta adressen 0x12345678 sparas som 78 56 34 12 unsigned long j; j=0x12345678; Resultat i MPLAB nedan
Ett enkelt program i C
C Preprocessor Preprocessor Två mest viktiga Första steget i kompileringen Rader som börjar med # är instruktion till preprocessor Räckvidd till slutet av filen Två mest viktiga #include Filinkludering #define Makrosubstitution Det finns även andra Avdefinering: #undef Villkorlig inkludering: #if, #elif, #else, #endif, #ifdef, #ifndef
Filinkludering #include <filnamn> eller ”filnamn” Raden ersätts av hela innehållet i filnamn <filnamn> Sökvägen till filen är implementationsberoende, (tillhandahålls av systemet) ”filnamn” Filen eftersöks där källfilen hittades, (tillhandahålls av programmeraren)
Symboliska Konstanter Även det instruktion till pre-processor #define namn ersättningsuttryck Ersätter ett uttryck med ett annat Bra sätt att ersätta konstanta tal i programmet, ex gränsvärden Istället för att deklarera en variabel button i förra exemplet kunde button ha ersatts av uttrycket RA0
If-else If satsen exekveras om uttryck är sant, dvs är skilt från noll. Måste innehålla minst ett if, resten kan utelämnas. if (uttryck) sats else if (uttryck) else Följande har orsakat många missförstånd: if (num1 = 5) Alltid sant num1 tilldelas 5, däremot if(num1 = 0) Alltid falskt if (num1 == 5) Kan vara sant eller falskt if (num1 == 0) Kan vara sant eller falskt
Switch switch (uttryck){ case konstantuttryck: satser default: satser } break; Kan användas för att lämna sats, annars fortsätter exekveringen med nästa case
While och for slingor While satsen utförs om uttryck är sant dvs skilt från noll while (uttryck) sats For-satsen har tre komponenter Vanligast är att uttryck1 och uttryck3 är tilldelningar medan uttryck2 är ett relationsuttryck for (uttryck1; uttryck2; uttryck3) sats Break och continue break; används för att lämna inuti en slinga continue; påbörja nästa varv i en slinga, i while testas uttrycket igen i for överförs kontrollen till uppräkningsdelen.
Oändliga Slingor I inbyggda system är det vanligt att programmet innesluts av en oändlig slinga för att det inte skall avslutas Ex: while (1){ programmets körs för evigt } Eller: for (;;){
Exempel While(1),Switch Samma funktion som tidigare program men med while(1) och switch istället för if Switch ger i detta fall ett större program Program space used ( 4.5%) Data space used ( 10.3%) Mot tidigare Program space used ( 3.2%) Data space used ( 4.4%) Orsak: Kompilatorn gör om if satsen till ett enkelt bit test, sker ej i switch fallet
Vektorer Pekare till minnesblock Sekvens av viss variabeltyp, börjar på noll Sista elementet på n-1 platsen Kan vara flerdimensionella [n] [n] Datatyp Namn [storlek (n)] int nArray[4]; Skapar en vektor av 4 int int nDispArray[]={'1', 2 , 3}; Skapar en vektor av 3 int, initierad till {(ASCII för 1), 2, 3}
String String (teckenvektor) char cDispString[]="Volt"; Vektor av typen char Avslutas med NULL, görs därför i storlek [n+1] Kan initieras med strängliteral char cDispString[]="Volt"; Skapar en vektor av 5 char initierad till ASCII tecknen för Volt, + NULL(0) char cDispVal[5]; Skapar en vektor av 5 char Sista bör reserveras för NULL, alltså 4 användbara
Tilldelning av vektorelement Måste tilldelas element för element cArray1= cArray2; //Går inte för sig cArray1[1]= cArray2[2]; //Fungerar bättre Använd index for (i=0;i<4;i++) cDispVal[i]=i; //Lägger in värdet på i på position i cDispVal[i]='\0'; //Avsluta med NULL när det är en tecken vektor
Kodläsbarhet För att underlätta programförståelse Olika stilar, ex: variabelnamn börjar med liten bokstav (nLength, n_length) Symboliska konstanter med VERSALER (jfr. BUTTON) Använd beskrivande variabelnamn L kontra nLength V kontra fVolt Däremot enkla loopvariabler i,j,k, osv.. Tänk på att n inte är samma som N i C
Kompilering PICC Lite PICC Lite Integreras i MPLAB Gratisversion av PICC ANSI C kompilator från Hi-Tech Software http://www.htsoft.com/ Begränsningar Stödjer inte alla PIC:ar Begränsningar i program och dataminne för vissa (dock ej 16F84) Integreras i MPLAB C koden transformeras till assembler därefter maskinkod
Skapa Projekt med PICC Lite Project Wizard i MPLAB Kontrollera sökvägen till PICC kompilatorn (picl.exe) se nedan Lägg till filen lab1_demo.c till ert projekt
Kompilering För att kompilera programmet Kompileringsinställningar Build All eller Make Kompileringsinställningar Build Options Bl.a. inställningar för char och double
Simulering Debugger: Select Tool: MPLAB SIM Den genererade assemblerkoden visas med Disassembly Listing
Tips för simulering Använd Watch för att titta på variabler StopWatch för att mäta exekveringstider Beroende på vilket fönster som är aktiverat Stegas antingen instruktioner i assemblerkoden eller satser i C koden Högerklocka i C koden och välj Run to Cursor
Funktioner Varför? Funktionsdefinition Läsbarhet Divide and conquer Returtyp funktionsnamn(argumentdeklarationer) { Deklarationer och satser } Vissa delar kan utelämnas, ex returtyp (default int)
Funktionens komponenter En funktion behöver inte returnera något värde Används som subrutin Call by value (värdeanrop) Argumenten är kopior, lokala för funktionen Call by reference kan implementeras med pekare (alt. globala variabler) Variabler definierade inuti funktion är lokala Automatisk minnesallokering Lagringsklassen static kan användas för statisk allokering Om en funktion definieras efter att den anropas måste den deklareras innan den anropas, ex: void DelayUs(int x);
Exempel funktion Exempel på fördröjningsfunktion utan returvärde: void DelayUs(int x){ int y; y= (x - 40) >> 2 ; TMR0= 0xFF - y; while(T0IF == 0){ continue; } T0IF = 0; Anropa ovanstående funktion: DelayUs(100);