230 likes | 443 Views
Lektion 1. Introduktion till C för enchipsdatorer. Kursinnehåll. Innehåll C föreläsningar Viss del repetition Om användning av C för inbyggda system i allmänhet Använda C för programmering av PIC enchipsdator Plan för de närmaste två veckorna Preliminär, kan anpassas efter önskemål.
E N D
Lektion 1 Introduktion till C för enchipsdatorer
Kursinnehåll • Innehåll C föreläsningar • Viss del repetition • Om användning av C för inbyggda system i allmänhet • Använda C för programmering av PIC enchipsdator • Plan för de närmaste två veckorna • Preliminär, kan anpassas efter önskemål
Planering v1 • v1. Lektion 1: Introduktion till C för enchipsdatorer • C kontra assembler • Datatyper och variabler • Lagringsklasser och kvalificerare • Operatorer • v1. Lektion 2: Programstruktur och kompileringsprocess (1) • Symboliska konstanter • Villkorssatser • Vektorer • Funktioner • Kompilering av C program • v1. C Lab1: Förstå C och skiftregister för portexpansion • Undersök ett C program • Utöka programmet till multiplikator med skiftregister och display
Planering v2 • v2. Lektion 3: Programstruktur och kompileringsprocess (2) • Inline assembler • Interrupt • Kompileringsprocessen • v2. Lektion 4: Programmeringstekniker • Bit-fält i struct • Pekare • Programoptimering • v2. C Lab 2: PIC Termometer • Skiftregister från Lab 1 • Konstanter i EEPROM
Dagens Agenda • C kontra assembler • Datatyper och variabler • Storlek • Användning • Lagringsklasser och kvalificerare • Hur skall en specific variabel lagras, respektive behandlas av kompilatorn? • Operationer • Aritmetiska • Logiska • Bitvis logiska
C kontra Assembler • C • Ganska effektivt • Högre abstraktionsnivå, portabel kod • Lättare att hantera större projekt • Assembler • Snabbhet, mindre kodstorlek • Svårt att hantera större projekt
ANSI C • C • Första utgåvan av C publicerad 1978 • ANSI C, American National Standards Institute’s Standard för C (1989) • Varför ANSI C? • Kompilatorstöd (ex. PICC Lite –gratis!) • Utbredd användning (ca.80 % av alla inbyggda system projekt 1999-2000) • Bra stöd för hårdvarunära programmering • Andra Programmeringsspråk • C++ (Objektorienterad efterföljare, ej lika effektivt -producerar mer kod, standard?) • Ada (Stöd för parallella processer i språket, används till största delen i försvarsindustri)
Inledande Exempel Ganska lätt att förstå! Ett tal räknas upp från 0 till 1000 (3E8) unsigned int j; for(j = 0 ; j<1000; j++) continue; Betydligt svårare! (reg d lägsta byte, reg e högsta byte) Adress Maskinkod Assembler 0003EC 18D CLRF 0xd ;clear register d 0003ED 18E CLRF 0xe ;clear register e 0003EE A8D INCF 0xd, F ;incr. d put back in d 0003EF 1903 BTFSC 0x3, 0x2 ;run next if reg. 3 bit 2 = 1 (statuz z=1) 0003F0 A8E INCF 0xe, F ;incr. d put back in e 0003F1 3003 MOVLW 0x3 ;load 3 to work 0003F2 20E SUBWF 0xe, W ;sub f-w put in w (1st 253 in w) 0003F3 30E8 MOVLW 0xe8 ;load e8 to work 0003F4 1903 BTFSC 0x3, 0x2 ;run next if reg. 3 bit 2 = 1 (statuz z=1) 0003F5 20D SUBWF 0xd, W ;sub f-w put in w 0003F6 1C03 BTFSS 0x3, 0 ;run next if reg. 3 bit 0 = 0 0003F7 2BEE GOTO 0x3ee ;back to 3ee
Variabler • En variabel avser ett visst minnesutrymme • Variabler deklareras av en viss datatyp • Storlek och värde på variabler • Viktigt att använda rätt datatyp m.a.p. minneskrav, korrekthet och prestanda • I föregående exempel unsigned int • 16 bitar (två register krävs)
Datatyper • Heltalstyper • bit (1 bit, 0 eller 1, ej ANSI C standard men stöds av PICC och kan användas för att spara minne) • Mindre heltal • char (8 bitar, signed or unsigned) • default unsigned, ändras i kompilatorinställningarna) • Andra större heltal (little endian, minst värda byten på lägsta adressen) • short = int (16 bitar, signed) • unsigned short = unsigned int (16 bitar, unsigned) • long (32 bitar, signed) • unsigned long (32 bitar, unsigned)
Flyttal • Flyttal (tal med flytande decimalpunkt),notera att heltalet (alltid =1 för alla tal utom 0) i signifikanden ej lagras – används för ökad precision • float (24 bitar) • double (32 bitar, välj 24 eller 32 i kompilatorinställningarna) • Det som skiljer är noggrannhet
Flyttalsrepresentation (PICC Manual) Ex: Pi ≈ 3,14159261 1,00 1001 0000 1111 1110 1101 001 Med double 24 bit-> Pi=3,141602 0 100 0000 0 100 1001 0001 0000 Med double 32 bit-> Pi=3,141593 0 100 0000 0 100 1001 0000 1111 1101 1011 Varför?
Blandning av datatyper • Typomvandling sker från ”lägre” till ”högre” typ • Vad händer? • unsigned int u; • if (u >-1) • Alltid falskt! • -1 omvandlas till unsigned (1111 1111 1111 1111) • Antag: int 16 bit och long 32 bit • Då är -1L < 1U men -1L > 1UL (L suffix för long, U suffix för unsigned, UL suffix för unsigned long)
Talformat (PICC Manual) Se upp med att använda 0 före ett tal Det betyder att det tolkas som oktalt
Lagringsklasser • Lagringsklasspecificerare talar om hur en variabel lagras • Extern • Global, extern behöver inte deklareras om den definieras i samma fil före den används • Auto • Behöver ej anges, automatisk allokering, i PICC bank 0 (kan ändras med bank kvalificerare) • Static • Extern blir osynlig utanför källfilen • Auto variabels värde kvarstår utanför funktion • Register • Lagra helst i register, inte aktuellt i vår PIC där vi endast arbetar med register
Kvalificerare • Datatypkvalificerare talar om hur kompilatorn skall tolka en variabel • const • Variabler med konstant värde (läggs i programminne, observera att detta inte gäller konstanta pekare) • volatile • Talar om för kompilatorn att värdet kan ändras emellan successiva accesser • Förhindrar att kompilatorn optimerar till synes redundanta avsnitt • Viktigt att tänka på vid interrupt och minne som delas av flera processorer • Speciella datatypkvalificerare (PICC) • absolute • Specific adress kan anges för globala och statiska variabler • volatile unsigned char @ 0x06; • persistent, bank ock eeprom
Exempel • I filen pic1684.h är SFR deklarerade och mappade till specifika adresser: • Lagringsklass kvalificerare datatyp absolut @ adress • static volatile unsigned char PORTB @ 0x06; • static unsigned char bank1 OPTION @ 0x81; • static volatile bit RB7 @ (unsigned)&PORTB*8+7; • static bank1 bit RBPU @ (unsigned)&OPTION*8+7; • Varför är inte OPTION volatile?
Operatorer • Aritmetiska • +,-,*,/ • Modulus %, ger rest vid heltalsdivision • Ex: 25%10 = 5 • Logiska (Förväxla ej med bitvis) • &&, ||, ! • Jämförelse • ==, >=, <=,>,<
Bitmanipulation • Bitvisa operatorer, används på heltalstyper • Varje operand behandlas som en ordnad bitvektor, jämförs bit för bit • Ett komplementet ~ • varje bit inverteras • Och & • Returnerar 1 om båda bitarna är 1 • Eller | • Returnerar 1 om någon av bitarna är 1 • Exlusivt eller ^ • Returnerar 1 om ena biten är 1 och den andra 0 • Skift operatorn • Skifta vänster << • Skifta höger >> • a = b << 6 (innehållet i b skiftas 6 steg åt vänster, de 6 bitarna längst till vänster i b förvinner, fylls på med nollor från höger • Se upp med högerskift och signed integer • Om neg. tal kan det fyllas med ettor från vänster (kompilatorberoende PICC sign extension dvs. med ettor)
Maskning • Ett bitmönster transformeras till ett annat genom en logisk bitvis operation • Testa enstaka bit • If (bitvar & 0x04) //Alt. 1: test av bit 2 • If (bitvar & (1 << 2)) //Alt. 2: test av bit 2 • Sätta enstaka bit • Bitvar = Bitvar | (1 << 2); // Sätt bit 2 till 1 • Bitvar |= (1 << 2); // Sätt bit 2 till 1 • Nollställa enstaka bit • Bitvar &= ~(1 << 2) //Nollställ bit 2 • Kombinera bitar ur flera register • nVolt = 0 | ADRESH; • nVolt = (nVolt << 8) | ADRESL;
Defaultvärden för konstanter • Se upp med att masken är lika stor som operanden! • unsigned long j • j=0xFFFFFFFF; • j &= ~(1 << 15); // j kan bli 0x00007FFF! • j &= ~(1 << 16); // j kan bli 0xFFFFFFFF! • 1 default int 16 bitar, istället 1L (suffix för long) • j &= ~(1L << 15); // j blir 0xFFFF7FFF! • j &= ~(1L << 16); // j blir 0xFFFEFFFF! • char i; • i=0x55; • if (~i == 0xAA) //Lurigt, heltalsbefordring till int ger: ~0x0055 = 0xFFAA
Testa flera bitar • Om man vill testa fler bitar • Ex. testa om bit 0 och 1 är satta • if (bitvar & 0x03) • True för bit 0 eller bit 1 • if ((bitvar & 0x03) == 0x03) • if (bitvar & 0x01 && bitvar & 0x02) • Båda måste vara true