# &microbe;

## Inledning och generell syntax

Microbe kompilerar program skrivna i språket anpassat för PIC:er, som ett medföljande program till &ktechlab;. Syntaxen har skapats för att passa ett &flowcode;-program. Syntaxen för att köra `microbe` på kommandoraden är:

    microbe [väljare] [indata.microbe] [utdata.asm]

där väljare är:

- `--show-source`: Lägger till varje &microbe;-källkodsrad som en kommentar i assemblerutmatningen innan själva assemblerinstruktionerna för den raden.

- `--no-optimize`: Förhindra optimering av instruktionerna skapade från källkoden. Optimering är oftast säker, alltså är väljaren i huvudsak avsedd för avlusning.

Filen indata.microbe måste identifiera PIC:n som är målet genom att infoga namnet på PIC:n längst upp i filen, t.ex. är namnet på PIC16F84 "P16F84".

### Enkelt fullständig &microbe;-program

    P16F84

    a = 0
    repeat
    {
            PORTA = a
            a = a + 1
    }
    until a == 5

    end

### Namngivningskonventioner

Följande regler gäller för variabelnamn och etiketter:

- De kan bara innehålla alfanumeriska tecken [a..z][A..Z][0..9] och understrecket "_".

- De är skiftlägeskänsliga.

- De kan inte börja med en siffra.

- De får inte börja med __ (dubbla understreck) eftersom det är reserverat för användning av kompilatorn.

### Parenteskonventioner

Klammerparenteser, {}, anger början och slutet på ett kodblock. De kan finnas var som helst före början och efter slutet på kodblocket. Exempel på korrekta kodblock:

    sats1 {
            någon kod
    }

    sats2 {
            annan kod }

    sats3
    {
            annan kod
    }

    sats5 {
            kodblock
    } sats6

### Kommentarer

Kommentarer liknar C. // kommenterar bort resten av raden. /* och */ anger en flerraders kommentar.

    // Det här är en kommentar
    x = 2
    /* Liksom denna
    flerraders kommentar */

### Programstruktur

PIC-id måste infogas överst i programmet. Slutet på huvudprogrammet anges med end. Subrutiner måste placeras efter end.

### Subrutiner

En subrutin kan anropas var som helst i koden. Syntax:

    sub SubrutinNamn
    {
            // Kod...
    }

Subrutinen anropas med call SubrutinNamn.

## &microbe; språkreferens

### if

Villkorliga hopp. Syntax:

    if [uttryck] then [sats]

eller

    if [uttryck] then
    {
            [satsblock]
    }

På liknande sätt för else:

    else [sats]

eller

    else
    {
            [satsblock]
    }

#### if

    if porta.0 is high then
    {
            delay 200
    }
    else
    {
            delay 300
    }

### alias

Skapar ett alias från en sträng till en annan. Syntax:

    alias [från] [till]

### repeat

Kör satsblocket upprepade gånger tills uttrycket utvärderas till true. Utvärderingen av uttrycket utförs efter satsblocket, så att satsblocket alltid körs minst en gång. Syntax:

    repeat
    {
            [satsblock]
    }
    until [uttryck]

### while

Liksom repeat, kör det satsblocket upprepade gånger. Dock utvärderas uttrycket innan körning, inte efter. Om uttrycket alltså utvärderas till false den första gången, körs inte satsblocket. Syntax:

    while [uttryck]
    {
            [satsblock]
    }

### goto

Gör att körning av koden fortsätter med nästa sats efter den angivna etiketten. Syntax för goto:

    goto [etikettnamn]

Etikettsyntax:

    etikettnamn:

Det är ofta god programmeringsvana att undvika användning av goto. Användning av kontrollsatser och subrutiner leder till ett mycket mer läsbart program.

#### goto

    goto MinEtikett

    ...

    [MinEtikett]:
    // Koden fortsätter på det här stället

### call

Anropar en subrutin. Syntax:

    call [SubrutinNamn]

där SubrutinNamn är namnet på subrutinen som ska anropas.

### delay

Gör att körning av koden stoppas under angiven tidsperiod. Intervallet anges i millisekunder. Syntax:

    delay [intervall]

För närvarande antar &microbe; att PIC:n använder frekvensen 4 MHz, dvs. varje instruktion tar 1 mikrosekund att köra. Om det inte är fallet, måste intervallet justeras proportionellt.

### sevenseg

Används för att definiera anslutningsavbildningen för en 7-segmentsdisplay (med gemensam katod) ansluten till PIC:n. Syntax

    sevenseg [namn] [a] [b] [c] [d] [e] [f] [g]

där [a] ... [g] är PIC:ns anslutningar dit respektive segment i 7-segmentsdisplayen är kopplade. Anslutningarna kan antingen skrivas som PORTX.N eller RXN.

För att visa ett tal på 7-segmentdisplayen, behandlas anslutningsavbildningen som en enbart skrivbar variabel.

#### Definiera och skriva ut på en 7-segmentsdisplay

    sevenseg seg1 RB0 RB1 RB2 RB3 RB4 RB5 RB6
    seg1 = x + 2

### keypad

Används för att definiera anslutningsavbildningen för en knappsats ansluten till PIC:n. Syntax:

    keypad [namn] [rad 1] ... [rad 4] [kolumn 1] ... [kolumn n]

där [rad 1] ... [rad 4] och [kolumn 1] ... [kolumn n] är PIC:ns anslutningar dit respektive rad och kolumn på knappsatsen är kopplade (för närvarande kan inte antal rader ändras). Se (ovan) för mer information om anslutningsavbildningar.

Knappsatsens kolumner ska använda ett 100k pull-down motstånd till jord. Radanslutningarna måste vara konfigurerade som utgångar och kolumnanslutningarna som ingångar. När knappsatsen väl har definierats, behandlas den som en enbart läsbar variabel.

#### Definiera och läsa från en knappsats

    keypad keypad1 RB0 RB1 RB2 RB3 RB4 RB5 RB6
    x = keypad1

Normalt är värdena som returneras för en knappsats:

- Värdet på siffran om det är en sifferknapp (1 till 3 längs övre raden, hexadecimalt A till D längs den fjärde kolumnen med fortsättning för varje extra kolumn).

- 253 för knappen i rad 4, kolumn 1.

- 254 för knappen i rad 4, kolumn 3.

Värdena kan definieras om genom att använda kommandot alias, där namnet på knappen i rad x, kolumn y (rader och kolumner börjar på 1), är Keypad_x_y. För att exempelvis ge asterisken på en 4x3 knappsats värdet noll, skulle följande alias användas:

#### Skapa ett alias för en knapp på en knappsats till ett värde

    alias Keypad_4_1 0

## PIC in- och utmatning

### Portriktning

Portriktningen anges genom att tilldela ett värde till TRIS*, där * är portbokstaven. Exempelvis:

#### Ställa in portriktningar

    TRISB = b'01111001'

Ovanstående ställer in anslutningarna RB1, RB2 och RB7 på PORTB som utgångar, och övriga anslutningar på PORTB som ingångar. I exemplet är b'01111001' den binära representationen av utgångstypen. Värdet 1 till höger representerar en utgång på RB0, och värdet 0 till vänster representerar en ingång på RB7.

### Port in- och utmatning

Porten kan behandlas som en variabel, exempelvis:

#### Skriva till en port

    x = PORTA

Det ovanstående tilldelar värdet av PORTA till variabeln x.

### In- och utmatning för anslutningar

Varje anslutning i en port erhålls genom att inleda anslutningsnumret med portnamnet: t.ex. anslutning 2 (med början på anslutning 0) på PORTA kallas PORTA.0. Syntaxen för att ställa in ett tillstånd på en anslutning är:

    PORTX.N = STATE

där STATE kan vara high (hög) eller low (låg). Syntaxen för att testa en anslutnings tillstånd är:

    if PORTX.N is STATEthen

Kombineras exemplen, får vi:

#### Ställa in och prova anslutningens tillstånd

    TRISA = 0
    TRISB = 255
    if PORTA.3 is high then
    {
            PORTB.5 = low
    }
    else
    {
            PORTB = PORTA + 15
    }

## Variabler

Alla variabler är 8-bitars heltal utan tecken, vilket ger intervallet 0 till 255. &microbe; stöder de typiska unära (som arbetar med en variabel) och binära (som arbetar med två variabler) operatorerna som stöds av PIC:n. Dessutom stöder &microbe; också division och multiplikation.

### Unära operationer

- rotateleft x - Roterar variabeln x åt vänster via carry.

- rotateright x - Roterar variabeln x åt höger via carry.

- increment x - Ökar variabeln x med ett. Om x har värdet 255, slår den runt till 0.

- decrement x - Minskar variabeln x med ett. Om x har värdet 0, slår den runt till 255.

### Aritmetik

Operationer som stöds:

- Addition: x + y

- Subtraktion: x - y

- Multiplikation: x * y

- Division: x / y

- Binär exklusiv ELLER: x XOR y

- Binär OCH: x AND y

- Binär ELLER: x OR y

### Jämförelse

Operationer som stöds:

- Lika med: x == y

- Skilt från: x != y

- Större än: x > y

- Mindre än: x < y

- Större än eller lika med: x >= y

- Mindre än eller lika med: x <= y

Till exempel:

#### Jämförelse

    if PORTA
    >= 5 then
    {
            ...
    }