240 likes | 607 Views
Lektion 2. Programstruktur: C för enchipsdatorer. Dagens Agenda. Uppvärmning 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
E N D
Lektion 2 Programstruktur: C för enchipsdatorer
Dagens Agenda • Uppvärmning • 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
C Preprocessor • Preprocessor • 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) • sats • else • sats • 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 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 (;;){ programmets körs för evigt }
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) • 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 • Använd index • Måste tilldelas element för element cArray1= cArray2; //Går inte för sig cArray1[1]= cArray2[2]; //Fungerar bättre 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 • 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 • 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? • Läsbarhet • Divide and conquer • Funktionsdefinition 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);