Lectura secuencial de una EEPROM 93c66

Este es mi programa que lee sólo a 8 bits todas las posiciones de memoria que desee e incluso desde un rango.

/*
Este programa lee desde una posicion de inicio especificada
por el usuario y la cantidad de posiciones adicionales a leer.
La variable alcance determina cuantos bytes va a leer y por tanto
cuantas posiciones avanza desde el inicio. Si queremos leer 15
posiciones desde la posicion 0, pondremos un 0 en inicio y 15 
en alcance.
*/
const int CS=5;
const int DI=3;
const int DO=2;
const int CLK=4;
const byte OPcode_Lectura=B00000010;

byte Buffer;


void setup()
{
  pinMode(CS, OUTPUT);//Pin CS como salida
  pinMode(DI, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(DO, INPUT);// Pin DO como entrada
  Serial.begin(9600);//Velocidad de conexion terminal
  //condicion de inicio
  digitalWrite(CS, LOW);//Desconectamos la memoria
  digitalWrite(DI, LOW);//Ponemos este pin a cero
  digitalWrite(CLK, LOW);// Reloj a cero
  delayMicroseconds(1);
   }

void startBit()
{
  digitalWrite(CS, LOW);//condicion de inicio
    delayMicroseconds(1);
    digitalWrite(CLK, LOW);
    digitalWrite(DI, LOW);
    digitalWrite(CS, HIGH);
    delayMicroseconds(1);
    digitalWrite(DI, HIGH);
    delayMicroseconds(1);
    digitalWrite(CLK, HIGH);//Flanco de subida de reloj
    delayMicroseconds(1);//Se ha escrito el bit SB
    digitalWrite(CLK,LOW);
    delayMicroseconds(1);
    
}
/*Esta funcion permite escribir cualquier numero de bits
 * especificado por la variable contador. La variable dato, 
 * será leida por una especie de puntero que apunta a la 
 * posicion del bit que queremos leer de la variable dato. Algo
 * así como un registro de desplazamiento pero con la ventaja de
 * que podemos elegir la posición del bit que quermos leer y luego
 * transmitir a la linea DI de la EEPROM.
 * Aquí recibe dos tipos de datos, uno es el OP de lectura que 
 * lleva 2 bits y otro es la dirección que lleva 9 bits.
 */
void escribe(int dato,byte contador)
  {
    Serial.print("Dato Recibido: ");
    Serial.println(dato);
    Serial.print("contador recibido: ");
    Serial.println(contador);
    
    while(contador>0)//repite el ciclo tantas veces
    {
    delayMicroseconds(1);
    digitalWrite(DI, bitRead(dato,(contador-1))); //Posicionamos el bit a leer de dato y lo copiamos a DI
   
    delayMicroseconds(1);
    digitalWrite(CLK, HIGH);
    delayMicroseconds(1);
    digitalWrite(CLK,LOW);
    delayMicroseconds(1);
    contador--;//necesario para el ciclo se repita
    }
   digitalWrite(DI,LOW);
  }

void leeMemoria()//solo para 8 bits de datos
{
    Buffer=0;//limpia el Buffer
    digitalWrite(CLK,LOW);
    Buffer=shiftIn(DO,CLK,MSBFIRST);
/*
Esta funcion obtiene el dato por DO, utiliza como reloj CLk
y se recepciona primero el MSB desde la memoria. El resultado
es un byte que se almacena en una variable tipo byte que he 
llamado Buffer.
*/
   
    Serial.print("Dato leido en Buffer: ");
    Serial.println(Buffer);
    delayMicroseconds(1);
 }

void leeAutomatico(int inicio, int alcance)
{
  int direccion=inicio;
  startBit();//condicion de inicio CS,DI y CLK A 1
  escribe(OPcode_Lectura,2);//mandamos el codigo op que es de 2 bits
  Serial.println("Mandamos la direccion");
  escribe(direccion,9);//9 bits de direccion
  if (alcance>direccion)
  {
   while(direccion<=alcance)//Tope de dirección a leer ( el máximo)
    {
      leeMemoria();
      delay(10);
      digitalWrite(CLK,LOW);
      delayMicroseconds(1);
      digitalWrite(DI,LOW);
      Serial.print("Direccion leida: ");
      Serial.println(direccion);
      direccion++;
    }
  }
  else 
  {
    Serial.println("ERROR.Alcance debe ser mayor que inicio. Se imprime solo inicio");
  leeMemoria();
  delay(10);
  digitalWrite(CLK,LOW);
  delayMicroseconds(1);
  digitalWrite(DI,LOW);
  Serial.print("Direccion leida: ");
  Serial.println(direccion);
  }
}

void loop()
{
  Serial.println("");
  Serial.println("Inicio del programa");
  int inicio=0;//Direccion de inicio de la lectura.
  int alcance=511;//POsicion final.DEBE SER MAYOR QUE inicio.
  //El numero maximo es 511 ya que la memoria no tiene mas capa
  //cidad por lo que si pasamos de este valor, volemos al 
  //principio.
  leeAutomatico(inicio,alcance);
  digitalWrite(CS, LOW);
  delayMicroseconds(1); 
  Serial.println("Fin del programa");
}

Me gustaria optimizarlo más pero tampoco me gustan los programas con directivas dificiles de entender para un electronico como yo.

Hola.
Estas eeprom son SPI, ¿no?
Si es así, por ahí tienes bastante terreno para optimizar.
Luego habría que ver qué entiendes por "directivas difíciles", porque habría que ponderar dificultad vs utilidad.

No son spi, son microwire. La microwire usan DI como dato entrada, DO como dato salida, CS para habiltar el chip y para programarlo, luego usa CLK para sincronizar. SPI usa MOSI, MISO y desconozco si dichas señales son compatibles con la memoria MICROWIRE en cuento a nivel de señal y de velocidad. Pero tampoco creo que sea muy diferente y creo que puedo conectarla a MISO, MOSI, SEÑAL DE RELOJ, HABILITACION DEL CHIP ( creo que este ultimo está invertido).

No es exactamente tu memoria pero explica la idea

Algo que ayuda a entender mejor las cosas. MICROWIRE es un subconjunto del SPI

MICROWIRE is a 3Mbps [full-duplex] serial 3-wire interface standard defined by National Semiconductor. The MICROWIRE protocol is essentially a subset of the SPI interface, CPOL = 0 and CPHA = 0.

Microwire is a serial I/O port on microcontrollers, so the Microwire bus will also be found on EEPROMs and other Peripheral chips. The 3 lines are: SI, the serial input line to the microcontroller, SO is the serial output line, and SK is the serial clock line. Data is shifted out on the falling edge of SK, and is valued on the rising edge. SI is shifted in on the rising edge of SK. In some cases a 4.7k W pull-up resistor may be used to increase the low-to-high rise time. The voltage level and swings is based on the microcontroller's I/O voltage, normally TTL. The protocol is a '1' state bit followed by a variable length instruction/address word, followed by a variable length data field. Or the device may send no start bit, just a variable length bit stream. The minimum clock cycle time is 2uS, 1uS high and 1uS low. The clock speed is dependent on the microcontroller, typical speeds are 0Hz to 250kHz.

An additional bus enhancement to MICROWIRE is called MICROWIRE/Plus. The main difference between the two buses seems to be that MICROWIRE/Plus architecture within the microcontroller is more complex.