29.01.2015 Views

Lab 10

Lab 10

Lab 10

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Namn:<br />

<strong>Lab</strong>orationen godkänd:<br />

<strong>Lab</strong>oration <strong>10</strong><br />

Digitala system <strong>10</strong> p<br />

LTH Ingenjörshögskolan vid Campus Helsingborg<br />

Datorteknik, laboration 3.<br />

Avbrottshantering, klocka.<br />

Schemat från föregående laboration<br />

är nu kompletterat med två anslutningar<br />

till displayen.<br />

LE (Latch Enable)<br />

Om LE dvs bit 7 i PORTC sätts = 0,<br />

så är D1 och D2 öppna för data från<br />

PORTB.<br />

BL (Blanking)<br />

Om BL (Blanking) dvs bit 3 i PORTA<br />

sätts = 1, så släcks displayen.<br />

I nästan alla konstruktioner med enchipsdatorer låter man vissa programavsnitt köras<br />

med regelbundet återkommande intervall. Ibland behöver man göra regelbundna<br />

avläsningar av givare eller ha en exakt tidbas för en klocka. I denna laboration<br />

ska vi se hur man använder ett periodiskt avbrott. Vi ska använda alla fyra siffrorna i<br />

displayen för att göra en klocka med hjälp av det interna avbrottet OC2.<br />

Förberedelser:<br />

Läs i kompendiet kap 4 (Avbrottshantering) och 5.4 (Output Compare).<br />

Använd också databoken kap 5.4 och 9.3.<br />

Till laborationen måste du bl.a. känna till följande begrepp:<br />

Avbrottsvektor, avbrottsrutin, lokal avbrottsmask, kvittering av avbrott.<br />

Stefan Nyman 2006-02-03


Förbered laborationsuppgifterna 2, 4 och 5.<br />

Med hjälp av tipsen du får på föreläsningarna, kan göra det mesta före laborationen.<br />

Hemuppgift:<br />

Skriv en funktion countSeconds som utför följande:<br />

1. Öka variabeln seconds med ett.<br />

2. Justera värdet så att det ser decimalt ut.<br />

3. Nollställ det om det skulle bli = 60.<br />

4. Returnera värdet som ändrats så man lätt kan testa om det blivit = 0.<br />

Här är skalet till funktionen countSeconds.<br />

char countSeconds()<br />

{<br />

; // Öka variabeln seconds<br />

; // Decimaljustering<br />

; // Nollställ om det blivit 60 60<br />

return seconds;<br />

}<br />

<strong>Lab</strong>orationsuppgifter:<br />

<strong>Lab</strong>orationens mål är att få displayen att visa timmar och minuter<br />

eller minuter och sekunder.<br />

Klockan ska styras med timeravbrottet OC2, som ska ge avbrott var <strong>10</strong>:e ms utan att<br />

påverka någon utgång.<br />

Den ska kunna ställas genom att man trycker på knapparna:<br />

• Klockan går normalt om ingen knapp trycks ner<br />

• Klockans timmar bläddras upp med hjälp av en knapp.<br />

• Klockans minuter bläddras upp med en annan knapp.<br />

2<br />

Digitala system , <strong>Lab</strong><strong>10</strong> 2006-02-03


Uppgift 1.<br />

Skapa ett nytt projekt Klocka.prj. Utgå från inställningarna i <strong>Lab</strong>3.prj så slipper du<br />

göra om dom.<br />

Projektet ska innehålla:<br />

‣ cstartup.s07<br />

‣ Clock.c<br />

Uppgift 2.<br />

Denna fil skriver du i denna laboration. Enklast tar du den<br />

föregående laborationens Logik.c och kopierar och döper om<br />

den. Spara funktionerna initL1 och main. De andra funktionerna<br />

kan du ta bort!<br />

<br />

Funktioner för att initiera och sköta avbrott med periodiskt intervall. Avbrottet<br />

OC2 ska startas och styras så att det kommer exakt var <strong>10</strong>:e ms.<br />

Funktionen initOC2 ska innehålla de programrader som initierar OC2 så att det<br />

genereras avbrott utan att påverka någon utgång.<br />

Fyll först i hur dessa två register ska programmeras:<br />

TCTL1<br />

TMSK1<br />

Skriv funktionen!<br />

Avbrottsfunktionen OC2_interrupt skrivs nästan som en vanlig funktion.<br />

Definitionen måste föregås av ordet ”interrupt” och funktionens namn måste vara<br />

exakt det som återfinns i Vectors.h<br />

Avbrottsflaggan måste kvitteras och tiden för nästa Output Compare laddas i<br />

TOC2. Skriv en avbrottsfunktion som sköter dessa saker, dvs gör så att OC2 inträffar<br />

exakt var <strong>10</strong>:e ms.<br />

TFLG1<br />

TOC2 Decimalt: ..............<br />

Observera att du inte kan skriva samma värde i OC2 varje gång, utan egentligen ska<br />

skriva in den tidpunkt då nästa avbrott ska ske.<br />

3<br />

Digitala system , <strong>Lab</strong><strong>10</strong> 2006-02-03


Här är skalet till dessa två funktioner:<br />

// OC2 ska ge avbrott utan att påverka några utgångar.<br />

void initOC2 (void)<br />

{<br />

;<br />

}<br />

// Avbrottsfunktion OC2 kommer var <strong>10</strong>:e ms.<br />

interrupt void OC2_interrupt(void)<br />

{<br />

; // Kvittera avbrottet<br />

; // Återladda TOC2<br />

}<br />

<br />

Uppgift 3.<br />

Genom att skriva ett minimalt huvudprogram, kan du testa att avbrottet fungerar.<br />

Initiering<br />

initL1<br />

initOC2<br />

Huvudprogram<br />

OC2_interrupt<br />

Här har du hela skalet till Clock.c.<br />

// Clock.c<br />

#include "IO-reg.h" // Definitioner av alla registeradresser.<br />

#include "Vectors.h" // Ser till att avbrottsvektorer initieras.<br />

#include "intr6811.h" // Deklarationer av specialare, t.ex.<br />

// enable_interrupt().<br />

// Funktionerna: initL1, initOC2 och OC2_interrupt skriver du här.<br />

main(void)<br />

{<br />

initL1();<br />

initOC2();<br />

enable_interrupt();<br />

while (1)<br />

{<br />

}<br />

}<br />

4<br />

Digitala system , <strong>Lab</strong><strong>10</strong> 2006-02-03


Det kan vara svårt att testa att avbrottet kommer med exakt <strong>10</strong> ms intervall, men<br />

man kan ändå se att det kommer ofta. Lägg t.ex till raden<br />

PORTB++;<br />

i avbrottsfunktionen.<br />

Uppgift 4.<br />

I avbrottsfunktionen ska nu en klocka räkna upp displayen med sekunder och minuter.<br />

Avbrottsfunktionen för OC2 körs ju nu automatiskt var <strong>10</strong>:e ms. Skriv en<br />

funktion, clock(), som gör följande:<br />

<br />

clock<br />

Öka räknare med 1<br />

= <strong>10</strong>0 <br />

Ja<br />

Nollställ<br />

räknaren<br />

countSeconds<br />

Nej<br />

= 0 <br />

Ja<br />

countMinutes<br />

Nej<br />

= 0 <br />

Ja<br />

countHours<br />

Nej<br />

newtime = 1<br />

klart<br />

Härovan har du clock i form av flödesplan.<br />

Funktionen clock ska anropas från avbrottsrutinen som kommer var <strong>10</strong>.e ms och<br />

räkna upp variablerna counter, seconds, minutes och hours enligt flödesplanen ovan.<br />

Dessutom ska en variabel newtime användas som flagga att klockan ändrat värde.<br />

Variablerna ska fungera såhär:<br />

• counter: En räknare som räknar <strong>10</strong>0 avbrott. När counter = <strong>10</strong>0 ska den nollställas<br />

och sekunderna ska räknas upp.<br />

5<br />

Digitala system , <strong>Lab</strong><strong>10</strong> 2006-02-03


• seconds: Räknas upp med ett och decimaljusteras varje gång. Om sekunderna<br />

fått värdet 60 (efter decimaljustering) ska de nollställas och minuterna ska räknas<br />

upp.<br />

• minutes: Räknas upp och nollställs på samma sätt som sekunderna.<br />

• newtime: Ettställs varje gång klockan ändrat värde.<br />

clock använder funktionerna countSeconds, countMinutes och countHours som<br />

var och en returnerar värdet 0 om resp. räknevärde blivit = 0.<br />

Försök att själv komma på hur decimaljustering ska kunna göras.<br />

Testa programmet!<br />

Hitta själv på hur du ska sätta brytpunkter för att konstatera att programmet går<br />

rätt. Passa också på att titta på variablerna seconds och minutes t.ex.<br />

<br />

Uppgift 5.<br />

Vi ska komplettera med en funktion display som ska skriva ut innehållet i en 16-<br />

bitarsvariabel till displayen.<br />

// display<br />

// Skriver ut värdet av en 16-bitarsvariabel på displayen.<br />

void display(int siffror) // Funktionens lokala variabel: siffror<br />

{<br />

; // Nollställ stroben<br />

; // Skriv höga halvan av Siffror till PORTB<br />

; // Ettställ stroben<br />

; // Skriv låga halvan av Siffror till PORTB<br />

}<br />

Funktionen anropas med ett 16-bitarsvärde som parameter.<br />

T.ex. om A och B är två 8-bitarsvariabler så gör anropet<br />

display (A*256 + B);<br />

att värdet av A syns till vänster och B till höger.<br />

<br />

6<br />

Digitala system , <strong>Lab</strong><strong>10</strong> 2006-02-03


Uppgift 6.<br />

main<br />

Initieringar<br />

newtime<br />

=0<br />

Ja<br />

Nej<br />

Skriv ut<br />

tiden<br />

newtime = 0<br />

Komplettera nu huvudprogrammet så att det skriver ut minuter och sekunder varje<br />

gång newtime inte är = 0.<br />

Vad händer om man inte testar newtime utan skriver ut hela tiden<br />

....................................................................<br />

Varför......................................................................................................................<br />

Observara att innan du anropar display ska minuter och sekunder kombineras ihop<br />

till en 16-bitarsvariabel.<br />

Efter utskriften nollställs newtime.<br />

Tips: om man vill testa om newtime är skilt från 0, kan man helt enkelt skriva:<br />

if (newtime)<br />

{<br />

;<br />

}<br />

Det ser ju rätt lättläst ut.<br />

<br />

7<br />

Digitala system , <strong>Lab</strong><strong>10</strong> 2006-02-03


Uppgift 7.<br />

Det är bra om klockan kan ställas. Komplettera funktionen clock så att timmar och<br />

minuter kan stegas upp.<br />

Varje sekund testas knapparna:<br />

• Om ingen är nere: normal gång.<br />

• Om en av knapparna är nere (välj själv): Räkna upp timmarna.<br />

• Om en annan är nere: Räkna upp minuterna och nollställ sekunderna.<br />

Om man håller nere en knapp kommer uppräkningen att ske med ett varje sekund.<br />

Om man tycker det går för långsamt, så kan man också passa på att tvångsställa variabeln<br />

counter till ett mindre värde än <strong>10</strong>0.<br />

<br />

I nästa laboration kommer vi att bland annat se hur man på ett bättre sätt kan ställa<br />

klockan. Man vill ju t.ex. bläddra upp tiden med knapparna i sin egen takt.<br />

8<br />

Digitala system , <strong>Lab</strong><strong>10</strong> 2006-02-03

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!