© Harry Broeders.
Deze pagina is bestemd voor EPv studenten van de THRijswijk.
Het inbraakalarmproject wordt beschreven in het dictaat van het practicum Praktische vaardigheden elektrotechniek. Op deze webpagina kun je de benodigde software vinden. Er is een testprogramma beschikbaar waarmee je de hardware kunt testen. Verder zijn er verschillende functies beschikbaar waarmee de hardware kan worden aangestuurd en ingelezen. Er is echter geen volledig inbraakalarm programma beschikbaar. Dat kunnen jullie met behulp van de gegeven functies best zelf maken!
Het hart van het inbraakalarm is de Simplex3 print met daarop de 68HC11 microcontroller. Aan dit bord wordt een door jou zelf gemaakt inbraakalarmbordje gekoppeld. In het schema van het inbraakalarmbordje kun je zien dat ingangssignalen afkomstig van het toetsenbord en de detectie-ingangen worden ingelezen via de pinnen C15 t/m C21 van de connector. Om het toetsenbord te kunnen "scannen" moeten bepaalde lijnen van het toetsenbord worden aangestuurd, dit gebeurt via de pinnen A1 t/m A4 van de connector. De leds, de buzzer en het relais kunnen door het Simplex3 bord worden aangestuurd via de pinnen A19 t/m A26 van de connector. In de beschrijving van de Simplex3 connector kun je opzoeken dat de pinnen C15 t/m C21 van de connector verbonden zijn met respectievelijk de pinnen PE7 t/m PE1 van de 68HC11. Dit zijn ingangspinnen van de 68HC11 waarmee zowel analoge als digitale ingangen kunnen worden ingelezen. De pinnen A1 t/m A4 zijn verbonden met de pinnen PAA0 t/m PAA3 van de PSD 833F290J. De afkorting PSD betekent in dit geval Programmable System Device (en dus niet Programma Structuur Diagram). De pinnen A19 t/m A26 zijn verbonden met PPB0 t/m PPB7 van de PSD. Deze PSD is een vrij ingewikkelde component waarin verschillende soorten geheugen (RAM en EEPROM), verschillende I/O poorten, een aantal configureerbare logische blokken en een JTAG interface om deze blokken te configureren op één chip zijn geïntegreerd. De datasheet van deze component is veel te ingewikkeld om nu (in de P fase) al te kunnen begrijpen. Wij gebruiken alleen de A en B Input/Output poorten van deze chip en het RAM geheugen om ons programma te testen. Er zijn C functies beschikbaar om naar de A en B poorten van de PSD te schrijven. RAM staat voor Random Access Memory en dit is geheugen dat zowel gelezen als beschreven kan worden maar dat zijn informatie verliest als de spanning wegvalt. Tijdens het testen gebruik je het RAM geheugen van de PSD om je programma in op te slaan. Je kunt het programma later ook in het EEPROM geheugen van de PSD laden. EEPROM staat voor Electrically Erasable Programmable Read Only Memory dit geheugen kan alleen uitgelezen worden en niet worden beschreven. Wel kan dit geheugen op een speciale manier worden geladen (geprogrammeerd) en ook kan het indien nodig weer worden gewist (niet per byte maar in blokken). Als je programma in het EEPROM geheugen geladen is hoef je het niet opnieuw te laden als de spanning wegvalt.
We beginnen met een programma waarmee we de B poort van de PSD kunnen aansturen om de leds, de buzzer en het relais te kunnen testen. Let op! De 68HC11 heeft zelf ook I/O poorten waaronder ook een A en B poort maar deze 68HC11 I/O poorten worden in dit eerste testprogramma niet gebruikt. De PSD op het Simplex3 bordje is zodanig geconfigureerd dat de A en B poorten van de PSD eenvoudig als input of als output te gebruiken zijn. In het zogenaamde Direction registers van de PSD kun je voor elke pin van poort A en poort B aangeven of deze pin als input (default) of als output wordt gebruikt. Vervolgens kun de Data In registers van de PSD gebruiken voor invoer en de Data Out registers voor output. Een overzicht van deze registers, met de adressen waar deze registers zich in de memory map van het Simplex bord, kun je vinden in de onderstaande tabel.
Naam | Adres | Beschrijving |
---|---|---|
Data In A | $1200 | Via dit register kun je de pinnen van poort A inlezen. |
Data In B | $1201 | Via dit register kun je de pinnen van poort B inlezen. |
Data Out A | $1204 | Via dit register kun je de output pinnen van poort A aansturen. |
Data Out B | $1205 | Via dit register kun je de output pinnen van poort B aansturen. |
Direction A | $1206 | Via dit register kun je voor elke pin van poort A aangeven of het een input (0) of output (1) pin moet zijn. |
Direction B | $1207 | Via dit register kun je voor elke pin van poort B aangeven of het een input (0) of output (1) pin moet zijn. |
Alle uitgangssignalen waarmee de leds, de buzzer en het relais worden aangestuurd zijn actief laag. Dat wil zeggen dat ze kunnen worden aangezet door het signaal 0 te maken en dat ze kunnen worden uitgezet door het signaal 1 te maken. Het is erg fijn dat de ontwerpers hier voor hebben gekozen. Als het Simplex bord wordt aangezet zijn alle PPB pinnen geconfigureerd als ingangen. De ingangen van de inverterende buffers (HEF4049) worden dan dus niet aangestuurd. Dit wordt door de inverterende buffers gezien als een logische 1 en de uitgangen van alle buffers zijn dus 0. Daardoor zijn alle ledjes uit, staat het relais uit en (nog veel prettiger) is de buzzer stil. Als we de leds, het relais of de buzzer willen aanzetten moeten we de PPB pinnen configureren als ouput en een 0 schrijven naar een pin om het bijbehorende device aan te zetten.
Het PSD (Programma Structuur Diagram) van een eenvoudig programma om outputs te testen ziet er als volgt uit.
In C kan dit als volgt (testoutputs.c) geïmplementeerd worden:
typedef unsigned char byte;
typedef unsigned short word;
void wacht() {
/* hou de processor even bezig... */
word i;
for (i=0; i<10000; ++i) {
/* niets */
}
}
int main() {
volatile byte* dob=(byte*)0x1205; /* Data Out B register van de PSD */
volatile byte* db= (byte*)0x1207; /* Direction B register van de PSD */
byte patroon[]={0x80, 0x40, 0xc0, 0x20, 0x10, 0x30, 0x08, 0x04, 0x0c, 0x02, 0x01, 0x00};
byte i;
*db=0xff; /* PPB0 t/m PPB7 output */
while (1) {
for (i=0; patroon[i]!=0x00; ++i) { /* Voor alle testpatronen: */
/* Haal testpatroon op uit een array met testpatronen */
/* en stuur dit testpatroon geïnverteerd naar de PPB pinnen */
*dob=~patroon[i];
wacht(); /* Wacht enige tijd */
}
}
return 0;
}
Verklaring:
typedef
wordt de typenaam byte
gedefinieerd. Deze typenaam kan dan gebruikt worden om pointers naar de registers
van de PSD te definiëren.
0x
voor te zetten. In C kunnen helaas geen binaire constanten gedefinieerd worden.
volatile
byte* dob=(byte*)0x1205;
dob
als een pointer naar een byte
in de memorymap. Door deze pointer te initialiseren met de hexadecimale waarde
0x1205
wordt ervoor gezorgd dat deze pointer naar de juiste lokatie in de memorymap
wijst. De notatie (byte*)
die voor
deze waarde staat, heet een "type cast" en is nodig omdat de compiler anders
"denkt" dat we een fout maken door een integer waarde aan een
byte*
toe te kennen. De compiler
geeft dan een warning, probeer maar. Zie eventueel
http://crasseux.com/books/ctutorial/The-cast-operator.html.
De zogenaamde "type modifier"
volatile
is nodig om de compiler te vertellen dat de lokatie waar de pointer naar
wijst geen "normale" geheugenlokatie is. Dit voorkomt dat de compiler ten
onrechte bepaalde optimalisaties uitvoert. Als
volatile
in dit geval wordt weggelaten dan zou de compiler het wegschrijven van een
waarde naar de locatie die door
dob
wordt aangewezen
(*dob=~patroon[i];
) bij het
optimaliseren kunnen weglaten omdat deze waarde toch nooit meer wordt gelezen.
Zie eventueel
http://crasseux.com/books/ctutorial/volatile.html#volatile.
*dob=~patroon[i];
i
uit de array met testpatronen
genaamd patroon
opgehaald en
geïnverteerd naar de PPB pinnen gestuurd. Deze regel maakt gebruik van
de zogenaamde "bit-wise" operator
~
. Let op! Deze operator is heel
iets anders dan de logische operator
!
. De bit-wise operatoren worden
pas in semester H2 bij het vak MICB2 behandeld. Voor studenten die niet kunnen
wachten: Bitn..... in C voor beginnners.
Dit programma kun je met behulp van THRSim11 op je Simplex3 bord draaien. Het THRSim11 programma is een simulatieprogramma voor de 68HC11 microcontroller. Dit programma is al geïnstalleerd op de PC's op school en kun je ook thuis installeren. Zie: http://bd.eduweb.hhs.nl/thrsim11_4_thuis/index.htm
Hier volgt een stap voor stap beschrijving waarmee je het testprogramma op jou bordje kan uitvoeren:
Klik hier voor een verklaring van deze instellingen (indien gewenst).
Als het goed gaat zie je de ledjes 1 voor 1 en kleur voor kleur aangestuurd worden, daarna wordt het relais even aangestuurd en tot slot hoor je de buzzer (misschien kun je dit programma gebruiken als je het inbraakalarmsysteem met Kerst in de boom hangt ;-).
Het scannen van het toetenbord is redelijk ingewikkelde code en deze code wordt nu dan ook niet verder uitgelegd. Deze software kan op dezelfde manier geladen en gestart worden als het testprogramma voor de outputs.
Het indrukken van een toets zal een bepaalde output tot gevolg hebben. Zie onderstaande tabel:
toets | bovenste led | middelste led | onderste led | relais | buzzer |
---|---|---|---|---|---|
1 | groen | uit | uit | uit | uit |
2 | rood | uit | uit | uit | uit |
3 | uit | groen | uit | uit | uit |
4 | uit | rood | uit | uit | uit |
5 | uit | uit | groen | uit | uit |
6 | uit | uit | rood | uit | uit |
7 | groen | groen | groen | uit | uit |
8 | rood | rood | rood | uit | uit |
9 | oranje | oranje | oranje | uit | uit |
* | uit | uit | uit | uit | aan |
0 | rood | oranje | groen | uit | uit |
# | uit | uit | uit | aan | uit |
Om de inbraakalarm software te kunnen programmeren moet je een bepaalde tijd kunnen wachten. Om een bepaalde tijdsduur te wachten maken we gebruik van de zogenaamde "Real Time" counter van de 68HC11. Deze counter zal telkens na 4.096 ms (later in semester H1 zul je leren dat deze waarde instelbaar is) het zogenaamde bit RTIF uit het TFLG2 register van de 68HC11 setten. We kunnen dit bit weer resetten door er een 1 naar toe te schrijven. Nee, dat is geen typefout! Je maakt het RTIF bit 0 door er een 1 naar toe te schrijven, raar maar waar. Dit is te vergelijken met een repeterende wekker die telkens na een bepaalde tijd weer afloopt en die je telkens kunt uitdrukken (je kent dat wel;-). Door nu te tellen hoeveel maal deze "wekker" is afgelopen kun je de verstreken tijd bepalen. Het TFLG2 register bevindt zich op adres $1025 van de memory map en bit RTIF is bit 6 van dit register.
In het testprogramma voor de outputs kan nu telkens een halve seconde worden
gewacht door de functie wacht
als
volgt te implementeren
(testoutputs.c):
typedef unsigned char byte;
void wacht() {
/* wacht 122 * 4.096 ms = (ongeveer) 0.5 sec */
volatile byte* tflg2=(byte*)0x1025; /* TFLG2 register van de 68HC11 */
byte i;
for (i=0; i<122; ++i) { /* wacht 122 keer */
while ((*tflg2&0x40)!=0x40) { /* wacht tot RTIF == 1 */
/* niets */
}
*tflg2=0x40; /*maak RTIF 0 (door er een 1 naar toe te schrijven) */
}
}
Verklaring:
volatile
byte*
tflg2=(byte*)0x1025;
tflg2
als een pointer naar een
byte in de memorymap. Door deze pointer te initialiseren met de hexadecimale
waarde
0x1025
wordt ervoor gezorgd dat deze pointer naar het TFLG2 register van de 68HC11
wijst.
while
((*tflg2&0x40)!=0x40)
{ /* niets */ }
&
. Let
op! Deze operator is heel iets anders dan de logische operator
&&
. De bit-wise operatoren
worden pas in semester H2 bij het vak MICB2 behandeld. Voor studenten die
niet kunnen wachten: Bitn..... in C voor
beginnners.
*tflg2=0x40;
0x40
naar het TFLG2 register van de 68HC11 geschreven. In bit 6 van dit register
wordt dus een 1 geschreven (zet de hexadecimale waarde
0x40
maar om naar het binaire stelsel). Door het schrijven van deze 1 wordt het
bit RTIF (bit 6 van het TFLG2 register) op 0 gezet! Dat is vreemd
maar zo werkt dit TFLG2 register van de 68HC11 nu eenmaal.
Het programma voor het inbraakalarmsysteem mag je zelf schrijven met behulp van een aantal functies waarmee je de hardware kunt aansturen en inlezen. De functies zijn beschikbaar in het programma inbraakalarm.c. Hier zijn de bijbehorende makefile en simplex3.ld files.
De beschikbare functies:
void wacht(word
n);
n
* 4.096 ms.
Tot 18 november 2005 zat
er een fout in deze functie waardoor het niet werkte voor
n
>255. Deze fout is inmiddels hersteld (met dank aan Sheng
Li die dit "vreemde" gedrag heeft beschreven in zijn verslag).
char
scankey();
'\0'
teruggegeven.
byte scaninput(byte i);
i
(i
=0 t/m 3) terug. Als de ingang
hoog is (verbinding is verbroken) wordt een
1
teruggegeven en als de ingang laag is (verbinding is verbonden) wordt een
0
teruggegeven. Bij een ongeldige waarde van
i
wordt
0xff
teruggegeven. De constanten
VERBROKEN
en
VERBONDEN
zijn gedefinieerd als
1
respectievelijk
0
.
void buzzer(byte
aanuit);
aanuit
0
is wordt de buzzer uitgezet. Als de parameter
aanuit
ongelijk aan
0
is wordt de buzzer aangezet. Bij aanroep kun je voor de parameter
aanuit
de constante
AAN
of
UIT
gebruiken.
void relais(byte
aanuit);
aanuit
0
is wordt het relais uitgezet. Als de parameter
aanuit
ongelijk aan
0
is wordt het relais aangezet. Bij aanroep kun je voor de parameter
aanuit
de constante
AAN
of
UIT
gebruiken.
void led(byte
i, byte k);
i
op kleur
k
. Bij aanroep kun je voor de parameter
i
de constante
BOVEN
,
MIDDEN
of
ONDER
gebruiken. Bij aanroep kun je voor de parameter
k
de constante
UIT
,
GROEN
,
ROOD
of
ORANJE
gebruiken.
Een testprogramma dat gebruik maakt van deze functies is hieronder gegeven:
int main() {
char c;
*db=0xff; /* PPB0 t/m PPB7 output */
*da=0x0f; /* PPA0 t/m PPA4 output */
*dob=0xff; /* PPB0 t/m PPB7 hoog (uit) */
while (1) {
/*
Schrijf hier je eigen inbraakalarm programma!
*/
c=scankey();
switch(c) {
case '0': led(BOVEN, UIT);
led(MIDDEN, UIT);
led(ONDER, UIT);
relais(UIT);
buzzer(UIT);
break;
case '1': led(BOVEN, ROOD);
break;
case '2': led(BOVEN, ORANJE);
break;
case '3': led(BOVEN, GROEN);
break;
case '4': led(MIDDEN, ROOD);
break;
case '5': led(MIDDEN, ORANJE);
break;
case '6': led(MIDDEN, GROEN);
break;
case '7': led(ONDER, ROOD);
break;
case '8': led(ONDER, ORANJE);
break;
case '9': led(ONDER, GROEN);
break;
case '*': buzzer(AAN);
break;
case '#': relais(AAN);
break;
}
if (scaninput(0)==VERBONDEN) {
buzzer(AAN);
wacht(122);
buzzer(UIT);
wacht(122);
}
}
return 0;
}
Tot nu toe hebben we de programma's in het RAM (Random Access Memory) van het Simplex3 bordje geladen. Het voordeel van het gebruik van RAM is dat dit geheugen zowel gelezen als geschreven kan worden. De programma's kunnen dus eenvoudig in RAM worden geladen. Een nadeel van RAM is dat de hierin opgeslagen informatie verloren gaat zodra de spanning wegvalt. Het Simplex3 bordje bevat ook 160 Kb Flash geheugen (in de PSD) en 0.5 Kb EEPROM geheugen (in de 68HC11). Zowel Flash als EEPROM (Electrical Erasable Programmable Read Only Memory) kunnen alleen gelezen worden maar behouden hun informatie als de spanning wegvalt. Zowel Flash als EEPROM geheugen moet eerst gewist worden voordat er nieuwe informatie in "geprogrammeerd" kan worden. We noemen het schrijven in Flash of EEPROM "programmeren" omdat het vele malen trager is dan het schrijven in RAM en alleen gedaan mag (kan) worden nadat het betreffende geheugen(deel) gewist is.
Het testkeyboard.c programma is klein genoeg om in het EEPROM geheugen van de 68HC11 te passen. Je kunt dit programma als volgt in het EEPROM geheugen "programmeren":
BULK
commando
in te typen.