Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Breadboardcomputerprogrammeur

Componenten en benodigdheden

Arduino UNO
× 1

Over dit project

Wat is dit voor project?

Dit is een uitbreiding op het 8-bits breadboard-computerproject van Ben Eater. Ik heb enorm genoten van het volgen van Bens video's over het bouwen van een breadboard-computer en het bouwen van mijn eigen versie ervan. Als je Ben nog niet hebt gevolgd, raad ik je ten zeerste aan zijn video's te bekijken voordat je gaat lezen - dit project heeft weinig zin zonder de context.

Na het bouwen van de computer werd het al snel duidelijk dat als ik een programma handmatig moest in- en uitschakelen via DIP-schakelaars elke keer dat ik hem aanzette, het helemaal niet veel zou betekenen. Zelfs het keer op keer in- en uitschakelen van slechts 16 bytes wordt erg snel oud. Ik was ook van plan het geheugen uit te breiden tot 256 bytes en dat zou alleen nuttig zijn als op de een of andere manier programma's konden worden geladen en opgeslagen.

Wat kan ik ermee doen?

  • Een programma opslaan vanuit het RAM-geheugen van de breadboard-computer
  • Laad een programma in het RAM-geheugen van de breadboard-computer
  • Voer een opgeslagen programma automatisch uit wanneer de breadboard-computer opstart
  • Inspecteer en wijzig de geheugeninhoud via een seriële verbinding
  • Programmeer de breadboard-computer in assembler
  • Demonteer geheugeninhoud
  • Eenstaps instructie per instructie
  • Stel breekpunten in en ren naar het breekpunt

Hier is een video die deze functies demonstreert. Excuseer de videokwaliteit - ik ben geenszins een professionele maker van video-inhoud:

Hoe werkt het?

Ik had een paar doelen in gedachten tijdens het maken van dit project:

  • Zo min mogelijk hardware nodig om het te bouwen
  • Zo min mogelijk wijzigingen aan de breadboard-computer zelf

In het begin dacht ik aan het gebruik van een EEPROM om programma's op te slaan en vervolgens een soort logica om programma's van de EEPROM naar het RAM-geheugen van de breadboard-computer over te brengen. Het bedenken van de overdrachtslogica bleek echter ingewikkelder dan ik aankon (ik ben meer een softwareman, hoewel ik er echt van geniet om dicht bij hardware te werken). Ik ben toevallig een grote Arduino-fan, dus op een gegeven moment begon ik te denken aan het vervangen van de overdrachtslogica door een Arduino. Het kostte wat tijd om mezelf ervan te overtuigen dat het gebruik van een Arduino niet vals spelen was (zelfs de Arduino UNO is immers veel krachtiger dan de breadboard-computer zelf), maar ik ben blij met het resultaat, dus ik heb mijn vrede gesloten.

Dus wat moet de Arduino kunnen doen? Welnu, het moet gegevens uit het geheugen kunnen lezen en gegevens naar het geheugen kunnen schrijven. De gemakkelijkste en minst ingrijpende (voor de breadboard-computer) manier om dat te doen, is door dezelfde interface te gebruiken die de geheugenmodule al heeft:de bus- en besturingssignalen. De digitale I/O-pinnen van Arduino zijn bidirectioneel, dus als u er 8 rechtstreeks op de bus aansluit, kan de Arduino lezen van en schrijven naar de bus. Om de RAM-module te laten lezen van of schrijven naar de bus, hoeft u alleen de MI/RI/RO-signalen dienovereenkomstig in te stellen. Nu worden die signalen meestal aangestuurd door de EEPROM's van de besturingslogica, dus als de Arduino ze ook bestuurt, zou dit leiden tot conflicten en mogelijke kortsluitingssituaties. De AT28C16 EEPROMS die door Ben worden gebruikt, hebben echter een Chip Enable (CE) -ingang die alle gegevensuitgangen in een hoge-z-status zet - waardoor de Arduino de signalen kan manipuleren. Om het RAM uit te lezen, moet de Arduino het volgende doen:

  • zet het CE-signaal van de EEPROM hoog (d.w.z. schakel de besturingslogica uit)
  • voer het eerste adres in dat moet worden gelezen op de bus
  • zet het MI-signaal hoog en wacht op een klok-laag-hoog-overgang
  • zet MI laag en RO hoog en wacht op een klok laag-hoog overgang
  • lees de databyte van de bus
  • herhaal vanaf stap 2 voor alle 16 adressen
  • zet het CE-signaal van de EEPROM laag (d.w.z. schakel de besturingslogica opnieuw in)

En dat is het. Het schrijven van RAM-inhoud lijkt erg op elkaar, de Arduino hoeft alleen maar naar de bus te schrijven en RI hoog in te stellen in plaats van RO. Er zijn natuurlijk enkele technische problemen die moeten worden opgelost, maar het bovenstaande basismechanisme is het hart van dit project.

Welke wijzigingen moet ik aanbrengen in de breadboard-computer?

Er zijn twee wijzigingen die moeten worden aangebracht:

  • Plaats pull-down weerstanden op de data-uitgangen van de besturingslogica EEPROM
  • Schakel de belteller uit (of reset continu) terwijl de EEPROM is uitgeschakeld

Pull-down weerstanden

De pull-down-weerstanden zijn vereist, want als de EEPROM eenmaal is uitgeschakeld, zullen de pull-up-weerstanden van de logische poorten waarop de besturingssignalen (zoals AO/AI/EO...) zijn aangesloten, deze signalen naar boven halen. Dat zou betekenen dat meerdere registers naar de bus zouden schrijven, waardoor er conflicten zouden ontstaan.

De pull-up weerstanden op de ingangen van 74LS-poorten zijn ongeveer 10k. Dus de pull-down-weerstanden moeten klein genoeg zijn om de spanning in een laag gebied te krijgen. Voor de meeste signaallijnen heb ik weerstanden van 3,3 kOhm gebruikt. Er zijn echter twee uitzonderingen:ten eerste is het "SU"-signaal verbonden met 8 exclusieve OF-poorten, wat betekent dat de effectieve pull-up-weerstand 10kOhm/8 =1,25kOhm is. Een pull-down-weerstand zou aanzienlijk minder dan 1k moeten zijn om dit laag te krijgen. Gelukkig regelt het SU-signaal (aftrekken) geen enkele interactie met de bus, dus we kunnen het gewoon negeren en geen pull-down-weerstand hebben. Ten tweede had de CE (counter enable) een pull-down-weerstand van 1k nodig - grotere waarden veroorzaakten in sommige gevallen willekeurig programmatellergedrag.

Ik vond het het gemakkelijkst om de pull-down-weerstanden toe te voegen op het breadboard dat alle blauwe LED's bevat, d.w.z. tussen de LED-anoden (die zijn aangesloten op de EEPROM-uitgangen) en GND.

[Ik kon de weerstanden hier niet inpassen voor de HLT/MI/RI-signalen, dus heb ik die op andere locaties op het breadboard toegevoegd]

Belteller resetten

De andere wijziging is het resetten van de belteller. Technisch gezien is dit niet echt nodig om programma's te kunnen opslaan/laden, maar het zorgt voor een soepele overdracht van de besturing van de Arduino terug naar de besturingslogica. Het punt is om de ringteller op 0 te houden zolang CE hoog is (d.w.z. de besturingslogica is uitgeschakeld). Wanneer de Arduino CE weer laag zet (waardoor de besturingslogica mogelijk wordt), staat de ringteller op nul en begint de breadboard-computer de volgende instructie uit te voeren.

Voor mijn build hoefde ik hier niets voor te doen omdat ik één EEPROM-uitgang gebruik om de ringteller te resetten. Dit verbetert de prestaties door de belteller te resetten zodra een instructie is voltooid. Het geeft me ook automatisch de ringteller-reset wanneer de besturingslogica EEPROM wordt uitgeschakeld:de pull-down-weerstand op de EEPROM-uitgang zal het signaal laag maken waardoor de ringteller wordt gereset.

Als je Ben's implementatie van een vaste 5-staps-ringteller gebruikt, denk ik dat de volgende uitbreiding van zijn resetcircuit de teller moet resetten als CE hoog is (klik op de links / rechts-pijlen hieronder om te schakelen tussen Ben's originele circuit en de uitgebreide versie):

Zoals je kunt zien, zijn er nog 3 NAND-poorten nodig, d.w.z. nog een 74LS00-chip. Merk op dat ik deze aanpak niet heb getest, maar het zou moeten werken voor zover ik kan zien.

Deze wijziging is niet absoluut noodzakelijk - u kunt deze in het begin weglaten. Zowel het laden en opslaan als de monitor/assembler/deassembler werken nog steeds prima. Elke actie waarbij de besturing van de Arduino naar de besturingslogica moet worden overgedragen, zal echter niet werken. Het meest opvallende is dat opgeslagen programma's automatisch worden uitgevoerd bij het opstarten en in één stap worden uitgevoerd in de debugger.

Hoe stel ik de Arduino in?

Upload de schets van het GIT-archief naar de Arduino en sluit de Arduino als volgt aan op de breadboard-computer:

  • Arduino 5V-pin (niet Vin!) naar 5V rail op het breadboard
  • Arduino GND-pin naar GND-pin op het breadboard
  • Arduino digitale pinnen 2-9 naar bus 0-7
  • Arduino digitale pin 10 om logische EEPROM-uitgang te besturen die RO bestuurt
  • Arduino digitale pin 11 om logische EEPROM-uitgang te besturen die RI bestuurt
  • Arduino digitale pin 12 om logische EEPROM-uitgang te besturen die MI bestuurt
  • Arduino analoge pin 0 naar KLOK-signaal
  • Arduino analoge pin 3 naar CE (pin 18) van alle besturingslogica EEPROM's en via een 10k weerstand naar +5v

Afgezien daarvan moet je de analoge 1 en analoge 2 ingangspinnen van de Arduino aansluiten op de DIP-schakelaars en drukknoppen zoals weergegeven in het schema (zie voor meer details het bijgevoegde Fritzing-bestand).

Voor een absoluut minimale (maar nog steeds functionele) versie kunt u het volgende doen:

  • Voeg 3.3kOhm pull-down weerstanden toe aan de EEPROM-uitgangspinnen die AO, CO, EO, IO, RO besturen
  • Sla de bovenstaande instructies voor "Belteller resetten" over
  • Doe de bedrading van de Arduino naar de breadboard-computer zoals hierboven weergegeven (je kunt de 10k-weerstand in de laatste stap weglaten als je wilt)
  • Verbind zowel analoge pin 1 als analoge pin 2 met GND

Om de load/save-knoppen te gebruiken, hoeft u alleen maar de knoppen, DIP-switches en bijbehorende weerstanden aan te sluiten op analoge pin 1 en 2 volgens het schema.

Om de autostart-functie te gebruiken, moet de Arduino de programmateller op en de belteller op 0 houden tijdens het resetten en terwijl het programma wordt overgedragen. De pull-up weerstand tussen analoge pin 3 en +5V houdt de besturingslogica uitgeschakeld (en dus de programmateller op 0) terwijl de Arduino reset. Volg voor de belteller de bovenstaande instructies voor "Belteller resetten".

Hoe kan ik programma's laden en opslaan?

Met de minimale setup hierboven kun je de Arduino bedienen via de seriële interface. Om met de Arduino te communiceren heb je een terminalprogramma nodig zoals Putty of TeraTerm. De seriële monitor in de Arduino-software zal ook werken, maar de scheiding tussen invoer- en uitvoergebied in de seriële monitor maakt het een beetje onhandig in dit scenario.

  • Zet de breadboard-computer aan
  • Sluit een pc aan op de Arduino via de USB-kabel
  • Start het terminalprogramma en configureer naar 9600 baud, 8 bits, geen pariteit, 1 stopbit
  • Druk op ESC in het terminalvenster om de monitormodus te openen
  • Je zou een "." moeten zien. als een opdrachtprompt
  • Typ "h" en druk op enter om een ​​lijst met ondersteunde opdrachten te krijgen

Met de minimale setup zou je de commando's "m", "M", "C", "l" en "s" moeten kunnen gebruiken. Hiermee kunt u de geheugeninhoud zien, de geheugeninhoud wijzigen en programma's laden en opslaan.

Om een ​​programma op te slaan of te laden via de knop:

  • Zet de klok van de breadboard-computer uit
  • Stel de DIP-schakelaars in om het bestandsnummer te selecteren waaronder de gegevens moeten worden opgeslagen.
  • Druk op de knop "opslaan" of "laden". De LED die op CE is aangesloten, gaat branden, wat aangeeft dat de Arduino de controle heeft overgenomen
  • Zet de klok van de breadboard-computer aan. Je zou de Arduino door de adressen moeten zien fietsen (let op de LED's van het geheugenadresregister)
  • Wacht tot de bus-LED's stoppen met knipperen en de LED's van het geheugenadresregister en 1111 weergeven
  • Zet de klok van de breadboard-computer uit. De LED die is aangesloten op CE gaat uit, wat aangeeft dat de besturing is teruggekeerd naar de besturingslogica

Om een ​​programma automatisch uit te voeren bij het opstarten (zorg ervoor dat alle benodigde circuits aanwezig zijn), zet u de DIP-schakelaars op het bestandsnummer waaronder het programma is opgeslagen en zet u de breadboard-computer aan (of drukt u op de reset-knop). Er zijn twee speciale gevallen:Als alle DIP-schakelaars uit staan, start de computer regelmatig op, zonder autostart. Als alle DIP-schakelaars zijn ingeschakeld, gaat de Arduino direct bij het opstarten naar de monitormodus.

Hoe gebruik ik de assembler en de disassembler?

Om de assembler/disassembler- en debugger-functies te gebruiken, moet u eerst het programma op de Arduino aanpassen aan uw specifieke setup. Zoek de sectie in de broncode die de opcodes_4bit-structuur definieert:

struct opcodes_struct opcodes_4bit [] ={ {"NOP ", B00000000, 0, false}, {"LDA ", B00010000, 2, true}, ... {".OR ", B11111110, 0, true}, // stel startadres in {".BY ", B11111111, 0, true}, // definieer één byte aan gegevens {NULL, 0, 0, false} }; 

Elke regel specificeert één opcode:

  • Het eerste veld is het geheugensteuntje ("LDA"). Voeg voor onmiddellijke adressering een "#" toe aan het geheugensteuntje. Dus wat Ben "LDI" noemt, wordt hier "LDA #" genoemd. Kun je zien dat ik ben opgegroeid met het programmeren van 6510 assembler op een C64?
  • Het tweede veld is de opcode zelf. De onderste vier bits moeten altijd 0 zijn. (behalve de speciale opcodes .OR en .BY, zie hieronder)
  • Derde veld is het aantal cycli dat de opcode nodig heeft om uit te voeren (dit komt bovenop de ophaalcycli). In mijn implementatie heeft LDA bijvoorbeeld opcode 0001 en duurt het in totaal vier cycli om uit te voeren, waarvan twee de ophaalcyclus. Als je Ben's instructies hebt gevolgd (waar alle opcodes 5 cycli gebruiken), dan zou dit altijd 3 moeten zijn.
  • Laatste veld specificeert of deze opcode een argument vereist. LDA vereist bijvoorbeeld een argument, maar OUT niet.

U moet deze lijst aanpassen aan de opcodes die u voor uw breadboard-computer hebt geïmplementeerd. De laatste twee regels zijn speciale opcodes die door de assembler worden gebruikt en moeten worden gelaten zoals ze zijn.

Nadat je al je opcodes hebt ingevoerd, upload je de software naar de Arduino. Sluit uw terminal aan en ga naar de monitormodus (door op ESC te drukken in het terminalvenster of door alle DIP-schakelaars aan te zetten). U zou nu uw programma moeten kunnen demonteren. Als u gewoon "d" in de monitor typt, begint het demonteren op adres 0.

De assembler is minimaal maar werkt redelijk goed. Typ "a" om te beginnen met monteren op adres 0. Conventies zijn:

  • Als een regel niet begint met een spatie, moet deze beginnen met een labeldefinitie. Labels moeten beginnen met een alfabetisch teken gevolgd door alfanumerieke tekens, mogen maximaal 3 tekens lang zijn en zijn hoofdlettergevoelig.
  • Na de eerste witruimte in een regel verwacht de assembler een geheugensteuntje (LDA, STA, OUT...).
  • Speciale geheugensteun ".BY" specificeert direct een databyte die op de huidige locatie moet worden opgeslagen.
  • Speciale geheugensteun ".OR" vertelt de assembler om door te gaan met monteren op een nieuw adres.
  • Als een argument begint met een alfabetisch teken, wordt aangenomen dat het een label is.
  • Elk numeriek argument is naar verwachting een decimaal getal. Om hexadecimaal op te geven, laat u het argument voorafgaan door een "$". Om bijvoorbeeld een hexadecimaal FF-nummer in het A-register te laden, gebruikt u "LDA #$FF".
  • Alles na een ";" wordt verondersteld een opmerking te zijn en wordt genegeerd.

De Fibonacci-code kan bijvoorbeeld als volgt worden ingevoerd:

eerste LDA #0; x =0 STA x LDA #1; y =1 STA y lp TOEVOEGEN x; z =y + x STA z JC eerste; herstart als overloop OUT; print z LDA y; x =ySTA x LDA z; y =z STA y JMP lp; lus x .BY 0 y .BY 0 z .BY 0  

Wat zijn de beperkingen?

Om RAM-ruimte op de Arduino te besparen, werkt de assembler als een 1-pass assembler (anders zou de Arduino alle broncode moeten bufferen). De assembler schrijft de opcodes naar het geheugen van de breadboard-computer als ze worden ingevoerd. Dit betekent dat de montage wordt vertraagd door de kloksnelheid van de breadboard-computer. Als u tekst in het terminalvenster kopieert en plakt, kan dat leiden tot verloren tekens, aangezien de Arduino de tekens die binnenkomen met 9600 baud niet kan bijhouden (omdat hij te veel tijd besteedt aan het wachten op de klok van de breadboard-computer). Om dit te omzeilen, verlaagt u de baudrate of gebruikt u TeraTerm, die een instelling biedt om een ​​vertraging tussen verzonden tekens op te geven. De andere oplossing is om de kloksnelheid op de breadboard-computer te verhogen. Mijn klok gaat tot 160 kHz en met die snelheid kan ik zonder problemen code kopiëren en plakken op 9600 baud.

In de standaardconfiguratie kan de Arduino-schets klokfrequenties op de breadboard-computer aan tot ongeveer 1-2 kHz (misschien een beetje meer). Merk op dat de klok van Ben in de standaardconfiguratie niet sneller gaat dan 500 Hz. Als je klok sneller is, zoek dan naar de #ifdef FAST_IO schakel de code in. Als u FAST_IO inschakelt, zou de Arduino moeten werken met kloksnelheden tot 250 kHz. Ik heb het getest tot 160 kHz. Het zou waarschijnlijk mogelijk zijn om hogere snelheden te ondersteunen door de tijdkritische lussen direct in assembler te implementeren, maar eerlijk gezegd voelt een 160 kHz kloksnelheid al te snel aan op de breadboard-computer met zijn anders beperkte mogelijkheden. Zorg ervoor dat u de bijbehorende opmerkingen in de code leest voordat u FAST_IO inschakelt.

De Arduino heeft 1k EEPROM en kan daarom 1024/16=64 verschillende programma's bevatten. Eigenlijk is het 63 omdat er 16 bytes zijn gereserveerd om configuratiegegevens op te slaan. Dat is niet veel, maar waarschijnlijk genoeg voor alle programma's die je kunt bedenken. Alleen de programma's nummer 0-15 daarvan kunnen worden geselecteerd via de dipswitches (1-14 voor autostart), maar de commando's "s" en "l" werken met het volledige bereik van 0-62.

Het ziet er een beetje rommelig uit. Kun je het opknappen?

Ja! In mijn definitieve versie hier heb ik eigenlijk gewoon de kale Atmega 328P-chip gebruikt (samen met een 16MHz-kristal en condensatoren) in plaats van een Arduino UNO. De spanningsregelaar op de UNO is hier niet nodig omdat de Arduino toch direct de 5V van onze voeding gebruikt. Het enige verlies is dat we nu een aparte USB-naar-serieel converter (FTDI of iets dergelijks) moeten gebruiken om met de Atmega te praten. Het algehele uiterlijk daarvan past veel beter bij de rest van de breadboard-computer:

Een andere optimalisatie is het verwijderen van de bootloader van de Arduino/Atmega. Dat haalt de vertraging van 2 seconden weg terwijl de Arduino-bootloader opstart. Ik zal instructies plaatsen over hoe dat te doen als mensen geïnteresseerd zijn. Laat het me weten in de reacties!

Code

Programmer van broodplankcomputer
De Arduino-schets voor de Breadboard Computer Programmerhttps://github.com/dhansel/programmer

Schema's

drive_pD8k28E85v.fzz

Productieproces

  1. Computermuis
  2. Een effect besturen met echte sensoren
  3. Arduino Spybot
  4. FlickMote
  5. Zelfgemaakte tv B-Gone
  6. Hoofdklok
  7. Vind mij
  8. Arduino Power
  9. Tech-TicTacToe
  10. Arduino Quadruped
  11. ThingSpeak Arduino-weerstation