First proto using the 82C54 CMOS Programmable Interval Timer

Just now I finished the first prototype using one counter on the 82C54 programmable 16-bit interval timer. This timer divides the masterclock by a programmable 16-bit integer (0-65535). When dividing a crystal masterclock, a very stable and precise pulse waveform can be achieved.

For possible future reference:

The Arduino programming sequence:

All following pins low

A0A1 -> 11 (select control word register)
WR -> 0  (enable CPU write operation)
D0 - D7 control word (send control word (page 8 datasheet)
WR -> 1 (disable CPU write)

A0A1 -> 00 (select counter 0)
WR -> 0 
D0 - D7 LSB (send LSB)
WR -> 1 
WR -> 0 
D0 - D7 MSB (send MSB)
WR -> 1

and the test code:

int incomingByte = 0;    // for incoming serial data
int statusled = 13;

// key sequence 32415241241

void setup() {
    Serial.begin(9600);

    setup4Mhz();
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  digitalWrite(8, LOW);

  // init done, statusled high
  digitalWrite(statusled,HIGH);

}

void loop() {
if(Serial.available() > 0)
      {
        incomingByte = Serial.read();
        if (incomingByte == 49) {  // 1
          Serial.println("2 high");
          digitalWrite(2, HIGH);
        }
        if (incomingByte == 50) {  // 2
          Serial.println("2 low");
          digitalWrite(2, LOW);
        }
        if (incomingByte == 51) {  // 3
          Serial.println("A0A1 -> 1");
          digitalWrite(3, HIGH);
          digitalWrite(4, HIGH);
        }
        if (incomingByte == 52) {  // 4
          Serial.println("D5 D4 D2 D1 -> 1");
          digitalWrite(5, HIGH);
          digitalWrite(6, HIGH);
          digitalWrite(7, HIGH);
          digitalWrite(8, HIGH);
        }
        if (incomingByte == 53) {  // 5
          Serial.println("A0A1 -> 0");
          digitalWrite(3, LOW);
          digitalWrite(4, LOW);
        }
        if (incomingByte == 54) {  // 6
          Serial.println("D5 D4 D2 D1 -> 0");
          digitalWrite(5, LOW);
          digitalWrite(6, LOW);
          digitalWrite(7, LOW);
          digitalWrite(8, LOW);
        }
      }
}

// not required because we're using a separate crystal oscillator
void setup4Mhz() {
    pinMode(9, OUTPUT);

  // Timer/Counter 1 :: registers TCCR1A and TCCR1B

  // Clear Timer on Compare Match (CTC) Mode
  bitWrite(TCCR1A, WGM10, 0);
  bitWrite(TCCR1A, WGM11, 0);
  bitWrite(TCCR1B, WGM12, 1);
  bitWrite(TCCR1B, WGM13, 0);

  // Toggle OC1A on Compare Match. p.134
  // arduino hw pin 9
  bitWrite(TCCR1A, COM1A0, 1);
  bitWrite(TCCR1A, COM1A1, 0);

  // prescaling *1
  bitWrite(TCCR1B, CS10, 1);
  bitWrite(TCCR1B, CS11, 0);
  bitWrite(TCCR1B, CS12, 0);

  OCR1A = 1;
}