Atom Nieuws 2000 nr 2
../../../images/back.gif ../../../images/exit.gif ../../../images/forward.gif
pagina 9
PIC 16F84 ICE
door Roland Leurs

Soms heeft een mens het dermate moeilijk in het leven dat hij echt behoefte heeft om eens te zien hoe het echt in elkaar steekt. Ik heb het hier niet over gezinsproblemen, problemen op mijn werk, maar over problemen met mijn PicAtom kaart. Dit project weet maar niet op te schieten. Temeer omdat ik steeds tegen de meest rare dingen aanloop: vergeten weerstandje, defecte 8250, Atom-in-PC kaart die niet functionezeert...

Kortom, ik zou nu wel eens willen zien wat er echt gebeurt op dat printje. Ik kan daarvoor een In-Circuit Emulator (ICE) kopen. Echter, dit is voor hobby doeleinden te kostbaar.

Met John Feron heb ik daar eens een boompje over opgezet. Het leek hem zeer ingewikkeld om zoiets zelf te bouwen. Nu ben ik het voor een gedeelte met hem eens. Maar voor mijn toepassing zou ik kunnen volstaan met een aantal zaken:

1. Alle instructies van de PIC16F84 moeten herkend en correct uitgevoerd worden
2. Alle I/O lijnen moeten beschikbaar zijn, dus elke pin bidirectionele I/O.

Mijn zeer premature ICE was een Atom met veertien draadjes aan zijne VIA poort op de brede connector rechts achter boven. Hiermee voldeed ik al aan punt 2. en daarmee had ik al redelijk snel de eerste twee problemen van de - gloeiende gloeiende, ik word zojuist door een mug gestoken - waar was ik? O ja, met die Atom en de veertien draadjes had ik al snel gevonden dat de 8250 niet werkte en dat ik de verkeerde data inlas. Dat wil zeggen, de data was welliswaar correct maar niet datgene dat ik moest hebben. De volgende stap is het automatisch uitvoeren van alle instructies in een PIC programma conform de datasheets. Hierbij moest ik de overweging maken tussen het Atom-platform of overstappen naar de PC. Aangezien de PIC assembler al op de PC draait vond ik het toch het meest voor de hand liggen om deze ICE op een PC te bouwen.

Een ICE kan volgens een betrekkelijk eenvoudig basisprincipe gebouwd worden:

  • Lees je programma bestand in binaire vorm in
  • Voer een reset uit (specificaties in datasheet)
  • Begin met de eerste instructie
Registers en vlaggen onthoud je in variabelen. Een voorbeeld van zo'n instructie is hieronder gegeven voor de instructie clrf, deze instructie wist een register. Het adres van het betreffende register staat in de opcode. (Voor de niet 16F84 kenner: deze PIC heeft een aantal geheugenplaatsen die als register gebruikt kunnen worden. Zie het maar als een kruising tussen de zeropage en de Accu van een 6502).

void opcode_clrf(int opcode, int command)
    {
     if (command & instr_show)
             {
              printf("CLRF %0.2X", opcode&0x7F);
              }
      if (command & instr_exec)
              {
              setreg(opcode,0);
              regfile[STATUS]|=0x04;
              clockpulse();
              pc++;
              }
      }
De kenner heeft al in de gaten dat het programma in de taal C geschreven heeft. Dat heb ik gedaan omdat het dan makkelijk om te zetten is van Linux (alwaar het ontwikkeld wordt) naar DOS.

Bovenstaande routine wordt voor twee doeleinden aangeroepen. De eerste is voor het afdrukken van de instructie in de disas lijst. De tweede aanroep voert de instructie uit. Door deze aanpak hoef ik per instructie slechts eenmaal een routine te schrijven. Da's een stuk duidelijker voor later.

Het uitvoeren van de instructie CLRF werkt dus als volgt:
  1. Voer de functie setreg uit; deze functie haalt het adres uit de meegestuurde opcode en de waarde die geschreven moet worden, wordt eveneens als parameter meegegeven. Registers worden via een aparte functie (lees: subroutine) geschreven en gelezen. Hierdoor kan dezelfde functie aanroep gebruikt worden voor normale en speciale registers.
  2. Zet de zero-vlag op 1. De zero-vlag is het derde bit van het statusregister. Het status register is een van de registers in de registerfile.
  3. Simuleer een klokpuls. In deze routine kunnen dus een aantal zaken zoals timer en interrupt bijgewerkt worden.
  4. Verhoog de program pointer. De emulator gaat dan vervolgens verder met het inlezen van de volgende instructie.

Op deze manier kunnen alle instructies nagebootst worden. Na elke instructie wordt het scherm bijgewerkt: de disaslijst wordt opnieuw afgedrukt, registers worden bijgewerkt en ook de datadump wordt herschreven. Afhankelijk van de mode (run of trace) wordt er gewacht op een toetsaanslag.

De emulator kent een aantal schermen met informatie:

  • Hexdump van de registers
  • Hexdump van het E-Eprom geheugen
  • Inhoud van de stack en stackpointer
  • Breakpoints (maximaal 8)
  • Definitie van het configuratie woord

Hieronder ziet u een afdruk van een van de schermen:

Het emuleren van de instructies heb ik nu al redelijk in mijn programma zitten. Het werkt al in zoverre dat ik mijn PicAtom software kan emuleren. De overige instructies moeten nog gemaakt worden. Ook randverschijnselen zoals interrupts, timers e.d. moeten nog geïmplementeerd worden. Maar het grootste probleem is hier: de bidirectionele I/O poorten. De doorsnee lezer weet dat een PC niet zo'n fijne I/O poort heeft als de Atom.

Samen met Leendert Bijnagte werk ik nu aan een I/O kaart die een standaard printerpoort voorziet van twee 8-bits brede bidirectionele I/O lijnen. Hiervoor gebruiken we een 6821 (vergelijkbaar met de Atom Via, maar zonder timers). Deze wordt middels enkele lees- en schrijfopdrachten naar de printerpoort aangestuurd. Een demo was te zien op de landdag, waarbij ik geen 6821 maar een 8255 gebruikte. Deze kan echter niet op bit-basis omschakelen tussen ingang en uitgang. Verder wil ik geen printje meer maken dat in de PC komt te zitten, dat is niet universeel genoeg, en zeker niet als de ISA bus uit de PC dreigt te verdwijnen. Het voorlopige schema van deze PC Printerpoort I/O kaart vindt u op de volgende bladzijde.

Er is nog veel te doen voordat het geheel af is, maar langzaam maar zeker kom ik toch weer een stapje verder bij het einddoel: de Atom-in-PC aan de laptop...

Groeten uit een zonnig Born,
Roland Leurs.

../../../images/back.gif ../../../images/exit.gif ../../../images/forward.gif