Tycker det är konstigt om man inte har någon som kan C-programmering på skolan. Det är ju det mest allmänna programmeringsspråket som finns. Men jag kan förstå om materialet för just PIC är baserat på assembler, då man kommer mycket närmare processorn och hur den är uppbyggd.
Ungefär så här ligger det till:
Det finns massor av olika sorters microcontrollers och en massa olika tillverkare. Varje tillverkare har en eller flera varumärken. Bland 8-bitars controllers, vilka är de enklaste att lära sig, är
AVR från Atmel och
PIC från Microchip de allra vanligaste.
Assemblerkoden skiljer sig åt ganska mycket mellan olika märken, men själva programspråket C är ju detsamma oavsett vilken processor man använder.
Likheter och skillnader:
Båda typerna har tre sorters minnen: (1) Flashminne där programmet lagras, (2) SRAM där variabler lagras, samt EEPROM där man kan lagra data som ska bevaras.
Alla processorer har s.k. register, där de lagrar tillfällig data som de använder vid bearbetning. Antalet register kan variera, men i AVR är det vanligt med 32 st 8 bitars register. All data som ska bearbetas (adderas , jämföras etc) måste (vanligtvis) först hämtas in i ett register i CPU. I assembler benämns dessa register r0 - r31 men man kan också tilldela dem egna namn.
Sedan har microcontrollers ett antal kontrollregister som används till kommunikation med kringutrustningen - både internt och externt. Det är ett antal minnesadresser där varje adress har en speciell funktion. Exempel i AVR är t.ex några adresser som heter DDRB, PINB och PORTB. Skriver man data till dessa så påverkar man den enhet som heter "port B" i processorn. På så vis kan man programmera vissa pinnar på processorn som digitala utgångar eller ingångar (DDRB), läsa in data från ingångarna (PINB) eller skicka ut data på utgångarna (PORTB). Hur detta fungerar kan du läsa i databladet eller kolla något enkelt exempel. PIC har motsvarande funktioner, men med helt andra namn för samma funktioner (jag har hört talas om t.ex TRISA t.ex.)
Båda typerna har ungefär samma slags inbyggd kringutrustning som t.ex. Timers (används till en massa saker, bl.a till att utföra uppgifter med vissa tidsintervall, generera toner (ljud) mer mera), Analog-till-digital-omvandlare, UART (seriell asynkron kommunikation , t.ex. RS232 - används ofta för kommunikation med PC), SPI (3-trådars seriell dataöverföring, används för att skicka data till andra kretsar, även shiftregister), I2C ännu en form av seriell kommunikation osv...
Assemblerkoden: Assemblerinstruktionerna är helt olika till namnet och kanske syntax också, men funktionen är ganska detsamma ändå. PIC har vissa instruktioner som inte AVR har och vice versa. Därför, om man lär sig assembler för AVR så går det inte att använda på PIC. Däremot har man lärt sig grunderna i hur en 8-bitars processor arbetar kan man lättare lära sig att skriva assembler även för andra processorer. I assembler väljer man själv vilka register man ska använda för att lagra och beräkna data. Man får själv skapa utrymme i SRAM för lagring av variabler osv.
Programmera i C: Processorn fungerar likadant oavsett om du arbetar i assembler eller i C. dvs. du måste fortfarande sriva till DDRB eller PORTB om du ska skicka ut data på "port B". Men C underlättar eftersom du kan hantera 16 eller 32 bitars heltal och använda formler utan att behöva krångla med detaljer. Man behöver inte bry sig om CPU-registren alls - detta tar kompilatorn hand om och sköter själv. Du behöver inte bekymra dig om SRAM-minnet (så länge det räcker till): när du deklarerar variabler så ordnas utymme i SRAM automatiskt för dessa variabler.
exempel i assebler:
beräkning: läs in data från port A, addera 15 och multiplicera med 4, skicka ut svaret på port B:
( r16 är ett internt 8-bitars register i CPU som ofta används för temporär lagring av data)
Kod: Markera allt
; först konfigurera in- och utgångarna
; alla 8 bitar i port A ska vara ingångar
LDI r16, 0x00
OUT DDRA,r16
; alla bitar i port B ska vara utgångar
LDI r16, 0xff
OUT DDRB, r16
; läs in data från port A
IN r16, PINA
; addera tre
LDI r17, 3
ADD r16,r17
; multiplicera med fyra
lsl r16 ; logic shift left = alla bitar flyttas ett steg åt vänster, vilket binärt ger multiplikation med två.
lsl r16 ; en gång till
; resultatet finns nu i registret r16
; skicka ut det på port B
OUT PORTB,r16
END: rjmp END ; stanna här.
Assemblerkoden ovan är specifik för just AVR och kan inte användas på andra processorer. AVR har sitt eget assemblerspråk. För PIC hade det sett annorlunda ut (någon får gärna ta samma exempel för en PIC för att man ska se skillnaden).
samma sak i C:
läs in data från port A, addera 15 och multiplicera med 4, skicka ut svaret på port B:
Kod: Markera allt
int main(void) {
unsigned char temp; // ett 8-bitars positivt heltal
// konfigurera portar
DDRA = 0x00;
DDRB = 0xff;
// läs in från port A
temp = PINA;
// beräkna resultat och skicka ut till port B
PORTB = (temp + 3)*4;
while(1); // stanna här
}
Även om programspråket C fungerar på PIC lika bra som AVR, så skulle ovanstående program inte fungera på en PIC. Varför? Jo, för att i PIC så heter DDRA,DDRB,PINA,PORTB osv.. något helt annat (och ibland används de på ett annat sätt också). Därför måste man vara väl bekant med processormodellen för att kunna skriva ett program till den.
Per Foyers bok "Mikroprocessorteknik" är en utmärkt bok där han mycket pedagogiskt och enkelt förklarar hur en processor fungerar, hur ALU, minne, kringutrustning fungerar osv. Man lär sig hur kontrollregistren fungerar och man lär sig AVR assembler. Från sidan 1-76 är boken generell, dvs ger allmän grundkunskap som inte är specifik för just AVR. Där man går igenom hårdvara, binära tal, binära heltal och negativa tal, hexadecimala tal, minneshanering, allmänt om programmeringsspråk med mera. Från sidan 77 och framåt användar man sedan en AVR för olika exempel.[/i]