Ladda ner rapporten... - EIT - Lunds Tekniska Högskola
Ladda ner rapporten... - EIT - Lunds Tekniska Högskola
Ladda ner rapporten... - EIT - Lunds Tekniska Högskola
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