23.08.2013 Views

Ladda ner rapporten... - EIT - Lunds Tekniska Högskola

Ladda ner rapporten... - EIT - Lunds Tekniska Högskola

Ladda ner rapporten... - EIT - Lunds Tekniska Högskola

SHOW MORE
SHOW LESS

Create successful ePaper yourself

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

Väderstation<br />

Projektrapport, Digitala projekt HT 04<br />

Institutionen för Informationsteknologi<br />

Utfört av: John Kaber och Marcus Ekerhult<br />

Handledare: Bertil Lindvall<br />

Datum: 2004-12-07


Sammanfattning<br />

Vårt projekt inriktar sig på styrning och avläsning av sensorer, vilket vi anser blir ett mer<br />

och mer attraktivt område inom industrin. Väderstationen har två stycken<br />

temperatursensorer och själva kärnan i systemet är uppbyggt runt den välkända<br />

processorn 68008 från Motorola. Nu valde vi temperatursensorer, men i praktiken hade vi<br />

kunnat välja sensorer för tryck, fuktighet, acceleration, m.m. Det är bara fantasin och<br />

naturligtvis pengarna som avgör användningsområdet.<br />

Väderstationen har en alfanumerisk LCD-display, samt en 16-knappars knappsats för<br />

styrning av systemet.<br />

Sida 2 av 43


Innehållsförteckning<br />

Väderstation.........................................................................................................................1<br />

Sammanfattning ...................................................................................................................2<br />

Innehållsförteckning.............................................................................................................3<br />

Inledning ..............................................................................................................................4<br />

Genomförande......................................................................................................................5<br />

Ritning..............................................................................................................................5<br />

Virning .............................................................................................................................5<br />

Test av hårdvaran med it-68.............................................................................................5<br />

Utveckling och test av mjukvaran med it-68 ...................................................................6<br />

Bortkoppling av it-68 .......................................................................................................6<br />

Beskrivning av användargränssnitt ......................................................................................7<br />

Ställ klocka.......................................................................................................................7<br />

Visa Temperatur ...............................................................................................................8<br />

Visa sparad data ...............................................................................................................8<br />

Visa min och max ............................................................................................................9<br />

Ställ alarm........................................................................................................................9<br />

Resultat...............................................................................................................................11<br />

Diskussion..........................................................................................................................12<br />

Appendix A: Programkod ..................................................................................................13<br />

Appendix B: PAL ..............................................................................................................40<br />

Appendix C: Hårdvara - En sammanfattning av kopplingsschemat..................................42<br />

Processor: Motorola 68008 ............................................................................................42<br />

SRAM: 43256 ................................................................................................................42<br />

EPROM: 27C256 ...........................................................................................................42<br />

PAL: PAL22V10 ...........................................................................................................42<br />

Knappsats: 16 knappars telefontangentbord ..................................................................42<br />

Knappsatsavkodare: 74C922..........................................................................................42<br />

Temperaturgivare: LM335 .............................................................................................42<br />

A/D-omvandlare: ADC0804 ..........................................................................................42<br />

Spänningsreferenser: LM336 .........................................................................................43<br />

Realtidsklocka: ICM7170 ..............................................................................................43<br />

LCD display:..................................................................................................................43<br />

Sida 3 av 43


Inledning<br />

Denna rapport är en del av kursen Digitala Projekt vilken ges av Institutionen för<br />

Informationsteknologi vid <strong>Lunds</strong> <strong>Tekniska</strong> <strong>Högskola</strong>.<br />

Kursen är som namnet antyder projektbaserad och går i stora drag ut på att man skall<br />

realisera en applikation med hjälp av hårdvara, samt dokumentera och redovisa sina<br />

resultat.<br />

Vi har valt att bygga en Väderstation och har satt upp följande krav på vår konstruktion:<br />

Två analoga signaler (från temperaturgivare) ska avläsas och presenteras kontinuerligt i<br />

hela grader Celsius. Varje sekund skall det aktuella värdet tillfälligt sparas undan för att<br />

var 60:de sekund, det vill säga varje minut, bilda medelvärdet av den aktuella<br />

temperaturen.<br />

När så önskas skall dygnets max- och minimitemperatur kunna presenteras i hela grader<br />

Celsius samt även dygnsmedeltemperaturen.<br />

Mätinsamling med tidsangivelse (mån, dag, tim, min) skall kunna presenteras.<br />

Via knappsatsen skall två larmgränser kunna programmeras in (till en av mätarna).<br />

När någon av larmgränserna överskrids ska varning ske.<br />

Temperaturintervallet väderstationen skall kunna mäta inom är det normala svenska<br />

medelklimatet.<br />

Rapporten behandlar den hårdvara vi valde samt de problem som uppstod vid<br />

genomförandet.<br />

Institutionen tillhandahåller två olika plattformar att utveckla på; AVR ATMega16, samt<br />

Motorola mc68008,<br />

Vi valde att an mc68 eftersom vi skulle spara undan en relativt stor mängd data och<br />

mc68 kan adressera en större rymd at ATMega16.<br />

Sida 4 av 43


Genomförande<br />

Genomförandet av väderstationen kan sammanfattas under fem huvudpunkter:<br />

• Ritning av kretsschema i programmet PowerLogic<br />

• Virning och lödning av komponenter.<br />

• Test av hårdvara med it-68<br />

• Utveckling och test av mjukvara med it-68<br />

• Bortkoppling av it-68<br />

Ritning<br />

Ritningen påbörjades strax efter första laborationen och pågick en dryg vecka. En del<br />

modifieringar har tillkommit efter hand.<br />

Schemat är ritat i programmet PowerLogic. Vi fick hjälp av vår handledare Bertil med<br />

tips och trix, men mycket av problemen vid ritningen löstes med hjälp av databladen.<br />

Virning<br />

När vi ritat klart på datorn var det dags att börja bygga. Lite komponenter, verktyg samt<br />

ett experimentbord från Bertil var det som behövdes för att komma igång.<br />

Att vira var ett arbete som till en början var både tidsödande och lite knepigt. Nu i slutet<br />

känns det naturligt och fort går det dessutom. Det är lätt att göra ändringar, om felen<br />

upptäcks dvs. Att etsa ett kort till ett sådant här projekt vore helt otänkbart med tanke på<br />

alla de logiska fel som gjordes från början. All drivspänning till kretsarna löddes fast med<br />

lite grövre kopplingsråd, då det inte är säkert att wiretråd klarar det strömuttag som kan<br />

uppstå. De båda oscillatorerna byggdes upp på ”sk lödsocklar” för att få ett kompakt<br />

format då detta är högst önskvärt när det gäller oscillatorer.<br />

Test av hårdvaran med it-68<br />

Bertil introducerade oss till hur testning av hårdvaran går till. Genom att på ett metodiskt<br />

sätt koppla in en komponent i taget, kan man isolera de problem som uppstår. Hade vi<br />

istället pluggat in alla komponenter på en gång och sedan direkt börjat felsöka, hade vi<br />

med största sannolikhet inte hittat enstaka fel.<br />

Displayen hade vi relativt stora problem med att få initierad. Till slut visade det sig att vi<br />

både hade vänt den upp och <strong>ner</strong>, samt vänt på MSB och LSB i databussen. Det var ett<br />

stort steg att få igång displayen, då den gav oss möjlighet att visuellt visa olika värden<br />

från kringkomponenter såsom RTC och ADC.<br />

RTC:n fick vi snabbt igång, med tillägg att vi inte förstod hur den skulle ställas in på rätt<br />

tid. Efter ett par timmar med det lite torftiga databladet och it-68: an, tickade den igång<br />

med rätt tid i registrena, samt ge<strong>ner</strong>erade ett avbrott varje sekund.<br />

ADC kretsarna fick vi komplettera med två stycken spänningsreferenser på 2.5V för att<br />

begränsa spänningssvinget och på så vis öka upplösningen.<br />

Sida 5 av 43


Utveckling och test av mjukvaran med it-68<br />

För att konstruktionen skall fungera krävs att parametrar som t.ex. stackpekare initieras i<br />

assembler. Vi fick från början ett färdigt programskelett att jobba med. Detta var en<br />

lättnad, då ingen av oss var någon höjdare på vare sig C eller Motorola-assembler. Vi fick<br />

dessutom låna en bra handbok i C av Bertil, så nu när projektets är slut är vi självfallet<br />

mästare på C.<br />

För att kunna utveckla programkod på ett effektivt sätt har en utvecklingsmiljö (ICE, In<br />

Circuit Emulation) tagits fram på IT-avdelningen. Den heter it-68 och arbetar seriellt via<br />

terminalprogram gentemot en PC. Istället för att processorn sätts i väderstationen,<br />

kopplas en kabel via en adapter till it-68 hårdvara.<br />

Detta förenklar avsevärt utvecklingen, eftersom man då inte behöver bränna ett EPROM<br />

varje gång ny kod skall testas. Programkoden skickas istället via RS-232 till it-68 som i<br />

sin tur är kopplad rätt in i vår väderstation.<br />

It-68 har bland annat följande funktio<strong>ner</strong>.<br />

• Test av minne och I/O enheter<br />

• Minnesarea för exekvering av program<br />

• Brytpunkter samt singelhopp<br />

Vi har utvecklat ett intuitivt menysystem i C där man kan välja vilka data som skall<br />

presenteras på displayen med hjälp av en knappsats.<br />

Som nämnts tidigare har processorn 2 avbrottsnivåer, vilka va använder till tangentbordet<br />

och RTC:n. RTC:n ge<strong>ner</strong>erar ett avbrott varje sekund och ligger således på den högsta<br />

prioritetsnivån. Tangentbordet ligger då på den lägsta. Vi använder autovektoriserade<br />

avbrott vilket betyder att processorn har ett i förväg bestämt register där den skall leta<br />

efter en startadress då ett avbrott sker.<br />

Vi valde att allokera ADC etc. på ganska höga adresser, bit 20-17.<br />

Vilket syns i allokeringstabellen nedan.<br />

Komponent: EPROM SRAM ADC_1 ADC_2 KEY_CTRL RTC DISP_DATA DISP_COM<br />

Adress: 0x00000 0x08000 0x20000 0x40000 0x80000 0xA0000 0xE0004 0xE0000<br />

- -<br />

-<br />

0x07FFF 0x0FFFF<br />

0xA0011<br />

Bortkoppling av it-68<br />

När programkoden till slut var färdigskriven och genomtestad var det dags att slutföra<br />

projektet genom att koppla loss vår hårdvara från it-68. För att ersätta utvecklingsmiljön<br />

måste vårt projekt kompletteras med två saker; processor samt ett eprom med<br />

programkoden inbränt i sig. Detta ledde till en del problem då minnesarean där epromet<br />

ligger inte går att testa med it-68. Detta löstes genom en funktion i it-68, som kopierar<br />

hela epromet till it-68 och sedan exekverar det därifrån. Detta var dock inte heller helt<br />

smärtfritt då kopieringen från epromet till it-68 inte fungerade som det skulle. Som med<br />

de flesta fel som uppstod, så var det fel virat.<br />

Sida 6 av 43


Beskrivning av användargränssnitt<br />

Väderstationens program är uppbyggt kring ett menysystem där man kan navigera mellan<br />

olika menyer som representerar varsin funktion.<br />

Figur 1: Diagram over väderstationens menysystem<br />

I texten nedan beskrivs vidare hur man kan navigera mellan systemets menyer med hjälp<br />

av knappsatsen.<br />

Vid uppstart av systemet behöver klockan ställas för att data skall kunna sparas med<br />

tidsangivelse. ”Ställ klocka” är därför alltid den första menyn som presenteras.<br />

Ställ klocka<br />

(yy) mata in årtal<br />

tryck för att spara , för att mata in igen<br />

mata sedan på liknade sätt in:<br />

Sida 7 av 43


(mm) mata in månad<br />

(dd) mata in dag<br />

(hh) mata in timme<br />

(mm) mata in minut<br />

(ss) mata in sekund<br />

När sekund har matats in och kvitterats via ställs klockan till den angivna tiden och<br />

systemet hoppar till menyn ”Visa temperatur”.<br />

Visa Temperatur<br />

Denna meny visar aktuell temperatur samt dygnsmedeltemperaturen.<br />

Genom att trycka på knappsatsen hopar systemet till menyn ”Ställ larm” Genom<br />

att trycka på hoppar systemet till menyn ”Visa sparad data”<br />

Visa sparad data<br />

Genom att trycka på eller kan man bläddra bland de sparade data värdena<br />

Och en skärm liknande den nedan presenteras.<br />

Sida 8 av 43


Genom att trycka på knappsatsen hoppar systemet till menyn ”Visa Temperatur”.<br />

Genom att trycka på hoppar systemet till menyn ”Visa min och max”<br />

Visa min och max<br />

Max- och min- temperatur presenteras omväxlande för givare a och givare b var femte<br />

sekund.<br />

Genom att trycka på knappsatsen hoppar systemet till menyn ”Visa sparad data”<br />

Genom att trycka på hoppar systemet till menyn ”Ställ alarm”<br />

Ställ alarm<br />

Skriv in den nedre larmgränsen (ll) för givare a genom att trycka på en knapp mellan 0-9<br />

två gånger.<br />

Tryck för att spara detta värde<br />

Sida 9 av 43


Tryck om du vill mata in ett nytt värde<br />

Tryck om du vill spara detta värde negativt, dvs om man knappar in 20 och trycker<br />

kommer talet –20 att sparas. Detta för att enkelt kunna sätta negativa<br />

larmgränser.<br />

Efter att ha knappat in den lägre larmgränsen för givare a får du knappa in den höga<br />

larmgränsen (hh) för givare a, följt av samma procedur för givare b.<br />

Efter att alla larmgränser är inknappade återgår systemet till menyn ”Visa temperatur”<br />

6.Alarm<br />

Om någon av larmgränserna passeras kommer följande skärm att presenteras:<br />

Displayen visar vilken givare och larmgräns som passerats.<br />

Genom att trycka på kommer larmgränserna att tas bort.<br />

Genom att trycka på återgår systemet till att visa aktuell temperatur och<br />

larmgränserna sparas.<br />

Observera att om man trycker på och temperaturen fortfarande är över eller under en<br />

larmgräns kommer systemet omedelbart att larma igen och man hamnar återigen vid<br />

”Alarm” menyn<br />

Sida 10 av 43


Resultat<br />

Konstruktionen uppfyller följande krav:<br />

Två temperaturer kan presenteras kontinuerligt i hela grader celcius<br />

Max och min samt dygnsmedeltemperatur kan presenteras<br />

Mätinsamling med tidsangivelse kan presenteras<br />

Två larmgränser kan programmeras in per givare<br />

Mätområde svenska medelklimatet<br />

Enligt kravspecifikationen skulle mätinsamling med tidsangivelse (mån,dag,tim,min)<br />

kunna presenteras. I skrivande stund uppfyller konstruktionen dock inte detta, utan<br />

presenterar endast sparade data med tidsangivelse i form av (dag,tim,min). Detta främst<br />

på grund av att displayen är för liten för att presentera all data på en skärm och vi inte har<br />

hunnit konstruera en alternativ lösning. I skrivande stund sparas således inte heller<br />

månadsangivelsen för respektive data.<br />

Förutom ovanstående uppfyller konstruktionen kravspecifikationen.<br />

Sida 11 av 43


Diskussion<br />

Under kursens gång har vi stött på en rad problem, vilka I och för sig ofta har varit på<br />

grund av våra egna tillkortakommanden. Våran handledare, Bertil, har dock alltid varit<br />

tillgänglig och har kommit med tips, råd och lösningar som har gjort att vi alltid har<br />

kunnat fortskrida.<br />

Med största sannolikhet hade vi inte kunnat genomföra projektet på så kort tid om det inte<br />

vore för hjälpen.<br />

Ett par mindre problem kvarstår i konstruktionen:<br />

Genom att koppla in en 2.5V referens på AD omvandlarnas V ref / 2 ingång försökte vi öka<br />

upplösningen från 20mV till 10mV. Detta innebär att en inspänning på 2.5V borde<br />

ge<strong>ner</strong>era ett max värde (0xFF) på AD omvandlarens datautgång. Så är dock inte fallet,<br />

utan en spänning på 2.9V som ge<strong>ner</strong>eras vid rumstemperatur ger runt 0x89 på<br />

datautgången. I skrivande stund har vi inte hunnit utreda varför.<br />

Vi har inte kunnat testa konstruktionen utan att it68 varit inkopplad, då vi får ett<br />

felmeddelande när vi försöker kopiera programmet från EPROM till minnet på it68.<br />

Detta innebär att vi inte heller har kunnat testa systemet med en processor och vår<br />

oscillator till denna.<br />

Knappsatsen ”studsar” även oönskat mycket, vilket vi försökte lösa genom att koppla in<br />

en kondensator på knappsatsavkodaren. Det gav en viss förbättring, men studsningar<br />

uppträder fortfarande lite för ofta för att vi skall vara nöjda.<br />

Eftersom våra kunskaper om konstruktion innan kursen var väldigt begränsade är vi<br />

mycket nöjda med vårat resultat och vad vi har lärt oss. Kursen har varit väldigt givande<br />

och vi har fått många praktiska kunskaper om konstruktion av digitala system, med<br />

betoning på just praktiska kunskaper, som annars är väldigt frånvarande i utbildningen.<br />

Sida 12 av 43


Appendix A: Programkod<br />

/***********************************************************************<br />

**<br />

test.c<br />

------<br />

Detta ar huvudprogrammet som ar skrivet i ANSI C. Exekveringen av<br />

hela<br />

programpaketet borjar i pmain.68k (lage __main).<br />

exp4() anropas fran assemblyprogrammet exp4.68k vid avbrott.<br />

_avben() anropar avben.68k vilket tillater avbrott fran PI/T.<br />

************************************************************************<br />

****/<br />

#include "variables.h"<br />

#include "display.c"<br />

#include "rtc.c"<br />

#include "int5.c"<br />

unsigned short int dispVal;<br />

unsigned short int *whichData,*alarm;<br />

main()<br />

{<br />

rtc = (unsigned short int *) 0x000a0000; /*Timer Control register*/<br />

keyb = (unsigned short int *) 0x00080000; /*Keyboard Control register*/<br />

disp = (unsigned short int *) 0x000e0000; /*Display base register*/<br />

ad1 = (unsigned short int *) 0x00020000; /*AD Converter 1 register*/<br />

ad2 = (unsigned short int *) 0x00040000; /*AD Converter 2 register*/<br />

init(); /* kör init() sätter upp<br />

allting */<br />

_avben(); /* tillåt avbrott */<br />

}<br />

dispWelcome(); /*skriv ut "welcome"*/<br />

setDispCursor(0,1);<br />

dispPressKey();<br />

while(1) {<br />

}<br />

void init(void)<br />

{<br />

tid=50; /* tidskonstant */<br />

status=2; /* Startläge */<br />

subStatus=0;<br />

nbrRep=0;<br />

Sida 13 av 43


}<br />

savedDataCtr=0;<br />

alarm1Low=-50;<br />

alarm2Low=-50;<br />

alarm1High=50;<br />

alarm2High=50;<br />

Max_ad1=0;<br />

Max_ad2=0;<br />

Min_ad1=1000;<br />

Min_ad2=1000;<br />

mean_array_pek = 0;<br />

data_array_pek = 0;<br />

mean_all_Ctr = 0;<br />

/*Stoppa RTC */<br />

*(rtc + 0x11)=0x00;<br />

wait(tid);<br />

*(rtc + 0x10)=0x00;<br />

wait(tid);<br />

/*Initsiera Display */<br />

*disp=0x30;<br />

wait(tid);<br />

*disp=0x30;<br />

wait(tid);<br />

*disp=0x30;<br />

wait(tid);<br />

*disp=0x01;<br />

wait(tid);<br />

*disp=0x3c;<br />

wait(tid);<br />

*disp=0x0f;<br />

wait(tid);<br />

*disp=0x06;<br />

void mainProg(void){<br />

if (status==1) /* power on, sätt klocka, etc */<br />

{<br />

setClock();<br />

}<br />

else if (status==2) /* klockan är ställd, visa nu temperatur*/<br />

{<br />

dispTemp();<br />

}<br />

else if (status==3) /* ställ in larmgränser */<br />

{<br />

setAlarm();<br />

}<br />

else if (status==4) /* visa sparade mätdata */<br />

{<br />

showSavedData();<br />

Sida 14 av 43


}<br />

else if (status==5)<br />

{<br />

dispMinMax();<br />

}<br />

else if (status==6)<br />

{<br />

dispTrigAlarm(adAlarm);<br />

}<br />

return;<br />

}<br />

void wait(int time) {<br />

int i,j;<br />

for(i = 0; i < time; i++) {<br />

for(j = 0; j < 100; j++) ;<br />

}<br />

}<br />

void exp2(void) /* avbrottsprogram Keyb*/<br />

{<br />

wait(tid);<br />

key = *keyb;<br />

mainProg();<br />

return;<br />

}<br />

void exp5(void) /* avbrottsprogram RTC*/<br />

{<br />

kvittera = *(rtc + 0x10); /*Kvittera avbrottet*/<br />

/*Följande kod måste ta mindre än 1 sek att utföra, ty annars<br />

kommer nytt avbrott mitt i. */<br />

dispMinMax_Cnt=(dispMinMax_Cnt+1)%10; /*Används för att växla<br />

mellan ad1 & ad2 i dispMinMax */<br />

UpdClock(); /*Uppdatera klockvariablerna*/<br />

UpdTemp(); /*Uppdatera aktuella temperaturen */<br />

UpdMean(); /*Uppdatera medelvärdet */<br />

UpdMinMax(); /*Uppdatera Min och Max */<br />

}<br />

if(status==2 && subStatus==1){<br />

intDispTemp();<br />

alarmChk();<br />

}<br />

else if (status==5 && subStatus>=1){<br />

}<br />

return;<br />

void setClock(void){<br />

if(dispMinMax_Cnt < 6){<br />

intDispMinMax(Min_ad1,Max_ad1,1);<br />

}<br />

else{<br />

intDispMinMax(Min_ad2,Max_ad2,2);<br />

}<br />

Sida 15 av 43


int tmp;<br />

switch(subStatus){<br />

case 0: /* sätt år*/<br />

dispVal=0x79; /*"y"*/<br />

whichData = &year;<br />

break;<br />

case 1: /* sätt månad*/<br />

dispVal=0x6d; /*"m"*/<br />

whichData = &month;<br />

break;<br />

case 2: /* sätt dag*/<br />

dispVal=0x64; /*"d"*/<br />

whichData = &day;<br />

break;<br />

case 3: /* sätt timme*/<br />

dispVal=0x68; /*"h"*/<br />

whichData = &hour;<br />

break;<br />

case 4: /* sätt minut*/<br />

dispVal=0x6d; /*"m"*/<br />

whichData = &minute;<br />

break;<br />

case 5: /* sätt sekund*/<br />

dispVal=0x73; /*"s"*/<br />

whichData = &second;<br />

break;<br />

default:<br />

break;<br />

}<br />

switch(nbrRep){ /* vid vilken repetition kommer vi<br />

in i subrutinen */<br />

case 0:<br />

clearDisp();<br />

dispEnter();<br />

writeToDisp(0x20); /* blankspace */<br />

writeToDisp(0x28); /* (*/<br />

writeToDisp(dispVal); /* bokstav beroende på<br />

vad vi skall ställa, även första inmatningfältet*/<br />

writeToDisp(dispVal); /*bokstav beroende på<br />

vad vi skall ställa*/<br />

writeToDisp(0x29); /*)*/<br />

setDispCursor(7,0); /* flytta markör till<br />

platsen för första inmatningfältet på displayen*/<br />

case 1:<br />

nbrRep+=1;<br />

break;<br />

dispKey(key);<br />

*whichData=10*getKey(); /*10tal gånger värdet (0-f)h<br />

som retur<strong>ner</strong>as av getKey() */<br />

nbrRep+=1;<br />

Sida 16 av 43


variabeln*/<br />

break;<br />

case 2:<br />

dispKey(key);<br />

*whichData+=getKey(); /* entals året adderas till<br />

setDispCursor(0,1);<br />

dispYN(); /*skriv ut y/n*/<br />

nbrRep+=1;<br />

break;<br />

case 3:<br />

if(key==0xFA) { /*key = "Y" */<br />

nbrRep=0;<br />

if(subStatus==0){<br />

RtcYEAR_RAM(*whichData);<br />

subStatus+=1;<br />

setClock();<br />

break;<br />

}<br />

else if (subStatus==1)<br />

{<br />

RtcMONTH_RAM(*whichData);<br />

subStatus+=1;<br />

setClock();<br />

break;<br />

}<br />

else if (subStatus==2)<br />

{<br />

RtcDATE_RAM(*whichData);<br />

subStatus+=1;<br />

setClock();<br />

break;<br />

}<br />

else if (subStatus==3)<br />

{<br />

RtcHOUR_RAM(*whichData);<br />

subStatus+=1;<br />

setClock();<br />

break;<br />

}<br />

else if (subStatus==4)<br />

{<br />

RtcMINUTE_RAM(*whichData);<br />

subStatus+=1;<br />

setClock();<br />

break;<br />

}<br />

else if (subStatus==5)<br />

{<br />

subStatus=0;<br />

RtcSECOND_RAM(*whichData);<br />

/*Starta RTC*/<br />

tmp= *rtc;<br />

Sida 17 av 43


klockan! */<br />

igen*/<br />

}<br />

}<br />

}<br />

else{<br />

}<br />

*(rtc + 0x11)=0x1c;<br />

wait(tid);<br />

*(rtc + 0x10)=0x08;<br />

wait(tid);<br />

status=2;<br />

dispTemp();<br />

break;<br />

/* kör även rutinen som skirver till<br />

subStatus+=1;<br />

setClock();<br />

break;<br />

}<br />

else if (key==0xFB) /*key = "n"*/<br />

{<br />

nbrRep=0; /*nästa gång skall vi göra om allt<br />

}<br />

else<br />

break;<br />

void setAlarm(void){ /*status == 3*/<br />

int tempChar;<br />

int adChar;<br />

switch(nbrRep){<br />

nbrRep=0; /* något är fel, vi gör om */<br />

break;<br />

case 0:<br />

alarm = &alarm1Low;<br />

adChar=0x61;<br />

tempChar=0x6C;<br />

break;<br />

case 1:<br />

alarm= &alarm1High;<br />

adChar=0x61;<br />

tempChar=0x68;<br />

break;<br />

case 3:<br />

alarm = &alarm2Low;<br />

adChar=0x62;<br />

tempChar=0x6C;<br />

break;<br />

case 4:<br />

alarm = &alarm2High;<br />

Sida 18 av 43


}<br />

switch(subStatus){<br />

case 0:<br />

adChar=0x62;<br />

tempChar=0x68;<br />

break;<br />

clearDisp();<br />

dispEnter();<br />

writeToDisp(0x20); /* blankspace */<br />

writeToDisp(adChar);<br />

writeToDisp(0x20); /* blankspace */<br />

writeToDisp(0x28); /* (*/<br />

writeToDisp(tempChar); /* "n" */<br />

writeToDisp(tempChar); /* "n" */<br />

writeToDisp(0x29); /*)*/<br />

setDispCursor(9,0); /* flytta markör till<br />

platsen för första inmatningfältet på displayen*/<br />

subStatus+=1;<br />

break;<br />

case 1:<br />

dispKey(key);<br />

*alarm=10*getKey(); /*10tal gånger värdet (0-f)h<br />

som retur<strong>ner</strong>as av getKey() */<br />

subStatus+=1;<br />

break;<br />

case 2:<br />

dispKey(key);<br />

*alarm+=getKey(); /* entals värder adderas till<br />

variabeln*/<br />

setDispCursor(0,1);<br />

dispYNMinus(); /*skriv ut y/n*/<br />

subStatus+=1;<br />

break;<br />

case 3:<br />

if(key==0xFA) { /*key = "Y" */<br />

subStatus=0;<br />

if(nbrRep


igen*/<br />

larmgräns!) */<br />

}<br />

}<br />

}<br />

else if (key==0xFB) /*key = "n"*/<br />

{<br />

subStatus=0;<br />

nbrRep=0; /*nästa gång skall vi göra om allt<br />

setAlarm();<br />

break;<br />

}<br />

else if (key==0xFD){ /*key = "


writeToDisp(0x20); /* blank*/<br />

writeToDisp(0x64); /* d*/<br />

writeToDisp(0x6f); /* o" */<br />

writeToDisp(0x77); /* w */<br />

writeToDisp(0x6e); /* n */<br />

subStatus+=1;<br />

break;<br />

case 1:<br />

if(key==0xFD) /* key = "" = move<br />

right dispMinMax */<br />

{<br />

subStatus=0;<br />

nbrRep=0;<br />

status=5;<br />

dispMinMax();<br />

break;<br />

}<br />

else if (key==0xFE) /* pil upp*/<br />

{<br />

dispSavedData(savedDataCtr%60);<br />

savedDataCtr+=1;<br />

break;<br />

}<br />

else if (key==0xFF) /*pil ned*/<br />

{<br />

dispSavedData(savedDataCtr%60);<br />

savedDataCtr-=1;<br />

break;<br />

}<br />

else {<br />

break;<br />

}<br />

}<br />

} /*end switch*/<br />

void forceClock(void){<br />

int tmp;<br />

year=04;<br />

month=11;<br />

day=28;<br />

hour=14;<br />

minute=49;<br />

second=00;<br />

Sida 21 av 43


}<br />

RtcYEAR_RAM(year);<br />

RtcMONTH_RAM(month);<br />

RtcDATE_RAM(day);<br />

RtcHOUR_RAM(hour);<br />

RtcMINUTE_RAM(minute);<br />

RtcSECOND_RAM(second);<br />

/*Starta RTC*/<br />

tmp= *rtc;<br />

*(rtc + 0x11)=0x1c;<br />

wait(tid);<br />

*(rtc + 0x10)=0x08;<br />

wait(tid);<br />

return;<br />

int getKey(void){<br />

if (key==0xF1) /* key = 1x1 */<br />

return 0x00;<br />

else if (key==0xF0) /* key = 1x2 */<br />

return 0x01;<br />

else if (key==0xF2) /* key = 1x3 */<br />

return 0x02;<br />

else if (key==0xF3) /* key = 1x4 */<br />

return 0x03;<br />

else if (key==0xF5) /* key = 2x1 */<br />

return 0x04;<br />

else if (key==0xF4) /* key = 2x2 */<br />

return 0x05;<br />

else if (key==0xF6) /* key = 2x3 */<br />

return 0x06;<br />

else if (key==0xF7) /* key = 2x4 */<br />

return 0x07;<br />

else if (key==0xF9) /* key = 3x1 */<br />

return 0x08;<br />

else if (key==0xF8) /* key = 3x2 */<br />

return 0x09;<br />

else if (key==0xFA) /* key = 3x3 */<br />

return 0x0a;<br />

else if (key==0xFB) /* key = 3x4 */<br />

return 0x0b;<br />

else if (key==0xFD) /* key = 4x1 */<br />

return 0x0c;<br />

else if (key==0xFC) /* key = 4x2 */<br />

return 0x0d;<br />

else if (key==0xFE) /* key = 4x3 */<br />

return 0x0e;<br />

else if (key==0xFF) /* key = 4x4 */<br />

return 0x0f;<br />

else return 0xff;<br />

}<br />

/***********************************************************************<br />

**<br />

display.c<br />

Sida 22 av 43


------<br />

kod som skriver ut en massa saker på displayen, typiskt en massa<br />

konstanta<br />

värden.<br />

************************************************************************<br />

****/<br />

#include "variables.h"<br />

void writeToDisp(int writeChar){<br />

int time=1;<br />

wait(time);<br />

*(disp + 0x04)=writeChar;<br />

return;<br />

}<br />

void dispTrigAlarm(int whichAlarm){<br />

int whichAD;<br />

int whichTemp;<br />

switch (whichAlarm)<br />

{<br />

case 0:<br />

whichAD=0x61; /*a*/<br />

whichTemp=temp_ad1;<br />

break;<br />

case 1:<br />

whichAD=0x61; /*a*/<br />

whichTemp=temp_ad1;<br />

break;<br />

case 2:<br />

whichAD=0x62; /*b*/<br />

whichTemp=temp_ad2;<br />

break;<br />

case 3:<br />

whichAD=0x62; /*b*/<br />

whichTemp=temp_ad2;<br />

break;<br />

}<br />

switch(subStatus){<br />

case 0:<br />

clearDisp();<br />

setDispCursor(0,0);<br />

writeToDisp(0x54); /* "T" */<br />

writeToDisp(0x65); /* "e" */<br />

writeToDisp(0x6d); /* "m" */<br />

writeToDisp(0x70); /* "p" */<br />

writeToDisp(0x20); /* "blank" */<br />

writeToDisp(whichAD); /* "vilken AD" */<br />

writeToDisp(0x20); /* "blank" */<br />

printTemp(whichTemp);<br />

setDispCursor(1,1);<br />

Sida 23 av 43


dispReset();<br />

writeToDisp(0x20); /*blank*/<br />

dispYN();<br />

subStatus+=1;<br />

break;<br />

case 1:<br />

if(key==0xFA) { /*key = "Y" */<br />

alarm1Low=0;<br />

alarm2Low=0;<br />

alarm1High=50;<br />

alarm2High=50;<br />

subStatus=0;<br />

nbrRep=0;<br />

status=2;<br />

dispTemp();<br />

break;<br />

}<br />

else if (key==0xFB) { /*key = "n"*/<br />

}<br />

else{<br />

break;<br />

}<br />

subStatus=0;<br />

nbrRep=0;<br />

status=2;<br />

dispTemp();<br />

break;<br />

}<br />

}<br />

void dispSavedData(int time){<br />

clearDisp();<br />

dispArrows();<br />

nbrRep=0; /* något är fel, vi gör om */<br />

setDispCursor(1,0);<br />

writeVal(savedDataCtr%60); /*vilken saved data position*/<br />

writeToDisp(0x61); /* "a " */<br />

writeToDisp(0x3A); /* ":" */<br />

printTemp(ad1_data[time].temperatur);<br />

writeToDisp(0x20); /*blanksteg*/<br />

/*writeToDisp(ad2_data[time].temperatur); */<br />

printTemp(ad1_data[time].dag);<br />

writeToDisp(0x20); /*blanksteg*/<br />

printTemp(ad1_data[time].timme);<br />

writeToDisp(0x3A); /* ":" */<br />

printTemp(ad1_data[time].minut);<br />

setDispCursor(1,1);<br />

Sida 24 av 43


eturn;<br />

}<br />

writeVal(savedDataCtr%60); /*vilken saved data position*/<br />

writeToDisp(0x62); /* "b " */<br />

writeToDisp(0x3A); /* ":" */<br />

printTemp(ad2_data[time].temperatur);<br />

writeToDisp(0x20); /*blanksteg*/<br />

/*writeToDisp(ad2_data[time].temperatur);*/<br />

printTemp(ad2_data[time].dag);<br />

writeToDisp(0x20); /*blanksteg*/<br />

printTemp(ad2_data[time].timme);<br />

writeToDisp(0x3A); /* ":" */<br />

printTemp(ad2_data[time].minut);<br />

void setDispCursor(int x,int y){<br />

}<br />

int t2=2;<br />

int t=1;<br />

int i=0;<br />

int j=0;<br />

*disp=0x0c; /* set cursor display off*/<br />

wait(t2);<br />

*disp=0x02; /*return cursor to home */<br />

wait(t2);<br />

switch(y){<br />

case 0:<br />

for(i=0;i


}<br />

printTemp(temp_ad2); /* Temp för AD2*/<br />

if (mean_all_Ctr != 0)<br />

{<br />

setDispCursor(3,1);<br />

printTemp(dygnsmedel_ad1); /*Dygnsmedel AD1*/<br />

setDispCursor(11,1);<br />

printTemp(dygnsmedel_ad2); /*Dygnsmedel AD2*/<br />

}<br />

return;<br />

void intDispMinMax(int min,int max,int ad){<br />

if(ad==1)<br />

{<br />

}<br />

if(ad==2)<br />

{<br />

}<br />

}<br />

void dispTemp(void){<br />

switch(subStatus){<br />

case 0:<br />

setDispCursor(0,0);<br />

writeToDisp(0x61); /* "a " */<br />

setDispCursor(0,8);<br />

writeToDisp(0x61); /* "a " */<br />

setDispCursor(3,0);<br />

printTemp(max); /* MAX för AD1*/<br />

setDispCursor(11,0);<br />

printTemp(min); /* MIN för AD1*/<br />

setDispCursor(0,0);<br />

writeToDisp(0x62); /* "b " */<br />

setDispCursor(0,8);<br />

writeToDisp(0x62); /* "b " */<br />

setDispCursor(3,0);<br />

printTemp(max); /* MAX för AD1*/<br />

setDispCursor(11,0);<br />

printTemp(min); /* MIN för AD1*/<br />

clearDisp();<br />

setDispCursor(0,0);<br />

writeToDisp(0x61); /* "a " */<br />

writeToDisp(0x3A); /* ":" */<br />

writeToDisp(0x20); /* skriv blanksteg*/<br />

writeToDisp(0x20); /* skriv blanksteg*/<br />

writeToDisp(0x20); /* skriv blanksteg*/<br />

writeToDisp(0xDF); /* " grader tecknet" */<br />

writeToDisp(0x43); /* " C" */<br />

Sida 26 av 43


writeToDisp(0x20); /* skriv blanksteg*/<br />

writeToDisp(0x62); /* "b " */<br />

writeToDisp(0x3A); /* ":" */<br />

writeToDisp(0x20); /* skriv blanksteg*/<br />

writeToDisp(0x20); /* skriv blanksteg*/<br />

writeToDisp(0x20); /* skriv blanksteg*/<br />

writeToDisp(0xDF); /* " grader tecknet" */<br />

writeToDisp(0x43); /* " C" */<br />

setDispCursor(3,0);<br />

printTemp(temp_ad1); /* Temp för AD1*/<br />

setDispCursor(11,0);<br />

printTemp(temp_ad2); /* Temp för AD2*/<br />

dispArrows();<br />

subStatus+=1;<br />

break;<br />

case 1:<br />

if(key==0xFD) /* key = "" = move<br />

}<br />

}<br />

setDispCursor(3,0);<br />

printTemp(temp_ad1); /* Temp för AD1*/<br />

setDispCursor(11,0);<br />

printTemp(temp_ad2); /* Temp för AD2*/<br />

break;<br />

}<br />

void dispArrows(void){<br />

setDispCursor(0,1);<br />

Sida 27 av 43


writeToDisp(0x7f); /* skriv vänster pil i vänster<br />

hörn*/<br />

setDispCursor(15,1);<br />

writeToDisp(0x7e); /* skriv häger pil i höger hörn*/<br />

}<br />

void clearDisp(void){<br />

wait(tid);<br />

*disp=0x01;<br />

wait(tid);<br />

return;<br />

}<br />

void dispKey(int key){<br />

if (key==0xF1) /* key = 1x1 */<br />

writeToDisp(0x30);<br />

else if (key==0xF0) /* key = 1x2 */<br />

writeToDisp(0x31);<br />

else if (key==0xF2) /* key = 1x3 */<br />

writeToDisp(0x32);<br />

else if (key==0xF3) /* key = 1x4 */<br />

writeToDisp(0x33);<br />

else if (key==0xF5) /* key = 2x1 */<br />

writeToDisp(0x34);<br />

else if (key==0xF4) /* key = 2x2 */<br />

writeToDisp(0x35);<br />

else if (key==0xF6) /* key = 2x3 */<br />

writeToDisp(0x36);<br />

else if (key==0xF7) /* key = 2x4 */<br />

writeToDisp(0x37);<br />

else if (key==0xF9) /* key = 3x1 */<br />

writeToDisp(0x38);<br />

else if (key==0xF8) /* key = 3x2 */<br />

writeToDisp(0x39);<br />

else if (key==0xFA) /* key = 3x3 */<br />

writeToDisp(0x41);<br />

else if (key==0xFB) /* key = 3x4 */<br />

writeToDisp(0x42);<br />

else if (key==0xFD) /* key = 4x1 */<br />

writeToDisp(0x43);<br />

else if (key==0xFC) /* key = 4x2 */<br />

writeToDisp(0x44);<br />

else if (key==0xFE) /* key = 4x3 */<br />

writeToDisp(0x45);<br />

else if (key==0xFF) /* key = 4x4 */<br />

writeToDisp(0x46);<br />

return;<br />

}<br />

void dispWelcome(void){<br />

wait(tid);<br />

writeToDisp(0x57); /* "W" */<br />

wait(tid);<br />

writeToDisp(0x65); /* "e" */<br />

Sida 28 av 43


}<br />

wait(tid);<br />

writeToDisp(0x6c); /* "l" */<br />

wait(tid);<br />

writeToDisp(0x63); /* "c" */<br />

wait(tid);<br />

writeToDisp(0x6f); /* "o" */<br />

wait(tid);<br />

writeToDisp(0x6d); /* "m" */<br />

wait(tid);<br />

writeToDisp(0x65); /* "e" */<br />

wait(tid);<br />

return;<br />

void dispPressKey(void){<br />

wait(tid);<br />

writeToDisp(0x50); /* "P" */<br />

wait(tid);<br />

writeToDisp(0x72); /* "r" */<br />

wait(tid);<br />

writeToDisp(0x65); /* "e" */<br />

wait(tid);<br />

writeToDisp(0x73); /* "s" */<br />

wait(tid);<br />

writeToDisp(0x73); /* "s" */<br />

wait(tid);<br />

writeToDisp(0x20); /* "blank" */<br />

wait(tid);<br />

writeToDisp(0x61); /* "a" */<br />

wait(tid);<br />

writeToDisp(0x20); /* "blank" */<br />

wait(tid);<br />

writeToDisp(0x6b); /* "k" */<br />

wait(tid);<br />

writeToDisp(0x65); /* "e" */<br />

wait(tid);<br />

writeToDisp(0x79); /* "y" */<br />

wait(tid);<br />

return;<br />

}<br />

void dispEnter(void){<br />

writeToDisp(0x45); /* "E" */<br />

writeToDisp(0x6e); /* "n" */<br />

writeToDisp(0x74); /* "t" */<br />

writeToDisp(0x65); /* "e" */<br />

writeToDisp(0x72); /* "r" */<br />

}<br />

void dispYN(void){<br />

writeToDisp(0x28); /* "(" */<br />

writeToDisp(0x79); /* "y" */<br />

writeToDisp(0x2F); /* " /" */<br />

writeToDisp(0x6e); /* "n" */<br />

writeToDisp(0x29); /* ")" */<br />

Sida 29 av 43


}<br />

void dispYNMinus(void){<br />

writeToDisp(0x28); /* "(" */<br />

writeToDisp(0x79); /* "y" */<br />

writeToDisp(0x2F); /* " /" */<br />

writeToDisp(0x6e); /* "n" */<br />

writeToDisp(0x2F); /* " /" */<br />

writeToDisp(0x7F); /* "


Max_ad1 = temp_ad1;<br />

}<br />

/*Kolla Max_ad2*/<br />

if(temp_ad2 >= Max_ad2)<br />

{<br />

Max_ad2 = temp_ad2;<br />

}<br />

/*Kolla Min_ad1*/<br />

if(temp_ad1


*Skriv ut texten Min/Max för AD2*/<br />

clearDisp();<br />

setDispCursor(0,0);<br />

writeToDisp(0x62); /* "b " */<br />

writeToDisp(0x3A); /* ":" */<br />

writeToDisp(0x20); /* skriv blanksteg*/<br />

writeToDisp(0x20); /* skriv blanksteg*/<br />

writeToDisp(0x20); /* skriv blanksteg*/<br />

writeToDisp(0xDF); /* " grader tecknet" */<br />

writeToDisp(0x43); /* " C" */<br />

writeToDisp(0x20); /* skriv blanksteg*/<br />

}<br />

break;<br />

writeToDisp(0x62); /* "b " */<br />

writeToDisp(0x3A); /* ":" */<br />

writeToDisp(0x20); /* skriv blanksteg*/<br />

writeToDisp(0x20); /* skriv blanksteg*/<br />

writeToDisp(0x20); /* skriv blanksteg*/<br />

writeToDisp(0xDF); /* " grader tecknet" */<br />

writeToDisp(0x43); /* " C" */<br />

dispArrows();<br />

subStatus=2;<br />

case 1:<br />

if(key==0xFD) /* key = "" = move<br />

{<br />

subStatus=0;<br />

nbrRep=0;<br />

status=3;<br />

setAlarm();<br />

break;<br />

}<br />

else{<br />

setDispCursor(3,0);<br />

printTemp(Max_ad1); /* MAX för AD1*/<br />

setDispCursor(11,0);<br />

printTemp(Min_ad1); /* MIN för AD1*/<br />

subStatus=0;<br />

break;<br />

Sida 32 av 43


}<br />

case 2:<br />

if(key==0xFD) /* key = "" = move<br />

right setAlarm */<br />

{<br />

subStatus=0;<br />

nbrRep=0;<br />

status=3;<br />

setAlarm();<br />

break;<br />

}<br />

else{<br />

}<br />

}<br />

setDispCursor(3,0);<br />

printTemp(Max_ad2); /* MAX för AD2*/<br />

setDispCursor(11,0);<br />

printTemp(Min_ad2); /* MIN för AD2*/<br />

subStatus=0;<br />

break;<br />

}<br />

Sida 33 av 43


*********************************************************************<br />

rtc.c<br />

------<br />

Programmering av RTC.<br />

**********************************************************************/<br />

#include "variables.h"<br />

/*SKRIVER NUMERA TILL COUNT REGISTRENA*/<br />

/*Skriv till År*/<br />

void RtcYEAR_RAM(int YEAR)<br />

{<br />

*(rtc + 0x06)=YEAR;<br />

wait(tid);<br />

}<br />

/*Skriv till Månad*/<br />

void RtcMONTH_RAM(int MONTH)<br />

{<br />

*(rtc + 0x04)=MONTH;<br />

wait(tid);<br />

}<br />

/*Skriv till Datum*/<br />

void RtcDATE_RAM(int DATE)<br />

{<br />

*(rtc + 0x05)=DATE;<br />

wait(tid);<br />

}<br />

/*Skriv till Timmar*/<br />

void RtcHOUR_RAM(int HOUR)<br />

{<br />

*(rtc + 0x01)=HOUR;<br />

wait(tid);<br />

}<br />

/*Skriv till Minuter*/<br />

void RtcMINUTE_RAM(int MINUTE)<br />

{<br />

*(rtc + 0x02)=MINUTE;<br />

wait(tid);<br />

}<br />

/*Skriv till Sekunder*/<br />

void RtcSECOND_RAM(int SECOND)<br />

{<br />

*(rtc + 0x03)=SECOND;<br />

wait(tid);<br />

}<br />

Sida 34 av 43


*********************************************************************<br />

int5.c<br />

------<br />

Vad som skall göras vid ett interupt från klockan.<br />

*********************************************************************/<br />

/*<br />

VAD SOM SKALL GÖRAS:<br />

- Updatera klockan...<br />

UpdClock();<br />

- Mäta båda tempgivarna, lagra deras värde i varsin array:<br />

int mean_arr1[60]<br />

int mean_arr2[60]<br />

Om arrayen är full, ta medelvärdet av allihoppa och spara undan<br />

det med tidsangivelse.<br />

- Kolla om temperaturen ligger under/över larmgränserna... i så<br />

fall, VARNA!<br />

*/<br />

#include "variables.h"<br />

void UpdClock()<br />

{<br />

/*<br />

Läs först 1/100 sekund registret: temp=*(rtc)<br />

Detta för att latcha ut aktuell tid i counter-registrena.<br />

*/<br />

kvittera=*(rtc);<br />

wait(tid);<br />

/*<br />

Uppdatera klockvariablerna... (year,month,day,hour,minute,second)<br />

*/<br />

year = *(rtc + 0x06);<br />

wait(tid);<br />

month = *(rtc + 0x04);<br />

wait(tid);<br />

day = *(rtc + 0x05);<br />

wait(tid);<br />

hour = *(rtc + 0x01);<br />

wait(tid);<br />

minute = *(rtc + 0x02);<br />

wait(tid);<br />

second = *(rtc + 0x03);<br />

wait(tid);<br />

} /*UpdClock End*/<br />

void UpdTemp()<br />

{<br />

temp_ad1=(*(ad1)-132);<br />

Sida 35 av 43


temp_ad2=(*(ad2)-133);<br />

}/*UpdTemp End*/<br />

void UpdMean()<br />

{<br />

mean_arr1[mean_array_pek]=temp_ad1;<br />

mean_arr2[mean_array_pek]=temp_ad2;<br />

if (mean_array_pek==59) /* Har det gått en minut? */<br />

{<br />

/*Roppar på MeanCount för att räkna ut medlet.*/<br />

mean_ad1=MeanCount(mean_arr1);<br />

mean_ad2=MeanCount(mean_arr2);<br />

/*Spara undan minutmedlet i en array */<br />

mean_all_arr_ad1[mean_all_Ctr]=mean_ad1;<br />

mean_all_arr_ad2[mean_all_Ctr]=mean_ad2;<br />

/*Ta medel på alla minutmedel*/<br />

dygnsmedel_ad1 = mean_all_arr_ad1[mean_all_Ctr]; /*Test*/<br />

dygnsmedel_ad2 = mean_all_arr_ad2[mean_all_Ctr];<br />

/*Spara undan mean_ad1 med tidsangivelse... */<br />

ad1_data[data_array_pek].temperatur = mean_ad1;<br />

/*Måste fixa till temperaturen på något sätt... hexadecimalt nu.*/<br />

ad1_data[data_array_pek].dag = day;<br />

ad1_data[data_array_pek].timme = hour;<br />

ad1_data[data_array_pek].minut = minute;<br />

/*Spara undan mean_ad1 med tidsangivelse... */<br />

ad2_data[data_array_pek].temperatur = mean_ad2;<br />

/*Måste fixa till temperaturen på något sätt... hexadecimalt nu.*/<br />

ad2_data[data_array_pek].dag = day;<br />

ad2_data[data_array_pek].timme = hour;<br />

ad2_data[data_array_pek].minut = minute;<br />

mean_all_Ctr = (mean_all_Ctr+1)%1439; /*Räknaren för totala<br />

dygnsmedlet, håller reda på minutplatsen.*/<br />

data_array_pek = (data_array_pek+1)%60; /*Uppdaterar arrayen för<br />

nästa värde, (modulus 60, hänger samman med antalet minuter...).*/<br />

}<br />

mean_array_pek = (mean_array_pek+1)%60; /*Uppdaterar arrayen för nästa<br />

värde, (modulus 60).*/<br />

}/*UpdMean End*/<br />

void alarmChk(void)<br />

{<br />

if(temp_ad1


}<br />

else if(temp_ad1>=alarm1High)<br />

{<br />

status=6;<br />

subStatus=0;<br />

nbrRep=0;<br />

adAlarm=1;<br />

dispTrigAlarm(adAlarm);<br />

/*<br />

clearDisp();<br />

writeToDisp(0x65); /* "e" */<br />

}<br />

else if(temp_ad2=alarm2High)<br />

{<br />

}<br />

else{<br />

}<br />

status=6;<br />

subStatus=0;<br />

nbrRep=0;<br />

adAlarm=3;<br />

dispTrigAlarm(adAlarm);<br />

/*<br />

clearDisp();<br />

writeToDisp(0x70); /* "p" */<br />

return;<br />

}<br />

/*AlarmChk End*/<br />

/*Räkna ut medel och retur<strong>ner</strong>a en int... */<br />

int MeanCount(int array[])<br />

{<br />

int i = 0;<br />

int fisk=0;<br />

int hund=0;<br />

while(i < sizeof(mean_array_pek))<br />

Sida 37 av 43


{<br />

fisk=fisk+array[i];<br />

i++;<br />

}<br />

if(mean_array_pek > 0)<br />

{<br />

hund=fisk/sizeof(mean_array_pek);<br />

return hund;<br />

}<br />

else<br />

{<br />

return 0;<br />

}<br />

} /*MeanCount End*/<br />

Sida 38 av 43


*********************************************************************<br />

variables.h<br />

-----------<br />

**********************************************************************/<br />

unsigned short int *rtc;<br />

unsigned short int *keyb;<br />

unsigned short int *disp;<br />

unsigned short int *ad1;<br />

unsigned short int *ad2;<br />

unsigned short int kvittera, key,tid, status,subStatus, nbrRep;<br />

unsigned short int year,month,day,hour,minute,second;<br />

signed short int alarm1Low,alarm1High,alarm2Low,alarm2High,adAlarm;<br />

unsigned short int savedDataCtr,mean_all_Ctr;<br />

int mean_all_arr_ad1[1439]; /*Medel för ett dygn */<br />

int mean_all_arr_ad2[1439]; /*Medel för ett dygn */<br />

int dygnsmedel_ad1;<br />

int dygnsmedel_ad2;<br />

/*int BuzyFlag=0; */<br />

int Max_ad1, Max_ad2, Min_ad1, Min_ad2;<br />

int dispMinMax_Cnt;<br />

int temp_ad1,temp_ad2; /*Aktuell temp för ad1 & ad2*/<br />

int mean_arr1[59]; /*Array med temp under den<br />

senaste min för ad1*/<br />

int mean_arr2[59]; /*Array med temp under den<br />

senaste min för ad1*/<br />

int mean_ad1,mean_ad2; /*Aktuell medeltemp för ad1 & ad2*/<br />

int mean_array_pek; /*Håller reda på aktuell<br />

position i de två medeltemp arrayerna */<br />

unsigned int data_array_pek; /*Håller reda på aktuell position i de två<br />

data arrayerna */<br />

/*Array struktor för datalagringen (60 minuters lagring.)*/<br />

typedef struct datab AD1;<br />

typedef struct datab AD2;<br />

struct datab<br />

{<br />

int temperatur;<br />

int dag;<br />

int timme;<br />

int minut;<br />

};<br />

AD1 ad1_data[59];<br />

AD2 ad2_data[59];<br />

Sida 39 av 43


Appendix B: PAL<br />

Title templog<br />

Patten INT<br />

Revison 0.1<br />

Author J o M<br />

Company LTH it<br />

Date 16-11-04<br />

device 22V10<br />

IRQKEYB 2<br />

IRQRTC 3<br />

FC2 4<br />

FC0 5<br />

FC1 6<br />

IPL1 14<br />

IPL02 15<br />

VPA 16<br />

start<br />

IPL1 /=IRQKEYB * IRQRTC;<br />

IPL02 /=/IRQRTC;<br />

VPA /=FC0*FC1*FC2;<br />

end<br />

Sida 40 av 43


Title templog<br />

Patten Minne o IO<br />

Revison 0.1<br />

Author J o M<br />

Company LTH it<br />

Date 16-11-04<br />

device 22V10<br />

A14 1<br />

A15 2<br />

A16 3<br />

A17 4<br />

A18 5<br />

A19 6<br />

RW 8<br />

DS 9<br />

AS 10<br />

OEEPROM 14<br />

CSSRAM 15<br />

DTACK 16<br />

OEKEYB 17<br />

CSAD1 18<br />

CSAD2 19<br />

CSRTC 20<br />

OESRAM 21<br />

WESRAM 22<br />

EDISP 23<br />

start<br />

OEEPROM /=/A14*/A15*/A16*/A17*/A18*/A19*/AS;<br />

CSSRAM /=A15*/A16*/A17*/A18*/A19*/AS;<br />

DTACK /=/OEEPROM+/CSSRAM+/OEKEYB+/CSAD1+/CSAD2+/CSRTC+ EDISP;<br />

OEKEYB /= A19*/A18*/A17*/AS;<br />

CSAD1 /=/A19*/A18*A17* RW */DS;<br />

CSAD2 /=/A19*A18*/A17* RW */DS;<br />

CSRTC /=A19*/A18*A17*/AS;<br />

OESRAM /=/DS*RW;<br />

WESRAM /=/DS*/RW;<br />

EDISP =A19*A18*A17*/A16*/DS;<br />

end<br />

Sida 41 av 43


Appendix C: Hårdvara - En sammanfattning av<br />

kopplingsschemat<br />

Processor: Motorola 68008<br />

Denna processor är släkt med Motorolas 68000, fast med en lite mer begränsad databuss<br />

på 8-bitar samt färre avbrottsnivåer än storebror, nämligen endast två stycken. På den<br />

högst prioriterade vill vi ha vår RTC och på den lägre knappsatsen.<br />

Processorn kan allokera upp till 1 MByte RAM och använder således en 14-bitars<br />

adressbuss. Vi har en harmonisk kristalloscillator på 10MHz som matar processorn med<br />

klockpulser. 68008 har en maximal hastighet på 10MHz.<br />

SRAM: 43256<br />

Som internminne använder vi oss utav ett 32 Kbyte stort SRAM.<br />

EPROM: 27C256<br />

Vi använder oss av ett 32 KByte stort EPROM, där vi lagrar programvaran för systemet i<br />

form av kompilerad C-kod.<br />

PAL: PAL22V10<br />

För att få ihop de olika delarna i systemet behövs en del logik. Detta kan man få till på<br />

två sätt; antingen med standardkomponenter ur 74-serien, eller vara steget före och<br />

använda sig av programmerbar logik, sk PAL. Vi har två stycken PAL22V10 där den ena<br />

främst tar hand om Chip Enable samt LCD-logiken. Den andra har hand om<br />

avbrottsge<strong>ner</strong>eringen till processorn.<br />

Knappsats: 16 knappars telefontangentbord<br />

Standardtangentbord med anslutningar för rader och kolum<strong>ner</strong>.<br />

Knappsatsavkodare: 74C922<br />

En smart liten krets som sköter vår knappsats genom att avkoda, avstuddsa, ge avbrott,<br />

samt lägga data på databussen. Till dess hjälp har den en 74HC74 (D-vippa med Set och<br />

Reset), som hjälper till vid avbrottsge<strong>ner</strong>eringen. Dess uppgift är att hålla kvar avbrottet<br />

till dess att vi kvitterar det via reset.<br />

Temperaturgivare: LM335<br />

Vi använder oss av två stycken linjära LM335 temperatursensorer. De ska enligt<br />

databladen ge ut 10 mV/K.<br />

A/D-omvandlare: ADC0804<br />

ADC0804 är en trevlig 8-bitars A/D som vi kör i sk. ”Free Running Mode.”<br />

I vårt system finns det två stycken, en till va rje sensor. Chip Select har vi kopplat direkt<br />

till jord vilket kan uppfattas märkligt, men istället styr vi den via Read (RD). Avbrottet är<br />

direkt återkopplat till Write (WR), detta för att få den i FRM.<br />

Sida 42 av 43


Spänningsreferenser: LM336<br />

Två stycken LM336 förser de två ADC0804 med +2,5V referens för att minska området<br />

för ADC och därmed öka dess noggrannhet. De kopplas in på VREF på ADC0804.<br />

Realtidsklocka: ICM7170<br />

En realtidsklocka som efter inställning av år, datum och tid, sköter sig helt autonomt. Den<br />

kan förses med en batteribackup, vilket uteslöts i detta projekt.<br />

I systemet vill vi att den ge<strong>ner</strong>erar ett avbrott varje sekund. Den klockas med en extern<br />

oscillator på 37kHz. Oscillatorn är trimbar för att uppnå en hög noggrannhet.<br />

LCD display:<br />

Vi har valt en hederlig alfanumerisk LCD med 16 tecken á två rader. Genom att koppla<br />

RS (Register Select) till adressbit 2 delar vi upp registrena (data och kommando) på två<br />

minnesplatser. Dvs. genom att ge displayen data på adress e0000 skickas data till<br />

kommandoregistret och via adress e0004 till dataregistret. En trimpotentiometer förser<br />

V0 med en spänning (0-5V) och via den ändrar man kontrasten.<br />

Sida 43 av 43

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

Saved successfully!

Ooh no, something went wrong!