1.3.11 Programmering MCS51

Mikrokontrollerens programkode skrives som assemblerinstruksjoner eller i et programmeringsspråk på et høyere nivå som eksempelvis PLM og C++. Kode skrevet i assembler gir et mer kompakt program og utnytter plassen i hukommelsen mer effektivt. Da hukommelsen i en mikrokontroller er ganske begrenset, kan det derfor være en fordel å skrive programmet i assemblerkode. Etter hvert som utviklingen har gått fremover er det fremkommet mikrokontrollere med stadig større minnekapasitet, og programmering i høynivåspråk er blitt mer aktuelt. Å programmere i høynivåspråk gjør også arbeidet enklere når man først har tilegnet seg kunnskapen.

I dette kapittelet i den videre presentasjonen av MCS51 vil vi kun konsentrere oss om assemblerkoding, da denne gir en god innsikt og forståelse av de mekanismer som foregår mellom mikrokontrollerens programvare (software) og hardvare (hardware). I kapittel 3.4 vil vi ved hjelp av utviklingsverktøyet Arduino ta for oss en mer moderne mikrokontroller for programmering i et høynivåspråk.

Da de første mikrokontrollerne så dagens lys, skrev man programmene i assemblerkode. Årsaken var først og fremst den begrensede ROM-kapasiteten i komponentene, siden program i assemblerkode krever langt mindre minnekapasitet enn tilsvarende program i høynivåspråk. Etter hvert fikk mikrokontrollerne stadig større minnekapasitet, og det ble vanlig å utarbeide programmer også i høynivåspråk.

I denne sammenheng vil vi kun ta for oss assemblerprogrammering, da denne formen for koding gjør det enkelt å forstå de grunnleggende mekanismene som foregår i selve mikrokontrolleren mellom hardwaredelen og softwaredelen.

  • Program for mikrokontrollere skrives som instruksjoner i assemblerkode eller i høynivåspråk (for eksempel C eller – mer vanlig – C++).

  • Instruksjonene kalles kildekode og lagres som en kildefil (eng. source-file)

  • Instruksjonene skrives som forståelig tekst, men må oversettes til maskinkode før de kan kjøres i mikrokontrolleren. Dette kalles assemblering.

  • Kildefilen kan skrives som en vanlig tekstfil, men må normalt lagres som DOS-tekst for å kunne behandles i en assembler.

  • Etter at kildefilen er kjørt i en assembler, genereres en listfil og en objektfil (nærmere forklaring kommer lenger bak i presentasjonen).

Assemblerinstruksjoner for MCS51

Instruksjonene grupperes etter funksjonstilhørighet:

  • aritmetiske instruksjoner (Arithmetic operations)

  • logiske instruksjoner (Logical operations)

  • instruksjoner for dataoverføring (Data transfer)

  • bitinstruksjoner (Boolean variable manipulation)

  • hoppinstruksjoner (Program branching)

Aritmetiske instruksjoner

Aritmetiske instruksjoner er instruksjoner som utfører rene regneoperasjoner.

Eksempel:

ADD A,#04 ;adderer innholdet i akkumulator med tallet 4

(# indikerer at verdien som følger, er en konstantverdi (tall) og ikke en adresse.)

ADD A,04 ; adderer innholdet i akkumulator med innholdet i adresse 4

 

Legg merke til kommentarene som er skrevet etter operasjonen.

Det er viktig at disse innledes med semikolon for at de skal bli oversett av assembleren når kildeprogrammet skal assembleres.

Logiske instruksjoner

Logiske instruksjoner er instruksjoner som utfører logiske operasjoner som OG (AND), ELLER (OR) osv.

Eksempel:

ANL A,#00110101B  ;logisk OG mellom akkumulator og bitmønsteret 00110101

Samme instruksjon kan også skrives med heksadesimalte tall:

ANL A,#35H 

Andre logiske instruksjoner:

  ORL – logisk ELLER

  XRL – eksklusiv ELLER

Instruksjoner for kontroll og setting av bit

Eksempel på instruksjoner som kontrollerer signaler eller bit, er JB og JNB:

JB P1.0,LOOP  ;hopp til adresse LOOP dersom port P1.0 er høy

JNB SIGNAL, LOOP ;hopp til adresse LOOP dersom SIGNAL ikke er høy

Når enkle utgangssignaler eller bit i hukommelsen skal settes, kan vi benytte instruksjonen SETB. Ved nullstilling av tilsvarende benyttes CLR. Eksempel:

  SETB P0.2  ;setter port P0.2 høy

  SETB SIGNAL  ;setter SIGNAL høy

  CLR P2.4  ;setter port P2.4 lav

Hoppinstruksjoner

Hoppinstruksjoner kan deles i tre hovedtyper:

  • ubetingede hopp

  • betingede hopp

  • relative hopp

Noen instruksjoner er en kombinasjon av disse typene.

Ved ubetinget hopp utføres et direkte eller indirekte hopp til en annen adresse, eksempelvis:

AJMP START; hopp til programadresse START

Betingede hopp utføres når en bestemt betingelse er oppfylt, eksempelvis:

JZ START   ;   hopp til adresse START hvis akkumulator er lik 0

Den siste typen instruksjon er samtidig en relativ hoppinstruksjon. Det betyr at programtelleren hopper et visst antall adresser forover eller bakover i programmet relativt til der den i øyeblikket peker.

Programutvikling

Når det skal utvikles program for en mikrokontroller, er det viktig å ha oversikt over hele utviklingsprosessen samt hvilken funksjon mikrokontrolleren skal ha for den enheten den skal benyttes i.

Blokkskjema mikrokontroller

Før man setter i gang programmeringsarbeidet, kan det være lurt å skaffe seg oversikt over alle signaler som skal brukes til og fra mikrokontrolleren for tilkobling til portene.

Blokkskjema for mikrokontroller anvendt i en alarmenhet:

Flytdiagram

Eksempel på flytdiagram for alarmenheten:

Programkode

  • Instruksjoner og operasjonskoder skrives linje for linje.

  • Eventuelle kommentarer må innledes med et semikolon (;) for ikke å lage problemer for assembleren.

  • Hvis ikke noe annet er angitt, vil programmets startadresse ligge på adresse

  0000H.

  • Dersom vi ønsker at programmet skal starte på en annen adresse, kan dette gjøres ved direktivet ORG. Eksempel:

  ORG 0030H

  • Programkoden for de tre første boksene i flytdiagrammet:

  START: JNB AKTIV,START   ;hopp til START dersom signalet AKTIV ikke er på

  • SETB GR_LED      ;tenn grønn lysdiode

Her indikerer START: en startadresse i programmet. START må avsluttes med kolon (:) for at assembleren skal oppfatte dette som en programadresse. Alle programadresser som navngis med etiketter på denne måten, må alltid avsluttes med kolon.

Assemblering

  • Programkoden (kildefilen) overføres til et assemblerverktøy (assembler) for assemblering.

  • I assembleren blir programkoden omgjort til maskinkode, det vil si 0-er og 1-ere.

  • Under assembleringen genereres en listfil (filnavn.lst) og en objektfil (filnavn.obj).

  • Listfilen gir en fullstendig oversikt over resultatet av assembleringen med eventuelle markeringer av feil (syntaksfeil).

  • Om listfilen er feilfri, betyr det ikke nødvendigvis at programmet er logisk riktig.

  • Dersom listfilen oppgir feil, må kildefilen rettes opp og assembleres på nytt til listfilen er helt feilfri.

  • Objektfilen benyttes i forbindelse med fremstilling av hexfil for programmering av PROM i mikrokontrolleren.

Simulering og debugging

De fleste programverktøy som benyttes til programmering og assemblering, har også mulighet for simulering og emulering av programmet. Dette kan være arbeidssparende under uttesting av den fysiske enheten som mikrokontrolleren skal plasseres i.

Med en simulator kan vi et godt stykke på vei analysere og kontrollere at programmet er logisk riktig og gjør den jobben det skal, før det brennes i selve mikrokontrolleren.

Ved å angi start- og stoppadresser kan man kontrollere (debugge) deler av programmet og skritt for skritt kontrollere om porter, registre og datahukommelse opererer riktig til riktig tidspunkt.

Brenning av mikrokontrollerens PROM

  • Denne delen av prosessen krever eget utstyr (programmeringsverktøy) tilsvarende det som benyttes for programmering/brenning av vanlige PROM-er. Disse er vanligvis beregnet for tilkobling til PC.

  • Ved hjelp av programmeringsverktøyet kan programmet overføres til mikrokontrolleren

  • Plasser mikrokontrolleren i sokkelen på programmeringsverktøyet og følg angitt prosedyre som eventuelt følger med eller kommer opp på PC-skjermen.

  • Det assemblerte programmet «brennes» inn i mikrokontrollerens PROM eller EPROM ved hjelp av egen prosedyre (avhengig av hvilket verktøy du benytter).

  • Under assembleringen ble det opprettet en objektfil som inneholder en sjekksum og de heksadesimale kodene som benyttes for programmering av mikrokontrollerens PROM-del.

Programmering, utviklingsverktøy

Det er i handelen forskjellige typer utviklingsverktøy for mikrokontrollere, både til utvikling av program og brenning av selve mikrokontrolleren.

Utviklingsverktøy for programmering av mikrokontroller for tilknytning til PC (Ceibo):

Emulering og fysisk testing

  • På en digital trainer kan mikrokontrolleren testes fysisk når den er ferdig programmert.

  • Programmet vil normalt starte når driftsspenning settes på, eller når mikrokontrollerens resetinngang aktiveres.

  • Ved å tilføre signal til inngangene kan vi kontrollere eller måle om utgangene reagerer slik de skal.

  • Det finnes også emulatorverktøy (In-circuit emulator) der vi ved hjelp av en plugget sokkel kan erstatte selve mikrokontrolleren i det utstyret den skal plasseres. Da kan vi kjøre en fullstendig fysisk kontroll av programmet før mikrokontrolleren brennes.

Utstyr for programmering

Her er en link til en emulator levert av Ceibo: http://www.ceibo.com/eng/pdf/ds51.pdf

Her er et annet utviklingsverktøy: http://www.pjrc.com/tech/8051/

Utstyr for brenning (programmering) av mikrokontrollere. Enheten tilkobles USB-porten på en PC:

Kretsskjema

Kretsskjema for alarmkretsen (tegnet i Proteus):

Eksempel på bruk av mikrokontroller i OG-funksjon

OG-port med logisk uttrykk og sannhetstabell:

Flytdiagram og assemblerkode for OG-port

Flytdiagram og assemblerkode for OG-port med to innganger:

Assemblerprogram

Programmet for OG-operasjonen:

INN_A   EQU P0.0

INN_B   EQU P0.1

X  EQU P1.5

;dette er et program som benytter mikrokontrolleren som en OG-port

START:   JNB INN_A,X_LIK_0   ; sjekker inngang A

  JNB INN_B,X_LIK_0   ; sjekker inngang B

  SETB X   ; setter utgangen X lik 1

  JMP START

X_LIK_0: CLR X   ; setter utgangen X lik 0

  JMP START

  END

Program for OG-funksjonen

#######################################################################

#                                                                     #

# Micro Series 8051 Assembler V2.03/DOS 22/May/08 11:13:04           #

#                                                                     #

# Source = n:\iar\exe\ogport.txt                                     #

#                                                                     #

# List = ogport.lst                                                   #

#                                                                     #

# Object = x.r03                                                     #

#                                                                     #

# Options = f                                                         #

#                                                                     #

#######################################################################

;dette er et program som benytter mikrokontrolleren som en OG-port

1 0080   INN_A EQU P0.0

2 0081   INN_B EQU P0.1

3 0095   X EQU P1.5

4

5 0000 308007   START:   JNB INN_A,X_LIK_0   ; sjekker inngang A

6 0003 308104   JNB INN_B,X_LIK_0   ; sjekker inngang B

7 0006 D295   SETB X   ; setter utgangen X lik 1

8 0008 80F6   JMP START

9 000A C295   X_LIK_0:   CLR X   ; setter utgangen X lik 0

10 000C 80F2   JMP START

11 000E END

Errors: None ##########

Bytes: 14   # ogport #

CRC: 0F68   ##########

Tabell   Programmet for OG-fuksjonen ferdig assemblert

Assembler

En assembler for gratis nedlasting kan du finne på denne linken: http://plit.de/asem-51/

NB! Les brukerbetingelsene før du tar i bruk programmet!

Tabell Assemblerinstruksjoner for MCS 51-serien:

Instruksjon

Engelsk beskrivelse

Norsk beskrivelse

ACALL

Absolute subroutine call

Hopp til subrutine

ADD

Add

Addisjon

ADDC

Add with carry

Addisjon med mente

AJMP

Absolute jump

Absolutt hopp

ANL

Logical AND

Logisk OG

CJNE

Compare and jump if not equal

Sammenlign og hopp hvis ikke lik

CLR

Clear

Nullstill

CPL

Complement

Komplementer (snu)

DA

Decimal adjust

Sett til desimalverdi

DEC

Decrement

Dekrementer (reduser med 1)

DIV

Divide with

Divider med

DJNZ

Decrement and jump if not zero

Reduser med 1 og hopp hvis ikke lik null

INC

Increment

Inkrementer (øk med 1)

JB

Jump if bit is set

Hopp hvis bit er satt

JBC

Jump if bit is set & clear bit

Hopp hvis bit er satt & nullstill bit

JC

Jump if carry is set

Hopp hvis menteflagg er satt

JMP

JMP

Hopp

JNB

Jump if bit not set

Hopp hvis bit ikke er satt

JNC

Jump if carry not set

Hopp hvis ikke menteflagg er satt

JNZ

Jump if accumulator is not zero

Hopp hvis ikke akkumulator er null

JZ

Jump if accumulator is zero

Hopp hvis akkumulator er null

LCALL

Long subroutine call

Langt subrutinehopp

LJMP

Long jump

Langt hopp

MOV

Move data

Flytt data

MOVC

Move Code

Flytt kode

MOVX

Move external

Flytt eksternt (ekstern hukommelse)

MUL

Multiply

Multipliser

NOP

No operation

Ingen operasjon (fyllinstruksjon)

ORL

Logical OR

Logisk ELLER

POP

Pop from stack

Hent fra stakk

PUSH

Push on stack

Overfør til stakk

RET

Return from subroutine

Returner fra subrutine

RETI

Return from interrupt

Returner fra interupt

RL

Rotate left

Roter til venstre

RLC

Rotate left through carry

Roter til venstre via mente

RR

Rotate right

Roter til høyre

RRC

Rotate right through carry

Roter til høyre via mente

SETB

Set bit

Sett bit lik \"1\"

SJMP

Short jump

Kort hopp (relativt)

SUBB

Subtract

Subtraksjon

SWAP

Swap nibbles

Bytt om de fire MSB med de fire LSB

XCH

Exhange

Kryssbytting

XCHD

Exchange low order digit

Kryssbytt laveste siffer

XRL

Exclusive OR

Eksklusiv ELLER