Het gebruik van het Simplex3 68HC11 bord in het windmeter project.

© Harry Broeders.

Deze pagina is bestemd voor EP1 studenten van de THRijswijk.

Inleiding.

Het windmeterproject wordt beschreven in het dictaat van het Ingenieurspracticum. Op deze webpagina kun je de benodigde software vinden. Je vind hier ook een beschrijving van de werking en enkele ideëen om deze windmetersoftware nog beter (of leuker) te maken. Het hart van de windmeter is de Simplex3 print met daarop de 68HC11 microcontroller. Aan dit bord wordt een door jou zelf gemaakt windmeterbordje gekoppeld. In het schema van het windmeterbordje kun je zien dat de puls afkomstig van de Hall sensor door het Simplex3 bord kan worden ingelezen via pin C25 van de connector. De leds kunnen door het Simplex3 bord worden aangestuurd via de pinnen A1 t/m A8 en A19 t/m A22 van de connector. In de beschrijving van de Simplex3 connector kun je opzoeken dat pin C25 van de connector verbonden is met pin PA2 van de 68HC11. Dit is een input capture ingang van de 68HC11 en met behulp van de input capture timer kunnen we de pulsduur van het signaal afkomsig van de Hall sensor bepalen. Ook kunnen we de pulsen op deze ingang gedurende een bepaalde tijd tellen. Maar hierover later meer. De pinnen A1 t/m A8 zijn verbonden met de pinnen PAA0 t/m PAA7 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 A22 zijn verbonden met PPB0 t/m PPB3 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.

Test programma om de LED's aan te sturen.

We beginnen met een programma waarmee we de A en B poort van de PSD kunnen aansturen om de led aansturing 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.

Registers voor het besturen van poort A en B van de PSD
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.

Het PSD (Programma Structuur Diagram) van een eenvoudig programma om leds te testen ziet er als volgt uit.

Als het goed gaat zie je afwisseld de even en de oneven ledjes branden (misschien kun je dit programma gebruiken als je de windmeter met Kerst in de boom hangt ;-).

In C kan dit als volgt (testleds.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* doa=(byte*)0x1204; /* Data Out A register van de PSD */
   volatile byte* dob=(byte*)0x1205; /* Data Out B register van de PSD */
   volatile byte* da= (byte*)0x1206; /* Direction A register van de PSD */
   volatile byte* db= (byte*)0x1207; /* Direction B register van de PSD */

   *da=0xff; /* PPA0 t/m PPA7 output */
   *db=0x0f; /* PPB0 t/m PPB3 output, PPB4 t/m PPB7 input (niet gebruikt) */

   while (1) {
      *doa=0x55; /* PPA0, PPA2, PPA4 en PPA6 aan rest uit */
      *dob=0x05; /* PPB0 en PPB2 aan rest uit */
      wacht();
      *doa=0xaa; /* PPA0, PPA2, PPA4 en PPA6 uit rest aan */
      *dob=0x0a; /* PPB0 en PPB2 uit rest aan */
      wacht();
   }

   return 0;
}

Verklaring:

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:

  1. Verbind het zelfgemaakte windmeterbordje met het Simplex3 bordje.
  2. De jumper JP1 (TRACE) op het Simplex bordje moet op de stand PA3 staan. De twee dipswitches DIPSW1 (MODA) en DIPSW2 (MODB) moeten beide in de OFF stand staan.
  3. De jumper op het windmeterbordje (naast de connector) moet zijn verwijderd.
  4. Start THRSim11.
  5. Kies de menu optie File, Options, Memory Configuration...
  6. Configureer het geheugen als volgt:

    Klik hier voor een verklaring van deze instellingen (indien gewenst).

  7. Controleer de memory map via het View, Memory, Memory Map... menu.
  8. Om het programma te kunnen compileren heb je een zogenaamde makefile en een linker script nodig. Klik hier voor meer uitleg over het linker script en de makefile (indien gewenst). Maak een nieuw directory aan en kopieer de files: testleds.c, simplex3.ld en makefile in dit directory. Je kunt deze files kopiëren door met de cursor op de link te gaan staan en op de rechterknop van de muis te klikken en vervolgens "Save Target As..." te kiezen.  Let op: Internet Explorer zet de extensie .txt achter de makefile (na het downloaden). Deze extensie moet je verwijderen.
  9. Laad het programma testleds.c in THRSim11 via het File, Open... menu. Als het goed is wordt het programma nu automatisch in de editor SciTe geopend.
  10. Compileer het programma en laad het resultaat met behulp van de sneltoets F5.
  11. Om dit programma in het Simplex bordje te kunnen laden moet je de seriële poort van het Simplex3 bordje verbinden met een seriële poort van de PC.
  12. In THRSim11 moet je de communicatie opties via het menu Target, Target Communications Options... als volgt instellen:

  13. Je kunt nu, via de sneltoets Ctrl+D, het programma in het Simplex3 bord downloaden. Let er op dat het window waarin de listing zichtbaar is actief is als je op Ctrl+D drukt. (Als dat niet zo is verschijnt een file select dialog box. Druk als deze dialog verschijnt op Cancel en probeer het opnieuw.)
  14. Via de spatiebalk kun je het programma instructie voor instructie op het bord uitvoeren. Met de sneltoets Ctrl+F9 kun je het programma op het target bord starten. De enige manier om het programma daarna te stoppen is via de reset switch (SW2). De reset switch zit op het Simplex3 bordje vlak naast de seriële connector.

Testprogramma voor de timing.

Om de windsnelheid te kunnen meten moet je de pulsjes afkomstig van de Hall sensor een bepaalde tijd kunnen tellen. 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 leds kan nu telkens een halve seconde worden gewacht door de functie wacht als volgt te implementeren (testleds.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:

Testprogramma voor de Hall sensor.

Het van de Hall sensor afkomstige pulsvormige signaal is aangesloten op ingangspin PA2 van de 68HC11. Elke keer dat de windmeter een rondje draait zal de Hall sensor een puls afgeven. De Input Capture Timer van de 68HC11 kan zo ingesteld worden dat het bit ICF1 uit het TFLG1 register van de 68HC11 wordt geset bij een opgaande flank op de PA2 ingang. Met behulp van de Input Capture Timer van de 68HC11 kunnen we ook de tijdsduur tussen 2 pulsen meten maar daar maken we nu geen gebruik van (dat leer je later in H1 bij de onderwijsmodule MICB1). Het TFLG1 register bevindt zich op adres $1023 van de memory map en bit IC1F is bit 2 van dit register. Je maakt het IC1F bit 0 door er een 1 naar toe te schrijven, raar maar daar ben je nu wel aan gewend. Om de Input Capure timer het IC1F bit bij elke opgaande flank van PA6 te laten setten moet de waarde $10 naar het TCTL2 register (adres $1021) van de 68HC11 worden geschreven.

Door nu in de functie wacht van het testleds.c programma niet meer een vaste tijd te wachten maar te wachten totdat een opgaande flank op de PA2 ingang is gedetecteerd zullen de leds "verspringen" als de windmeter een rondje heeft gedraaid.

typedef unsigned char byte;

void wacht() {
   /* wacht op een opgaande flank van PA2 (Hall sensor) */
   volatile byte* tflg1=(byte*)0x1023; /* TFLG1 register van de 68HC11 */
   while ((*tflg1&0x04)!=0x04) { /* wacht tot IC1F = 1 */
      /* niets */
   }
   *tflg1=0x04; /* maak IC1F 0 (door er een 1 naar toe te schrijven) */
}

int main() {
   volatile byte* tctl2=(byte*)0x1021; /* TCTL2 register van de 68HC11 */
   volatile byte* doa=(byte*)0x1204; /* Data Out A register van de PSD */
   volatile byte* dob=(byte*)0x1205; /* Data Out B register van de PSD */
   volatile byte* da= (byte*)0x1206; /* Direction A register van de PSD */
   volatile byte* db= (byte*)0x1207; /* Direction B register van de PSD */

   *tctl2=0x10; /* zorg ervoor dat IC1F 1 wordt bij een opgaande flank op PA2 */
   *da=0xff; /* PPA0 t/m PPA7 output */
   *db=0x0f; /* PPB0 t/m PPB3 output, PPB4 t/m PPB7 input (niet gebruikt) */

   while (1) {
      *doa=0x55; /* PPA0, PPA2, PPA4 en PPA6 aan rest uit */
      *dob=0x05; /* PPB0 en PPB2 aan rest uit */
      wacht();
      *doa=0xaa; /* PPA0, PPA2, PPA4 en PPA6 uit rest aan */
      *dob=0x0a; /* PPB0 en PPB2 uit rest aan */
      wacht();
   }

   return 0;
}

De windsnelheidsindicator.

Door nu het tellen van Real Time counter "perioden" en het tellen van pulsen van de Hall sensor met elkaar te combineren kun je een programma maken waarmee een indicatie voor de windsnelheid op de leds wordt weergegeven.

Windmeter variabelen tabel
naam type omschrijving
IC1F bit bit 2 in het TFLG1 register van de 68HC11 wordt gebruikt om pulsen afkomstig van de Hall sensor te tellen
RTIF bit bit 6 in het TFLG2 register van de 68HC11 wordt elke 4.096 ms geset en wordt gebruikt om 2 s af te tellen
pulsen word hierin wordt het aantal pulsen, gedurende 2 s, afkomstig van de Hall sensor geteld
RT_perioden word hierin wordt het aantal Real Time perioden geteld. 1 periode = 4.096 ms dus 488 perioden = 488 * 4.096 = ongeveer 2 s
aantal_leds word het aantal_leds wat moet branden, wordt elke 2 s berekend met behulp van de waarde van pulsen
patronen_a byte[13] op plaats X in deze array staat het patroon dat naar poort A van de PSD moet schrijven om de eerste X leds te laten branden (X = 0 t/m 12)
patronen_b byte[13] op plaats X in deze array staat het patroon dat naar poort B van de PSD moet schrijven om de eerste X leds te laten branden (X = 0 t/m 12)

In C kan dit als volgt geïmplementeerd worden (windmeter.c):

typedef unsigned char byte;
typedef unsigned short word;

int main() {
   volatile byte* tflg1=(byte*)0x1023;
   volatile byte* tflg2=(byte*)0x1025;
   volatile byte* tctl2=(byte*)0x1021;
   volatile byte* doa=(byte*)0x1204;
   volatile byte* dob=(byte*)0x1205;
   volatile byte* da= (byte*)0x1206;
   volatile byte* db= (byte*)0x1207;
   word pulsen, RT_perioden, aantal_leds;
   byte patronen_a[13]={0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff,0xff,0xff,0xff,0xff};
   byte patronen_b[13]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x0f};

   *tctl2=0x10;
   *da=0xff;
   *db=0x0f;
   while (1) {
      pulsen=0;
      RT_perioden=488;
      do {
         if ((*tflg1&0x04)==0x04) {
            *tflg1=0x04;
            pulsen=pulsen+1;
         }
         if ((*tflg2&0x40)==0x40) {
            *tflg2=0x40;
            RT_perioden=RT_perioden-1;
         }
      }
      while (RT_perioden!=0);
      aantal_leds=pulsen*25/100; /* nog afregelen! */
      if (aantal_leds>12) {
         aantal_leds=12;
      }
      *doa=patronen_a[aantal_leds];
      *dob=patronen_b[aantal_leds];
   }
   return 0;
}

In dit programma is het commentaar bewust weggelaten. Kun jij dat zelf toevoegen?
Hier zijn de bijbehorende makefile en simplex3.ld files.

Ook zonder bordje kun je dit programma in de simulator testen. Dit is erg handig als je het programma wilt aanpassen en vervolgens wilt testen en/of debuggen. Klik hier voor een stap voor stap beschrijving hoe je het programma in de simulator kunt testen.

Programma laden in het EEPROM geheugen van de 68HC11.

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 windmeter.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":

  1. Maak een nieuw directory aan en kopieer de files: windmeter.c, simplex3_eeprom.ld en makefile in dit directory. Je kunt deze files kopiëren door met de cursor op de link te gaan staan en op de rechterknop van de muis te klikken en vervolgens "Save Target As..." te kiezen.  Let op: Internet Explorer zet de extensie .txt achter de makefile (na het downloaden). Deze extensie moet je verwijderen.
  2. Laad het programma windmeter.c in THRSim11 via het File, Open... menu. Als het goed is wordt het programma nu automatisch in de editor SciTe geopend.
  3. Compileer het programma en laad het resultaat met behulp van de sneltoets F5.
  4. Om dit programma in het Simplex bordje te kunnen laden moet je de seriële poort van het Simplex3 bordje verbinden met een seriële poort van de PC.
  5. Als de communicatie opties juist zijn ingesteld (zie hierboven) dan kun je nu met de menu optie: Target, Target Connect verbinding maken met het Simplex3 bord.
  6. Je kunt nu een window openen om commando's naar het Simplex3 bord te sturen met behulp van de menu optie: Target, Target Command Window. Het EEPROM geheugen kan nu gewist worden door het BULK commando in te typen.
  7. Je kunt dit programma nu in het EEPROM geheugen van de 68HC11 op het Simplex3 bord "programmeren" met behulp van de menu optie: Target, Target Copy, Copy Simulator EEPROM Memory to Target. Je moet er zelf voor zorgen dat het EEPROM geheugen eerst wordt gewist voordat het wordt geprogrammeerd. Om deze optie te kunnen gebruiken moet je versie 5.21c (26 september 2004) of hoger van THRSim11 hebben. Je kunt de laatste versie van THRSim11 hier vinden: http://bd.eduweb.hhs.nl/thrsim11_4_thuis/index.htm.
  8. Het programma in EEPROM kan worden gestart door de jumper op het windmeterbordje (naast de connector) door te verbinden en de reset switch (SW2) in te drukken (en weer los te laten). De reset switch zit op het Simplex3 bordje vlak naast de seriële connector.
  9. Als nu de voedingsspanning wordt weggenomen zal het windmeter.c programma automatisch worden opgestart zodra de voedingspanning weer wordt aangesloten.
  10. Vergeet niet om de jumper op het windmeterbordje (naast de connector) weer te verwijderen als je THRSim11 weer met je bordje wilt laten communiceren.

Afregelen van de windmeter.

In de windtunnel kun je de windmeter afregelen. Je doet dit door in het programma de volgende regel aan te passen:
aantal_leds=pulsen*25/100; /* nog afregelen! */

Mogelijke uitbreidingen:

Mogelijke verbeteringen:

In het eerste semester en tweede semster van de hoofdfase (H1 en H2) leer je nog veel meer over microcontrollers in het algemeen en de 68HC11 in het bijzonder. Als je de onderwijsmodulen MICB1 en MICB2 volgt zal blijken dat er nog andere (betere) mogelijkheden zijn: