Arduino: ColecoVision patron läsare (8 / 13 steg)
Steg 8: Arduino skiss fil
Den följande Arduino skiss filen orsakar Arduino att vänta på en linje från värddatorn. Om raden läser i "Läsa alla", kommer att Arduino göra följande:
- Skicka en "START:" linje till värddatorn.
- Läsa alla data från patronen och skicka den till värddatorn i HEX, en byte per rad.
- Skicka en ": slutet" linje till värddatorn.
När patronen data har skickats till värddatorn, är Arduino redo för sin nästa kommando från värddatorn.
ColecoVision / ADAM Cartridge läsare
för Arduino UNO
2014-11-25
//----------------------------------------------------------------------------------
Arduino Pins
CONST int gcChipSelectLine [4] = {A0, A1, A2, A3};
CONST int gcShiftRegisterClock = 11;
CONST int gcStorageRegisterClock = 12;
CONST int gcSerialAddress = 10;
CONST int gcDataBit [8] = {2, 3, 4, 5, 6, 7, 8, 9};
Skiftar ett 16-bitarsvärde ut till ett skiftregister.
Parametrar:
dataPin - Arduino Pin ansluten till skiftregister data stift.
clockPin - Arduino Pin ansluten till data klocka stift skiftregister.
//----------------------------------------------------------------------------------
void shiftOut16 (int dataPin, int clockPin, int bitOrder, int värde)
{
Flytta ut highbyte för MSBFIRST
shiftOut (dataPin, clockPin, bitOrder, (bitOrder == MSBFIRST? (värde >> 8): värde));
flytta ut lowbyte för MSBFIRST
shiftOut (dataPin, clockPin, bitOrder, (bitOrder == MSBFIRST? värde: (värde >> 8)));
}
Välj vilka chipet på patronen att läsa (låg = aktiv).
Använd -1 för att ange alla chip Välj rader hög.
//----------------------------------------------------------------------------------
void SelectChip(byte chipToSelect)
{
för (int currentChipLine = 0; currentChipLine < 4; currentChipLine ++)
{
digitalWrite (gcChipSelectLine [currentChipLine], (chipToSelect! = currentChipLine));
}
}
Ange adress linjer
//----------------------------------------------------------------------------------
void SetAddress (unsigned int adress)
{
SelectChip(-1);
Avaktivera SKIFT register utgång fördriva tiden lastande adress
digitalWrite (gcStorageRegisterClock, låg);
Skriva ut adressen
shiftOut16 (gcSerialAddress, gcShiftRegisterClock, MSBFIRST, adress);
Aktivera SKIFT register utgång
digitalWrite (gcStorageRegisterClock, hög);
int chipToSelect;
om (adress < 0xA000) {
chipToSelect = 0;
} else om (adress < 0xC000) {
chipToSelect = 1;
} else om (adress < 0xE000) {
chipToSelect = 2;
} annat {
chipToSelect = 3;
}
SelectChip(chipToSelect);
}
Läsa data linjer
//----------------------------------------------------------------------------------
void ReadDataLines()
{
CONST char cHexLookup [16] = {
'0', '1', '2', '3', '4', '5', ' 6', ' 7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
int highNibble = 0;
int lowNibble = 0;
booleska dataBits [8].
char byteReadHex [4].
för (int currentBit = 0; currentBit < 8; currentBit ++)
{
dataBits [currentBit] = digitalRead(gcDataBit[currentBit]);
}
highNibble = (dataBits [7] << 3) + (dataBits [6] << 2) + (dataBits [5] << 1) + dataBits [4].
lowNibble = (dataBits [3] << 3) + (dataBits [2] << 2) + (dataBits [1] << 1) + dataBits [0];
Serial.write(cHexLookup[highNibble]);
Serial.write(cHexLookup[lowNibble]);
Serial.println();
}
Läsa alla data från kassetten.
//----------------------------------------------------------------------------------
void ReadCartridge()
{
unsigned int baseAddress = 0x8000;
Serial.println("start:");
Läs aktuella Chip (patronen är 32K, varje chip är 8k)
för (unsigned int currentAddress = 0; currentAddress < 0x8000; currentAddress ++)
{
SetAddress (baseAddress + currentAddress);
ReadDataLines();
}
Serial.println(":end");
}
Returnerar nästa rad från den seriella porten som en sträng.
//----------------------------------------------------------------------------------
Sträng SerialReadLine()
{
CONST int BUFFER_SIZE = 81.
char lineBuffer [BUFFER_SIZE];
int aktuellaposition = 0;
int currentValue;
göra
{
Läs tills vi får nästa tecken
göra
{
currentValue = Serial.read();
} medan (currentValue == -1);
Ignorera '\r' tecken
om (currentValue! = '\r')
{
lineBuffer [aktuellaposition] = currentValue;
aktuellaposition ++;
}
} medan ((currentValue! = "\n") & & (aktuellaposition < BUFFER_SIZE));
lineBuffer [aktuellaposition-1] = 0;
återvända String(lineBuffer);
}
Tyder på fjärrdatorn Arduino är redo för nästa kommando.
//----------------------------------------------------------------------------------
void ReadyForCommand()
{
Serial.println("Ready:");
}
void setup()
{
Setup Serial Monitor
Serial.BEGIN(57600);
Setup Chip Välj stift
för (int chipLine = 0; chipLine < 4; chipLine ++)
{
pinMode (gcChipSelectLine [chipLine], produktionen);
}
Setup seriell adress Pins
pinMode (gcShiftRegisterClock, produktionen);
pinMode (gcStorageRegisterClock, produktionen);
pinMode (gcSerialAddress, produktionen);
Setup Data stift
för (int currentBit = 0; currentBit < 8; currentBit ++)
{
pinMode (gcDataBit [currentBit], INPUT_PULLUP);
}
tag (!. Serial) {
; vänta för seriell port att ansluta. Behövs för Leonardo endast.
}
Återställ utdatarader
SetAddress(0);
ReadyForCommand();
}
void loop()
{
om (Serial.available() > 0)
{
String lineRead = SerialReadLine();
lineRead.toUpperCase();
om (lineRead == "Läsa alla")
{
ReadCartridge();
} / / lineRead = "Läs alla"
ReadyForCommand();
} / / Serial.available
}
Om du har tur nog att använda en Arduino ombord med 29 eller mer digitala I/O stift (t.ex. den Arduino Due, Arduino MEGA ADK, Arduino Mega 2560, etc.) och du inte använder SKIFT register krets, funktionen SetAddress i filen skiss ovan kommer att behöva skrivas igen.