Tutorial.SPIEEPROM History

Hide minor edits - Show changes to markup

June 08, 2010, at 06:08 PM by Equipo Traduccion -
Changed lines 37-38 from:

Los registros de estado cambian su estado basándose en varias condiciones del microcontrolador. Por ejemplo, el septimo bit del registro de estado del SPI se pone en 1 cuando un valor es desplazado dentro o fuera del SPI.

to:

Los registros de estado cambian su estado basándose en varias condiciones del microcontrolador. Por ejemplo, el séptimo bit del registro de estado del SPI se pone en 1 cuando un valor es desplazado dentro o fuera del SPI.

Changed line 45 from:

SPIE - Permine la interrupción del SPI cuando es 1.

to:

SPIE - Permite la interrupción del SPI cuando es 1.

Changed line 106 from:

Aquí ubicamos las variables glovales que mas adelante usaremos en el programa.

to:

Aquí ubicamos las variables globales que mas adelante usaremos en el programa.

Changed lines 117-118 from:

Primero inicializamos la comunicación serie, establecemos nuestros pines de entrada o salida y fijamos SLAVESELECT en nivel alto para comenzar. Esto inhavilita el dispositivo e impide cualquier transmisión falsa debida a ruido en los cables:

to:

Primero inicializamos la comunicación serie, establecemos nuestros pines de entrada o salida y fijamos SLAVESELECT en nivel alto para comenzar. Esto inhabilita el dispositivo e impide cualquier transmisión falsa debida a ruido en los cables:

Changed lines 143-144 from:

Aquí llenaremos nuestra matriz con números y enviaremos una instrucción que permita la escritura en la EEPROM. La EEPROM debe tener la escritura habilitada antes de enviar ninguna instrucción de escritura. Para enviar la instrucción ponemos la linea SLAVESELECT (SS) en estado bajo, seleccionando el dispositivo, y despues enviamos la instrucción utilizando la función spi_transfer(). Al utilizar el opcode WREN estamos definiendo el comienzo del programa. Finalmente devolvemos la linea SLAVESELECT a estado alto para liberarlo.

to:

Aquí llenaremos nuestra matriz con números y enviaremos una instrucción que permita la escritura en la EEPROM. La EEPROM debe tener la escritura habilitada antes de enviar ninguna instrucción de escritura. Para enviar la instrucción ponemos la linea SLAVESELECT (SS) en estado bajo, seleccionando el dispositivo, y después enviamos la instrucción utilizando la función spi_transfer(). Al utilizar el opcode WREN estamos definiendo el comienzo del programa. Finalmente devolvemos la linea SLAVESELECT a estado alto para liberarlo.

Changed lines 180-181 from:

En nuestro bloque loop() tan solo leeremos uno por uno los bytes de la EEPROM y los escribiremos a través del puerto serie. Podemos añadir un retorno de carro y una pausa por motivos de legivilidad. Cada vez que se ejecute el bucle incrementaremos la dirección a leer. Cuando la dirección llegue al valor 128 la pondremos a 0 por que solo hemos llenado 128 direcciones en la EEPROM con datos.

to:

En nuestro bloque loop() tan solo leeremos uno por uno los bytes de la EEPROM y los escribiremos a través del puerto serie. Podemos añadir un retorno de carro y una pausa por motivos de legibilidad. Cada vez que se ejecute el bucle incrementaremos la dirección a leer. Cuando la dirección llegue al valor 128 la pondremos a 0 por que solo hemos llenado 128 direcciones en la EEPROM con datos.

Changed lines 215-216 from:

La función read_eeprom nos permite leer los datos devueltos por la EEPROM. Primero debemos poner en estado bajo la línea SLAVESELECT para seleccionar el dispositivo. Luego transmitimos una instrucción READ, seguida por la dirección de 16 bits (Most Significant Bit first) que queremos leer. Lo siguiente es enviar un byte falso a la EEPROM con el propósito de desplazar el dato fuera. Finalmente ponemos la línea SLAVESELECT en estado alto para liberar el dispositivo después de leer un byte y retornar el dato. Si queremos leer multiples bytes al mismo tiempo podemos mantener la línea SLAVESELECT en estado bajo mientras repetimos la data = spi_transfer(0xFF); hasta 128 veces por cada página completa de datos.

to:

La función read_eeprom nos permite leer los datos devueltos por la EEPROM. Primero debemos poner en estado bajo la línea SLAVESELECT para seleccionar el dispositivo. Luego transmitimos una instrucción READ, seguida por la dirección de 16 bits (Most Significant Bit first) que queremos leer. Lo siguiente es enviar un byte falso a la EEPROM con el propósito de desplazar el dato fuera. Finalmente ponemos la línea SLAVESELECT en estado alto para liberar el dispositivo después de leer un byte y retornar el dato. Si queremos leer múltiples bytes al mismo tiempo podemos mantener la línea SLAVESELECT en estado bajo mientras repetimos la data = spi_transfer(0xFF); hasta 128 veces por cada página completa de datos.

June 08, 2010, at 06:06 PM by Equipo Traduccion -
Changed lines 171-172 from:

We end the setup function by sending the word "hi" plus a line feed out the built in serial port for debugging purposes. This way if our data comes out looking funny later on we can tell it isn't just the serial port acting up:

to:

Terminamos la función de setup() enviando la palabra "hi" más un retorno de carro por el puerto serie para corrección de errores.

Changed lines 180-182 from:

In our main loop we just read one byte at a time from the EEPROM and print it out the serial port. We add a line feed and a pause for readability. Each time through the loop we increment the eeprom address to read. When the address increments to 128 we turn it back to 0 because we have only filled 128 addresses in the EEPROM with data:

to:

En nuestro bloque loop() tan solo leeremos uno por uno los bytes de la EEPROM y los escribiremos a través del puerto serie. Podemos añadir un retorno de carro y una pausa por motivos de legivilidad. Cada vez que se ejecute el bucle incrementaremos la dirección a leer. Cuando la dirección llegue al valor 128 la pondremos a 0 por que solo hemos llenado 128 direcciones en la EEPROM con datos.

Changed lines 191-192 from:

The fill_buffer function simply fills our data array with numbers 0 - 127 for each index in the array. This function could easily be changed to fill the array with data relevant to your application:

to:

La función fill_buffer simplemente llena nuestra matriz de datos con números del 0 al 127, uno para cada índice de la matriz. Esta función puede ser fácilmente modificada para llenar la matriz con datos que sean relevantes a tus aplicaciones.

Changed lines 203-204 from:

The spi_transfer function loads the output data into the data transmission register, thus starting the SPI transmission. It polls a bit to the SPI Status register (SPSR) to detect when the transmission is complete using a bit mask, SPIF. An explanation of bit masks can be found here. It then returns any data that has been shifted in to the data register by the EEPROM:

to:

La función spi_transfer carga los datos de salida en el registro de transmisión de datos, así empieza la transmisión SPI. Sondeando un bit en el registro de estado del SPI (SPSR) para detectar cuando la transmisión se ha completado usando una máscara de bit, SPIF. Una explicación más profunda de lo que son las máscaras de bits se puede encontrar aquí. Esta retorna los datos que han sido desplazados en el registro de datos por la EEPROM.

Changed lines 215-216 from:

The read_eeprom function allows us to read data back out of the EEPROM. First we set the SLAVESELECT line low to enable the device. Then we transmit a READ instruction, followed by the 16-bit address we wish to read from, Most Significant Bit first. Next we send a dummy byte to the EEPROM for the purpose of shifting the data out. Finally we pull the SLAVESELECT line high again to release the device after reading one byte, and return the data. If we wanted to read multiple bytes at a time we could hold the SLAVESELECT line low while we repeated the data = spi_transfer(0xFF); up to 128 times for a full page of data:

to:

La función read_eeprom nos permite leer los datos devueltos por la EEPROM. Primero debemos poner en estado bajo la línea SLAVESELECT para seleccionar el dispositivo. Luego transmitimos una instrucción READ, seguida por la dirección de 16 bits (Most Significant Bit first) que queremos leer. Lo siguiente es enviar un byte falso a la EEPROM con el propósito de desplazar el dato fuera. Finalmente ponemos la línea SLAVESELECT en estado alto para liberar el dispositivo después de leer un byte y retornar el dato. Si queremos leer multiples bytes al mismo tiempo podemos mantener la línea SLAVESELECT en estado bajo mientras repetimos la data = spi_transfer(0xFF); hasta 128 veces por cada página completa de datos.

Changed lines 232-233 from:

For easy copy and pasting the full program text of this tutorial is below:

to:

Para un más fácil copiado y pegado aquí viene el sketch completo:

Changed line 343 from:

code and tutorial by Heather Dewey-Hagborg, photos by Thomas Dexter

to:

código y tutorial por Dewey-Hagborg, fotos por Thomas Dexter

June 08, 2010, at 05:13 PM by Equipo Traduccion -
Changed lines 143-145 from:

Here we fill our data array with numbers and send a write enable instruction to the EEPROM. The EEPROM MUST be write enabled before every write instruction. To send the instruction we pull the SLAVESELECT line low, enabling the device, and then send the instruction using the spi_transfer function. Note that we use the WREN opcode we defined at the beginning of the program. Finally we pull the SLAVESELECT line high again to release it:

to:

Aquí llenaremos nuestra matriz con números y enviaremos una instrucción que permita la escritura en la EEPROM. La EEPROM debe tener la escritura habilitada antes de enviar ninguna instrucción de escritura. Para enviar la instrucción ponemos la linea SLAVESELECT (SS) en estado bajo, seleccionando el dispositivo, y despues enviamos la instrucción utilizando la función spi_transfer(). Al utilizar el opcode WREN estamos definiendo el comienzo del programa. Finalmente devolvemos la linea SLAVESELECT a estado alto para liberarlo.

Changed lines 153-154 from:

Now we pull the SLAVESELECT line low to select the device again after a brief delay. We send a WRITE instruction to tell the EEPROM we will be sending data to record into memory. We send the 16 bit address to begin writing at in two bytes, Most Significant Bit first. Next we send our 128 bytes of data from our buffer array, one byte after another without pause. Finally we set the SLAVESELECT pin high to release the device and pause to allow the EEPROM to write the data:

to:

Ahora volvemos a poner la línea SLAVESELECT en estado bajo para volver a seleccionar el dispositivo tras un pequeño retardo. Enviamos una instrucción WRITE para comunicarle a la EEPROM que le vamos a enviar datos que debe guardar en la memoria. Enviamos una dirección de 16 bits en 2 bytes para comenzar la escritura, el bit más significativo primero (Most Significant Bit first). Luego enviaremos los 128 bytes de datos almacenados en nuestra matriz, un byte tras otro sin pausas. Finalmente volveremos a poner el pin SLAVESELECT en estado alto para liberar el dispositivo y haremos una pausa para darle tiempo a la EEPROM a escribir los datos.

June 08, 2010, at 11:59 AM by Equipo Traduccion -
Changed lines 70-71 from:

El dispoditivo esta habilitado cuando su pin Chip Select (CS) esta en nivel bajo. Las instrucciones se envían como códigos operacionales (opcodes) de 8 bits y son desplazados en el borde de subida del pulso de reloj. Esto le lleva a la EEPROM unos 10 milisegundos para escribir una página de datos (128 bytes) por lo que hay que introducir en la rutina de escritura una pausa de 10ms por cada ciclo de escritura.

to:

El dispositivo esta habilitado cuando su pin Chip Select (CS) esta en nivel bajo. Las instrucciones se envían como códigos operacionales (opcodes) de 8 bits y son desplazados en el borde de subida del pulso de reloj. Esto le lleva a la EEPROM unos 10 milisegundos para escribir una página de datos (128 bytes) por lo que hay que introducir en la rutina de escritura una pausa de 10ms por cada ciclo de escritura.

Changed lines 130-134 from:

Ahora establecemos el registro de control SPI (SPCR) con el valor binario 01010000. En el registro de control cada bit tiene una función diferente. El octavo bit deshabilita las interrupciones del SPI, el séptimo habilita el SPI,

the sixth bit chooses transmission with the most significant bit going first, the fifth bit puts the Arduino in Master mode, the fourth bit sets the data clock idle when it is low, the third bit sets the SPI to sample data on the rising edge of the data clock, and the second and first bits set the speed of the SPI to system speed / 4 (the fastest). After setting our control register up we read the SPI status register (SPSR) and data register (SPDR) in to the junk clr variable to clear out any spurious data from past runs:

to:

Ahora establecemos el registro de control SPI (SPCR) con el valor binario 01010000. En el registro de control cada bit tiene una función diferente. El octavo bit deshabilita las interrupciones del SPI, el séptimo habilita el SPI, el sexto bit elige la transmisión del bit más significativo primero, el quinto bit establece la Arduino como maestro, el cuarto señala que el ciclo bajo del reloj es el de reposo, el tercer bit establece el SPI para que muestree datos en el borde de subida de cada ciclo de reloj y el segundo y primer bits fijan la velocidad en 4, el modo más rápido.

Después de definir nuestro registro de control pasamos a leer el registro de estado (SPSR) y el registro de datos (SPDR) con una variable clr que limpiará cualquier dato falso contenido en esos registros.

Added line 143:
June 08, 2010, at 10:50 AM by Equipo Traduccion -
Changed lines 106-107 from:

Here we allocate the global variables we will be using later in the program. Note char buffer [128];. this is a 128 byte array we will be using to store the data for the EEPROM write:

to:

Aquí ubicamos las variables glovales que mas adelante usaremos en el programa. Nota: char buffer [128]; es una matriz de 128 bytes que usaremos para almacenar datos y escribirlos en la EEPROM.

Changed lines 117-118 from:

First we initialize our serial connection, set our input and output pin modes and set the SLAVESELECT line high to start. This deselects the device and avoids any false transmission messages due to line noise:

to:

Primero inicializamos la comunicación serie, establecemos nuestros pines de entrada o salida y fijamos SLAVESELECT en nivel alto para comenzar. Esto inhavilita el dispositivo e impide cualquier transmisión falsa debida a ruido en los cables:

Changed lines 130-132 from:

Now we set the SPI Control register (SPCR) to the binary value 01010000. In the control register each bit sets a different functionality. The eighth bit disables the SPI interrupt, the seventh bit enables the SPI, the sixth bit chooses transmission with the most significant bit going first, the fifth bit puts the Arduino in Master mode, the fourth bit sets the data clock idle when it is low, the third bit sets the SPI to sample data on the rising edge of the data clock, and the second and first bits set the speed of the SPI to system speed / 4 (the fastest).

to:

Ahora establecemos el registro de control SPI (SPCR) con el valor binario 01010000. En el registro de control cada bit tiene una función diferente. El octavo bit deshabilita las interrupciones del SPI, el séptimo habilita el SPI,

the sixth bit chooses transmission with the most significant bit going first, the fifth bit puts the Arduino in Master mode, the fourth bit sets the data clock idle when it is low, the third bit sets the SPI to sample data on the rising edge of the data clock, and the second and first bits set the speed of the SPI to system speed / 4 (the fastest).

June 08, 2010, at 10:38 AM by Equipo Traduccion -
Changed lines 79-81 from:

Connect EEPROM pin 1 to Arduino pin 10 (Slave Select - SS), EEPROM pin 2 to Arduino pin 12 (Master In Slave Out - MISO), EEPROM pin 5 to Arduino pin 11 (Master Out Slave In - MOSI), and EEPROM pin 6 to Arduino pin 13 (Serial Clock - SCK).

to:

Conectamos el pin 1 de la EEPROM al pin 10 de la Arduino (Slave Select - SS), el pin 2 de la EEPROM al pin 12 de la Arduino (Master In Slave Out - MISO), el pin 5 de la EEPROM al pin 11 de la Arduino (Master Out Slave In - MOSI),y por último, el pin 6 de la EEPROM al pin 13 de la Arduino (Serial Clock - SCK).

Changed lines 82-91 from:

SS wire is white, MISO wire is yellow, MOSI wire is blue, SCK wire is green

Program the Arduino

Now we will write the code to enable SPI communication between the EEPROM and the Arduino. In the setup routine this program fills 128 bytes, or one page of the EEPROM with data. In the main loop it reads that data back out, one byte at a time and prints that byte out the built in serial port. We will walk through the code in small sections.

The first step is setting up our pre-processor directives. Pre-processor directives are processed before the actual compilation begins. They start with a "#" and do not end with semi-colons.

We define the pins we will be using for our SPI connection, DATAOUT, DATAIN, SPICLOCK and SLAVESELECT. Then we define our opcodes for the EEPROM. Opcodes are control commands:

to:

El cable SS es blanco, el MISO es amarillo, MOSI azul y SCK en color verde.

Programando la Arduino.

Ahora escribiremos el código para permitir la comunicación SPI entre la EEPROM y nuestra Arduino. En la rutina setup() este programa grabará 128 bytes, o una página, de datos en la EEPROM. En la rutina loop() leeremos los datos, un byte cada vez y enviaremos esta byte por el puerto serie. Iremos comentando el código por pequeñas secciones.

El primer paso es establecer nuestra directivas de pre-procesamiento. Estas directivas se procesan antes de que la compilación comience, cada linea empieza con el carácter # y no necesita terminar con ;.

Definimos los pines que vamos a utilizar para nuestra conexión SPI: DATAOUT, DATAIN, SPICLOCK y SLAVESELECT. Después definiremos nuestros "opcodes" para la EEPROM. Los "opcodes" son comandos de control:

June 08, 2010, at 10:21 AM by Equipo Traduccion -
Changed lines 70-76 from:

The device is enabled by pulling the Chip Select (CS) pin low. Instructions are sent as 8 bit operational codes (opcodes) and are shifted in on the rising edge of the data clock. It takes the EEPROM about 10 milliseconds to write a page (128 bytes) of data, so a 10ms pause should follow each EEPROM write routine.

Prepare the Breadboard

Insert the AT25HP512 chip into the breadboard. Connect 5V power and ground from the breadboard to 5V power and ground from the microcontroller. Connect EEPROM pins 3, 7 and 8 to 5v and pin 4 to ground.

to:

El dispoditivo esta habilitado cuando su pin Chip Select (CS) esta en nivel bajo. Las instrucciones se envían como códigos operacionales (opcodes) de 8 bits y son desplazados en el borde de subida del pulso de reloj. Esto le lleva a la EEPROM unos 10 milisegundos para escribir una página de datos (128 bytes) por lo que hay que introducir en la rutina de escritura una pausa de 10ms por cada ciclo de escritura.

Preparando la placa entrenadora.

Insertamos el chip AT25HP512 en la placa entrenadora. Conectamos 5v al pin de alimentación y el pin GND lo conectamos a la linea negativa del microcontrolador. Conectamos los pines 3, 7 y 8 de la EEPROM a 5v y el pin 4 a GND.

Changed lines 77-78 from:

+5v wires are red, GND wires are black

to:

los cables +5v en rofo, los GND en negro

June 08, 2010, at 12:57 AM by Equipo Traduccion -
Changed lines 54-63 from:

This means that to write code for a new SPI device you need to note several things and set the SPCR accordingly:

  • Is data shifted in MSB or LSB first?
  • Is the data clock idle when high or low?
  • Are samples on the rising or falling edge of clock pulses?
  • What speed is the SPI running at?

Once you have your SPI Control Register set correctly you just need to figure out how long you need to pause between instructions and you are ready to go. Now that you have a feel for how SPI works, let's take a look at the details of the EEPROM chip.

Introduction to Serial EEPROM

to:

Esto significa que para escribir código para un periférico SPI nuevo debes tener en cuenta sus especificaciones y establecer el SPCR adecuadamente:

  • ¿Son los datos desplazados en MSB o en LSB primero?.
  • ¿Está el reloj inactivo en alto o en bajo?.
  • ¿Se hace el muestreo en el flanco de subida o en el de bajada?.
  • ¿A que velocidad correrá el SPI?.

Un vez que tengas el Registro de Control del SPI correctamente establecido solo necesitas calcula como de larga debe ser la pausa entre instrucciones y estarás listo para continuar. Ahora que sabes como funciona el SPI es el momento de ver los detalles del chip EEPROM.

Introducción a la EEPROM Serie.

Changed lines 68-69 from:

The AT25HP512 is a 65,536 byte serial EEPROM. It supports SPI modes 0 and 3, runs at up to 10MHz at 5v and can run at slower speeds down to 1.8v. It's memory is organized as 512 pages of 128 bytes each. It can only be written 128 bytes at a time, but it can be read 1-128 bytes at a time. The device also offers various degerees of write protection and a hold pin, but we won't be covering those in this tutorial.

to:

El AT25HP512 es una memoria EEPROM Serie de 65.536 bytes. Soporta los modos SPI 0 y 3, funciona a 10MHZ y 5v y puede funcionar a velocidades inferiores por debajo de los 1.8v. Esta memoria está organizada en 512 páginas de 128 bytes cada una. Solo se pueden escribir 128 bytes cada vez, pero pueden ser leídos de 1 a 128 bytes cada vez. El dispositivo también ofrece varios grados de protección de escritura y un pin de espera, pero no veremos eso en este tutorial.

June 08, 2010, at 12:26 AM by Equipo Traduccion -
Changed lines 15-18 from:

El Interfaz Periférico Serie (SPI) es un protocolo de datos serie sincrono utilizado por microcontroladores para comunicar con uno o varios dispositivos periféricos de una forma rápida y a través de una distancia corta. También puede comunicar dos microcontroladores.

En la comunicación SPI hay un dispositivo maestro (generalmente el microcontrolador) que controla varios dispositivos esclavos. Tipicamente se usan tres lineas comunes para todos los dispositivos:

to:

El Interfaz Periférico Serie (SPI) es un protocolo de datos serie síncrono utilizado por microcontroladores para comunicar con uno o varios dispositivos periféricos de una forma rápida y a través de una distancia corta. También puede comunicar dos microcontroladores.

En la comunicación SPI hay un dispositivo maestro (generalmente el microcontrolador) que controla varios dispositivos esclavos. Típicamente se usan tres lineas comunes para todos los dispositivos:

Changed lines 29-39 from:

La parte difícil del SPI es que se ha perdido el standard y cada dispositivo implementa un protocolo ligeramente diferente. Esto quiere decir que debes prestar especial antención a las hojas de características (datasheet) del dispositivo cuando escribas el código para la comunicación. Generalmente hablando hay cuatro tipos de transmisiones numeradas del 0 al 3. Estos tipos de transmisión establecen si los datos se desplaza en un sentido u otro en el flanco de subida o de bajada de la señal de reloj y cuando el reloj entra en reposo, si en estado alto o bajo.

Todos los valores del SPI están determinados por el Registro de Control SPI (siglas en ingles SPCR) de Arduino. El registro es un byte en la memoria del microcontrolador que puede ser leido o escrito. Los registros normalmente sirven para tres propositos: control, datos y estado.

Control registers code control settings for various microcontroller functionalities. Usually each bit in a control register effects a particular setting, such as speed or polarity.

Data registers simply hold bytes. For example, the SPI data register (SPDR) holds the byte which is about to be shifted out the MOSI line, and the data which has just been shifted in the MISO line.

Status registers change their state based on various microcontroller conditions. For example, the seventh bit of the SPI status register (SPSR) gets set to 1 when a value is shifted in or out of the SPI.

The SPI control register (SPCR) has 8 bits, each of which control a particular SPI setting.

to:

La parte difícil del SPI es que se ha perdido el standard y cada dispositivo implementa un protocolo ligeramente diferente. Esto quiere decir que debes prestar especial atención a las hojas de características (datasheet) del dispositivo cuando escribas el código para la comunicación. Generalmente hablando hay cuatro tipos de transmisiones numeradas del 0 al 3. Estos tipos de transmisión establecen si los datos se desplaza en un sentido u otro en el flanco de subida o de bajada de la señal de reloj y cuando el reloj entra en reposo, si en estado alto o bajo.

Todos los valores del SPI están determinados por el Registro de Control SPI (siglas en ingles SPCR) de Arduino. El registro es un byte en la memoria del microcontrolador que puede ser leído o escrito. Los registros normalmente sirven para tres propósitos: control, datos y estado.

Los registros de control establecen varias funcionalidades de los microcontroladores. Usualmente cada bit en un registro de control afecta a una función particular, como velocidad o polaridad.

Los registros de datos solo almacenan bytes. Por ejemplo, el registro de datos del SPI almacena el byte que está a punto de ser lanzado por la linea MOSI, y el byte que acaba de ser recibido por la linea MISO.

Los registros de estado cambian su estado basándose en varias condiciones del microcontrolador. Por ejemplo, el septimo bit del registro de estado del SPI se pone en 1 cuando un valor es desplazado dentro o fuera del SPI.

El registro de control SPI (SPCR) tiene 8 bits, cada uno de ellos controla un parametro particular del SPI.

Changed lines 45-51 from:

SPIE - Enables the SPI interrupt when 1 SPE - Enables the SPI when 1 DORD - Sends data least Significant Bit First when 1, most Significant Bit first when 0 MSTR - Sets the Arduino in master mode when 1, slave mode when 0 CPOL - Sets the data clock to be idle when high if set to 1, idle when low if set to 0 CPHA - Samples data on the falling edge of the data clock when 1, rising edge when 0 SPR1 and SPR0 - Sets the SPI speed, 00 is fastest (4MHz) 11 is slowest (250KHz)

to:

SPIE - Permine la interrupción del SPI cuando es 1. SPE - Permite el SPI cuando es 1. DORD - Envía el bit menos significativo primero cuando el 1, el mas significativo bit primero cuando es 0. MSTR - Establece la Arduino como maestro cuando es 1, esclava cuando es 0. CPOL - Ajusta la polaridad del reloj en alto cuando es 1 y en bajo cuando es 0. CPHA - Envía los datos en el flanco de bajada del reloj cuando es 1, en el de subida cuando es 0. SPR1 and SPR0 - Establece la velocidad del SPI: 00 es la mas rápida (4MHz) y 11 es la mas lenta (250KHz).

June 08, 2010, at 12:00 AM by Equipo Traduccion -
Changed lines 31-33 from:

Todos los valores del SPI están determinados por el Registro de Control SPI (siglas en ingles SPCR) de Arduino. El registro

 A register is just a byte of microcontroller memory that can be read from or written to. Registers generally serve three purposes, control, data and  status. 
to:

Todos los valores del SPI están determinados por el Registro de Control SPI (siglas en ingles SPCR) de Arduino. El registro es un byte en la memoria del microcontrolador que puede ser leido o escrito. Los registros normalmente sirven para tres propositos: control, datos y estado.

June 07, 2010, at 11:57 PM by Equipo Traduccion -
Changed lines 29-33 from:

The difficult part about SPI is that the standard is loose and each device implements it a little differently. This means you have to pay special attention to the datasheet when writing your interface code. Generally speaking there are three modes of transmission numbered 0 - 3. These modes control whether data is shifted in and out on the rising or falling edge of the data clock signal, and whether the clock is idle when high or low.

All SPI settings are determined by the Arduino SPI Control Register (SPCR). A register is just a byte of microcontroller memory that can be read from or written to. Registers generally serve three purposes, control, data and status.

to:

La parte difícil del SPI es que se ha perdido el standard y cada dispositivo implementa un protocolo ligeramente diferente. Esto quiere decir que debes prestar especial antención a las hojas de características (datasheet) del dispositivo cuando escribas el código para la comunicación. Generalmente hablando hay cuatro tipos de transmisiones numeradas del 0 al 3. Estos tipos de transmisión establecen si los datos se desplaza en un sentido u otro en el flanco de subida o de bajada de la señal de reloj y cuando el reloj entra en reposo, si en estado alto o bajo.

Todos los valores del SPI están determinados por el Registro de Control SPI (siglas en ingles SPCR) de Arduino. El registro

 A register is just a byte of microcontroller memory that can be read from or written to. Registers generally serve three purposes, control, data and  status. 
June 07, 2010, at 10:36 PM by Equipo Traduccion -
Changed lines 1-20 from:

Interfacing a Serial EEPROM Using SPI

In this tutorial you will learn how to interface with an AT25HP512 Atmel serial EEPROM using the Serial Peripheral Interface (SPI) protocol. EEPROM chips such as this are very useful for data storage, and the steps we will cover for implementing SPI communication can be modified for use with most other SPI devices. Note that the chip on the Arduino board contains an internal EEPROM, so follow this tutorial only if you need more space than it provides.

Materials Needed:

  • AT25HP512 Serial EEPROM chip (or similar)
  • Hookup wire
  • Arduino Microcontroller Module

Introduction to the Serial Peripheral Interface

Serial Peripheral Interface (SPI) is a synchronous serial data protocol used by Microcontrollers for communicating with one or more peripheral devices quickly over short distances. It can also be used for communication between two microcontrollers.

With an SPI connection there is always one master device (usually a microcontroller) which controls the peripheral devices. Typically there are three lines common to all the devices,

  • Master In Slave Out (MISO) - The Slave line for sending data to the master,
  • Master Out Slave In (MOSI) - The Master line for sending data to the peripherals,
  • Serial Clock (SCK) - The clock pulses which synchronize data transmission generated by the master, and
  • Slave Select pin - allocated on each device which the master can use to enable and disable specific devices and avoid false transmissions due to line noise.
to:

Interactuando con una memoria EEPROM Serie usando SPI.

En este tutorial aprenderás como interactuar con una memoria EEPROM Serie AT25HP512 de la marca Atmel utilizando el protocolo de Interfaz Periférico Serie (siglas SPI en ingles). Los chips de memoria EEPROM son ampliamente utilizados para almacenar datos. Los pasos que veremos para implementar una comunicación SPI pueden ser fácilmente modificados para su uso con cualquier otro dispositivo SPI. Ten en cuenta que el chip de la placa Arduino contiene una memoria EEPROM interna, sigue este tutorial sólo si necesitas una cantidad mayor.

Materiales que necesitamos:

  • Chip AT25HP512 EEPROM Serie (o similar).
  • Cables de unión.
  • Microcontrolador Arduino.

Introducción al Interfaz Periférico Serie.

El Interfaz Periférico Serie (SPI) es un protocolo de datos serie sincrono utilizado por microcontroladores para comunicar con uno o varios dispositivos periféricos de una forma rápida y a través de una distancia corta. También puede comunicar dos microcontroladores.

En la comunicación SPI hay un dispositivo maestro (generalmente el microcontrolador) que controla varios dispositivos esclavos. Tipicamente se usan tres lineas comunes para todos los dispositivos:

  • Master In Slave Out (MISO) - La linea del esclavo para enviar datos al maestro.

  • Master Out Slave In (MOSI) - La linea del maestro para enviar datos a los periféricos.

  • Serial Clock (SCK) - Los pulsos de reloj generados por el maestro para sincronizar la transmisión de los datos.

Se utiliza una cuarta linea que es diferente para cada uno de los periféricos:

  • Slave Select pin (SS) - Asignada a cada uno de los dispositivos el maestro la utiliza para habilitar o inhabilitar la comunicación. Esto protege de falsas transmisiones por culpa de posibles ruidos en los cableados.

October 07, 2006, at 06:30 PM by Heather Dewey-Hagborg -
Changed lines 16-17 from:
  • Master In Slave Out (MISO) - The Master line for sending data to the peripherals,
  • Master Out Slave In (MOSI) - The Slave line for sending data to the master,
to:
  • Master In Slave Out (MISO) - The Slave line for sending data to the master,
  • Master Out Slave In (MOSI) - The Master line for sending data to the peripherals,
September 06, 2006, at 11:30 PM by David A. Mellis - adding note about internal eeprom on arduino
Changed lines 3-4 from:

In this tutorial you will learn how to interface with an AT25HP512 Atmel serial EEPROM using the Serial Peripheral Interface (SPI) protocol. EEPROM chips such as this are very useful for data storage, and the steps we will cover for implementing SPI communication can be modified for use with most other SPI devices.

to:

In this tutorial you will learn how to interface with an AT25HP512 Atmel serial EEPROM using the Serial Peripheral Interface (SPI) protocol. EEPROM chips such as this are very useful for data storage, and the steps we will cover for implementing SPI communication can be modified for use with most other SPI devices. Note that the chip on the Arduino board contains an internal EEPROM, so follow this tutorial only if you need more space than it provides.

September 06, 2006, at 10:38 PM by Heather Dewey-Hagborg -
Changed lines 7-10 from:
  1. AT25HP512 Serial EEPROM chip (or similar)
  2. Hookup wire
  3. Arduino Microcontroller Module
to:
  • AT25HP512 Serial EEPROM chip (or similar)
  • Hookup wire
  • Arduino Microcontroller Module
September 05, 2006, at 07:57 PM by Heather Dewey-Hagborg -
Changed lines 329-331 from:

@]

to:

@]

code and tutorial by Heather Dewey-Hagborg, photos by Thomas Dexter

August 31, 2006, at 08:19 PM by Heather Dewey-Hagborg -
Changed lines 70-71 from:

Connect EEPROM pin 1 to Arduino pin 10 (Slave Select), EEPROM pin 2 to Arduino pin 12 (Master In Slave Out), EEPROM pin 5 to Arduino pin 11 (Master Out Slave In), and EEPROM pin 6 to Arduino pin 13 (Serial Clock).

to:

Connect EEPROM pin 1 to Arduino pin 10 (Slave Select - SS), EEPROM pin 2 to Arduino pin 12 (Master In Slave Out - MISO), EEPROM pin 5 to Arduino pin 11 (Master Out Slave In - MOSI), and EEPROM pin 6 to Arduino pin 13 (Serial Clock - SCK).

August 31, 2006, at 08:17 PM by Heather Dewey-Hagborg -
Changed lines 68-69 from:
to:

+5v wires are red, GND wires are black

Changed lines 73-74 from:
to:

SS wire is white, MISO wire is yellow, MOSI wire is blue, SCK wire is green

August 31, 2006, at 08:13 PM by Heather Dewey-Hagborg -
Changed lines 67-68 from:

PICTURE of pwr wires

to:
Changed lines 71-72 from:

PICTURE of SPI wires

to:
August 30, 2006, at 06:08 PM by Heather Dewey-Hagborg -
Changed lines 2-3 from:

(IN PROGRESS)

to:
August 30, 2006, at 06:05 PM by Heather Dewey-Hagborg -
Changed lines 180-182 from:

This function simply fills our data array with numbers 0 - 127 for each index in the array. This function could easily be changed to fill the array with data relevant to your application:

to:

The fill_buffer function simply fills our data array with numbers 0 - 127 for each index in the array. This function could easily be changed to fill the array with data relevant to your application:

Changed lines 191-192 from:

This function loads the output data into the data transmission register, thus starting the SPI transmission. It polls a bit to the SPI Status register (SPSR) to detect when the transmission is complete using a bit mask, SPIF. An explanation of bit masks can be found here. It then returns any data that has been shifted in to the data register by the EEPROM:

to:

The spi_transfer function loads the output data into the data transmission register, thus starting the SPI transmission. It polls a bit to the SPI Status register (SPSR) to detect when the transmission is complete using a bit mask, SPIF. An explanation of bit masks can be found here. It then returns any data that has been shifted in to the data register by the EEPROM:

Changed lines 203-204 from:

This function allows us to read data back out of the EEPROM. First we set the SLAVESELECT line low to enable the device. Then we transmit a READ instruction, followed by the 16-bit address we wish to read from, Most Significant Bit first. Next we send a dummy byte to the EEPROM for the purpose of shifting the data out. Finally we pull the SLAVESELECT line high again to release the device after reading one byte, and return the data. If we wanted to read multiple bytes at a time we could hold the SLAVESELECT line low while we repeated the data = spi_transfer(0xFF); up to 128 times for a full page of data:

to:

The read_eeprom function allows us to read data back out of the EEPROM. First we set the SLAVESELECT line low to enable the device. Then we transmit a READ instruction, followed by the 16-bit address we wish to read from, Most Significant Bit first. Next we send a dummy byte to the EEPROM for the purpose of shifting the data out. Finally we pull the SLAVESELECT line high again to release the device after reading one byte, and return the data. If we wanted to read multiple bytes at a time we could hold the SLAVESELECT line low while we repeated the data = spi_transfer(0xFF); up to 128 times for a full page of data:

August 30, 2006, at 06:05 PM by Heather Dewey-Hagborg -
Added lines 78-81:

The first step is setting up our pre-processor directives. Pre-processor directives are processed before the actual compilation begins. They start with a "#" and do not end with semi-colons.

We define the pins we will be using for our SPI connection, DATAOUT, DATAIN, SPICLOCK and SLAVESELECT. Then we define our opcodes for the EEPROM. Opcodes are control commands:

Changed lines 96-99 from:

Here we set up our pre-processor directives. Pre-processor directives are processed before the actual compilation begins. They start with a "#" and do not end with semi-colons.

First we define the pins we will be using for our SPI connection, DATAOUT, DATAIN, SPICLOCK and SLAVESELECT. Then we define our opcodes for the EEPROM. Opcodes are control commands.

to:

Here we allocate the global variables we will be using later in the program. Note char buffer [128];. this is a 128 byte array we will be using to store the data for the EEPROM write:

Changed lines 106-107 from:

Here we allocate the global variables we will be using later in the program. Note char buffer [128];. this is a 128 byte array we will be using to store the data for the EEPROM write.

to:

First we initialize our serial connection, set our input and output pin modes and set the SLAVESELECT line high to start. This deselects the device and avoids any false transmission messages due to line noise:

Changed lines 119-120 from:

First we initialize our serial connection, set our input and output pin modes and set the SLAVESELECT line high to start. This deselects the device and avoids any false transmission messages due to line noise.

to:

Now we set the SPI Control register (SPCR) to the binary value 01010000. In the control register each bit sets a different functionality. The eighth bit disables the SPI interrupt, the seventh bit enables the SPI, the sixth bit chooses transmission with the most significant bit going first, the fifth bit puts the Arduino in Master mode, the fourth bit sets the data clock idle when it is low, the third bit sets the SPI to sample data on the rising edge of the data clock, and the second and first bits set the speed of the SPI to system speed / 4 (the fastest). After setting our control register up we read the SPI status register (SPSR) and data register (SPDR) in to the junk clr variable to clear out any spurious data from past runs:

Changed lines 131-133 from:

Now we set the SPI Control register (SPCR) to the binary value 01010000. In the control register each bit sets a different functionality. The eighth bit disables the SPI interrupt, the seventh bit enables the SPI, the sixth bit chooses transmission with the most significant bit going first, the fifth bit puts the Arduino in Master mode, the fourth bit sets the data clock idle when it is low, the third bit sets the SPI to sample data on the rising edge of the data clock, and the second and first bits set the speed of the SPI to system speed / 4 (the fastest). After setting our control register up we read the SPI status register (SPSR) and data register (SPDR) in to the junk clr variabl to clear out any spurious data from past runs.

to:

Here we fill our data array with numbers and send a write enable instruction to the EEPROM. The EEPROM MUST be write enabled before every write instruction. To send the instruction we pull the SLAVESELECT line low, enabling the device, and then send the instruction using the spi_transfer function. Note that we use the WREN opcode we defined at the beginning of the program. Finally we pull the SLAVESELECT line high again to release it:

Changed lines 141-142 from:

Here we fill our data array with numbers and send a write enable instruction to the EEPROM. The EEPROM MUST be write enabled before every write instruction. To send the instruction we pull the SLAVESELECT line low, enabling the device, and then send the instruction using the spi_transfer function. Note that we use the WREN opcode we defined at the beginning of the program. Finally we pull the SLAVESELECT line high again to release it.

to:

Now we pull the SLAVESELECT line low to select the device again after a brief delay. We send a WRITE instruction to tell the EEPROM we will be sending data to record into memory. We send the 16 bit address to begin writing at in two bytes, Most Significant Bit first. Next we send our 128 bytes of data from our buffer array, one byte after another without pause. Finally we set the SLAVESELECT pin high to release the device and pause to allow the EEPROM to write the data:

Changed lines 159-160 from:

Now we pull the SLAVESELECT line low to select the device again after a brief delay. We send a WRITE instruction to tell the EEPROM we will be sending data to record into memory. We send the 16 bit address to begin writing at in two bytes, Most Significant Bit first. Next we send our 128 bytes of data from our buffer array, one byte after another without pause. Finally we set the SLAVESELECT pin high to release the device and pause to allow the EEPROM to write the data.

to:

We end the setup function by sending the word "hi" plus a line feed out the built in serial port for debugging purposes. This way if our data comes out looking funny later on we can tell it isn't just the serial port acting up:

Changed lines 168-169 from:

We end the setup function by sending the word "hi" plus a line feed out the built in serial port for debugging purposes. This way if our data comes out looking funny later on we can tell it isn't just the serial port acting up.

to:

In our main loop we just read one byte at a time from the EEPROM and print it out the serial port. We add a line feed and a pause for readability. Each time through the loop we increment the eeprom address to read. When the address increments to 128 we turn it back to 0 because we have only filled 128 addresses in the EEPROM with data:

Changed lines 181-182 from:

In our main loop we just read one byte at a time from the EEPROM and print it out the serial port. We add a line feed and a pause for readability. Each time through the loop we increment the eeprom address to read. When the address increments to 128 we turn it back to 0 because we have only filled 128 addresses in the EEPROM with data.

to:

This function simply fills our data array with numbers 0 - 127 for each index in the array. This function could easily be changed to fill the array with data relevant to your application:

Changed lines 192-193 from:

This function simply fills our data array with numbers 0 - 127 for each index in the array. This function could easily be changed to fill the array with data relevant to your application.

to:

This function loads the output data into the data transmission register, thus starting the SPI transmission. It polls a bit to the SPI Status register (SPSR) to detect when the transmission is complete using a bit mask, SPIF. An explanation of bit masks can be found here. It then returns any data that has been shifted in to the data register by the EEPROM:

Changed lines 204-205 from:

This function loads the output data into the data transmission register, thus starting the SPI transmission. It polls a bit to the SPI Status register (SPSR) to detect when the transmission is complete using a bit mask, SPIF. An explanation of bit masks can be found here. It then returns any data that has been shifted in to the data register by the EEPROM.

to:

This function allows us to read data back out of the EEPROM. First we set the SLAVESELECT line low to enable the device. Then we transmit a READ instruction, followed by the 16-bit address we wish to read from, Most Significant Bit first. Next we send a dummy byte to the EEPROM for the purpose of shifting the data out. Finally we pull the SLAVESELECT line high again to release the device after reading one byte, and return the data. If we wanted to read multiple bytes at a time we could hold the SLAVESELECT line low while we repeated the data = spi_transfer(0xFF); up to 128 times for a full page of data:

Changed lines 220-222 from:

This function allows us to read data back out of the EEPROM. First we set the SLAVESELECT line low to enable the device. Then we transmit a READ instruction, followed by the 16-bit address we wish to read from, Most Significant Bit first. Next we send a dummy byte to the EEPROM for the purpose of shifting the data out. Finally we pull the SLAVESELECT line high again to release the device after reading one byte, and return the data. If we wanted to read multiple bytes at a time we could hold the SLAVESELECT line low while we repeated the data = spi_transfer(0xFF); up to 128 times for a full page of data.

to:
August 30, 2006, at 06:01 PM by Heather Dewey-Hagborg -
Changed line 107 from:

void fill_buffer()

to:

void setup()

Deleted lines 108-132:
  for (int I=0;I<128;I++)
  {
    buffer[I]=I;
  }

} @]

This function simply fills our data array with numbers 0 - 127 for each index in the array. This function could easily be changed to fill the array with data relevant to your application.

char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait for the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}

This function loads the output data into the data transmission register, thus starting the SPI transmission. It polls a bit to the SPI Status register (SPSR) to detect when the transmission is complete using a bit mask, SPIF. An explanation of bit masks can be found here. It then returns any data that has been shifted in to the data register by the EEPROM.

The following setup function is long so we will take it in parts.

[@ void setup() {

Changed lines 163-164 from:
  delay(1000);@]
to:
  delay(1000);

}@]

Changed line 169 from:

byte read_eeprom(int EEPROM_address)

to:

void loop()

Changed lines 171-179 from:
  //READ EEPROM
  int data;
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(READ); //transmit read opcode
  spi_transfer((char)(EEPROM_address>>8));   //send MSByte address first
  spi_transfer((char)(EEPROM_address));      //send LSByte address
  data = spi_transfer(0xFF); //get data byte
  digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
  return data;
to:
  eeprom_output_data = read_eeprom(address);
  Serial.print(eeprom_output_data,DEC);
  Serial.print('\n',BYTE);
  address++;
  delay(500); //pause for readability
Changed lines 178-179 from:

This function allows us to read data back out of the EEPROM. First we set the SLAVESELECT line low to enable the device. Then we transmit a READ instruction, followed by the 16-bit address we wish to read from, Most Significant Bit first. Next we send a dummy byte to the EEPROM for the purpose of shifting the data out. Finally we pull the SLAVESELECT line high again to release the device after reading one byte, and return the data. If we wanted to read multiple bytes at a time we could hold the SLAVESELECT line low while we repeated the data = spi_transfer(0xFF); up to 128 times for a full page of data.

to:

In our main loop we just read one byte at a time from the EEPROM and print it out the serial port. We add a line feed and a pause for readability. Each time through the loop we increment the eeprom address to read. When the address increments to 128 we turn it back to 0 because we have only filled 128 addresses in the EEPROM with data.

Changed line 181 from:

void loop()

to:

void fill_buffer()

Changed lines 183-187 from:
  eeprom_output_data = read_eeprom(address);
  Serial.print(eeprom_output_data,DEC);
  Serial.print('\n',BYTE);
  address++;
  delay(500); //pause for readability
to:
  for (int I=0;I<128;I++)
  {
    buffer[I]=I;
  }
Changed lines 189-193 from:

Finally we get to our main loop, the simplest function in the program! Here we just read one byte at a time from the EEPROM and print it out the serial port. We add a line feed and a pause for readability. Each time through the loop we increment the eeprom address to read. When the address increments to 128 we turn it back to 0 because we have only filled 128 addresses in the EEPROM with data.

For easy copy and pasting the full program text of this tutorial is below:

to:

This function simply fills our data array with numbers 0 - 127 for each index in the array. This function could easily be changed to fill the array with data relevant to your application.

Changed lines 192-212 from:
  1. define DATAOUT 11//MOSI
  2. define DATAIN 12//MISO
  3. define SPICLOCK 13//sck
  4. define SLAVESELECT 10//ss

//opcodes

  1. define WREN 6
  2. define WRDI 4
  3. define RDSR 5
  4. define WRSR 1
  5. define READ 3
  6. define WRITE 2

byte eeprom_output_data; byte eeprom_input_data=0; byte clr; int address=0; //data buffer char buffer [128];

void fill_buffer()

to:

char spi_transfer(volatile char data)

Changed lines 194-195 from:
  for (int I=0;I<128;I++)
to:
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait for the end of the transmission
Deleted lines 196-204:
    buffer[I]=I;
  }

}

char spi_transfer(volatile char data) {

  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
Changed lines 199-201 from:

}

void setup()

to:

}@]

This function loads the output data into the data transmission register, thus starting the SPI transmission. It polls a bit to the SPI Status register (SPSR) to detect when the transmission is complete using a bit mask, SPIF. An explanation of bit masks can be found here. It then returns any data that has been shifted in to the data register by the EEPROM.

[@ byte read_eeprom(int EEPROM_address)

Changed lines 206-222 from:
  Serial.begin(9600);

  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  digitalWrite(SLAVESELECT,HIGH); //disable device
  // SPCR = 01010000
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on leading edge of clk,system clock/4 rate (fastest)
  SPCR = (1<<SPE)|(1<<MSTR);
  clr=SPSR;
  clr=SPDR;
  delay(10);
  //fill buffer with data
  fill_buffer();
  //fill eeprom w/ buffer
to:
  //READ EEPROM
  int data;
Deleted lines 208-234:
  spi_transfer(WREN); //write enable
  digitalWrite(SLAVESELECT,HIGH);
  delay(10);
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(WRITE); //write instruction
  address=0;
  spi_transfer((char)(address>>8));   //send MSByte address first
  spi_transfer((char)(address));      //send LSByte address
  //write 128 bytes
  for (int I=0;I<128;I++)
  {
    spi_transfer(buffer[I]); //write data byte
  }
  digitalWrite(SLAVESELECT,HIGH); //release chip
  //wait for eeprom to finish writing
  delay(3000);
  Serial.print('h',BYTE);
  Serial.print('i',BYTE);
  Serial.print('\n',BYTE);//debug
  delay(1000);

}

byte read_eeprom(int EEPROM_address) {

  //READ EEPROM
  int data;
  digitalWrite(SLAVESELECT,LOW);
Changed lines 215-228 from:

}

void loop() {

  eeprom_output_data = read_eeprom(address);
  Serial.print(eeprom_output_data,DEC);
  Serial.print('\n',BYTE);
  address++;
  if (address == 128)
    address = 0;
  delay(500); //pause for readability

} @]

to:

} @]

This function allows us to read data back out of the EEPROM. First we set the SLAVESELECT line low to enable the device. Then we transmit a READ instruction, followed by the 16-bit address we wish to read from, Most Significant Bit first. Next we send a dummy byte to the EEPROM for the purpose of shifting the data out. Finally we pull the SLAVESELECT line high again to release the device after reading one byte, and return the data. If we wanted to read multiple bytes at a time we could hold the SLAVESELECT line low while we repeated the data = spi_transfer(0xFF); up to 128 times for a full page of data.

For easy copy and pasting the full program text of this tutorial is below:

Added lines 223-327:
  1. define DATAOUT 11//MOSI
  2. define DATAIN 12//MISO
  3. define SPICLOCK 13//sck
  4. define SLAVESELECT 10//ss

//opcodes

  1. define WREN 6
  2. define WRDI 4
  3. define RDSR 5
  4. define WRSR 1
  5. define READ 3
  6. define WRITE 2

byte eeprom_output_data; byte eeprom_input_data=0; byte clr; int address=0; //data buffer char buffer [128];

void fill_buffer() {

  for (int I=0;I<128;I++)
  {
    buffer[I]=I;
  }

}

char spi_transfer(volatile char data) {

  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
  return SPDR;                    // return the received byte

}

void setup() {

  Serial.begin(9600);

  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  digitalWrite(SLAVESELECT,HIGH); //disable device
  // SPCR = 01010000
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on leading edge of clk,system clock/4 rate (fastest)
  SPCR = (1<<SPE)|(1<<MSTR);
  clr=SPSR;
  clr=SPDR;
  delay(10);
  //fill buffer with data
  fill_buffer();
  //fill eeprom w/ buffer
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(WREN); //write enable
  digitalWrite(SLAVESELECT,HIGH);
  delay(10);
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(WRITE); //write instruction
  address=0;
  spi_transfer((char)(address>>8));   //send MSByte address first
  spi_transfer((char)(address));      //send LSByte address
  //write 128 bytes
  for (int I=0;I<128;I++)
  {
    spi_transfer(buffer[I]); //write data byte
  }
  digitalWrite(SLAVESELECT,HIGH); //release chip
  //wait for eeprom to finish writing
  delay(3000);
  Serial.print('h',BYTE);
  Serial.print('i',BYTE);
  Serial.print('\n',BYTE);//debug
  delay(1000);

}

byte read_eeprom(int EEPROM_address) {

  //READ EEPROM
  int data;
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(READ); //transmit read opcode
  spi_transfer((char)(EEPROM_address>>8));   //send MSByte address first
  spi_transfer((char)(EEPROM_address));      //send LSByte address
  data = spi_transfer(0xFF); //get data byte
  digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
  return data;

}

void loop() {

  eeprom_output_data = read_eeprom(address);
  Serial.print(eeprom_output_data,DEC);
  Serial.print('\n',BYTE);
  address++;
  if (address == 128)
    address = 0;
  delay(500); //pause for readability

} @]

[@

August 30, 2006, at 05:57 PM by Heather Dewey-Hagborg -
Changed lines 53-54 from:

Once you have your SPI Control Register set correctly you just need to figure out how long you need to pause between instructions and you are ready to go. Now that you have a feel for how SPI works, let's take a look at the EEPROM chip.

to:

Once you have your SPI Control Register set correctly you just need to figure out how long you need to pause between instructions and you are ready to go. Now that you have a feel for how SPI works, let's take a look at the details of the EEPROM chip.

Changed lines 62-63 from:

The device is enabled by pulling the Chip Select (CS) pin low. Instructions are 8 bit opcodes and are shifted in on the rising edge of the data clock. It takes the EEPROM about 10 milliseconds to write a page (128 bytes) of data, so a 10ms pause should follow each EEPROM write routine.

to:

The device is enabled by pulling the Chip Select (CS) pin low. Instructions are sent as 8 bit operational codes (opcodes) and are shifted in on the rising edge of the data clock. It takes the EEPROM about 10 milliseconds to write a page (128 bytes) of data, so a 10ms pause should follow each EEPROM write routine.

Changed lines 127-128 from:

This function loads the output data into the data transmission register, thus starting the SPI transmission. It polls a bit to the SPI Status register (SPSR) to detect when the transmission is complete. It then returns any data that has been shifted in to the data register by the EEPROM.

to:

This function loads the output data into the data transmission register, thus starting the SPI transmission. It polls a bit to the SPI Status register (SPSR) to detect when the transmission is complete using a bit mask, SPIF. An explanation of bit masks can be found here. It then returns any data that has been shifted in to the data register by the EEPROM.

Changed lines 154-155 from:

After setting our control register up we clear any spurious data from the Status and Control registers.

to:

After setting our control register up we read the SPI status register (SPSR) and data register (SPDR) in to the junk clr variabl to clear out any spurious data from past runs.

August 30, 2006, at 05:51 PM by Heather Dewey-Hagborg -
Changed lines 53-54 from:

Once you have your SPI Control Register set correctly you just need to figure out how long you need to pause between instructions and you are ready to go.

to:

Once you have your SPI Control Register set correctly you just need to figure out how long you need to pause between instructions and you are ready to go. Now that you have a feel for how SPI works, let's take a look at the EEPROM chip.

August 30, 2006, at 05:44 PM by Heather Dewey-Hagborg -
Changed lines 24-32 from:

All SPI settings are determined by the Arduino SPI Control Register (SPCR). The SPCR has 8 bits each of which control a particular SPI setting.

to:

All SPI settings are determined by the Arduino SPI Control Register (SPCR). A register is just a byte of microcontroller memory that can be read from or written to. Registers generally serve three purposes, control, data and status.

Control registers code control settings for various microcontroller functionalities. Usually each bit in a control register effects a particular setting, such as speed or polarity.

Data registers simply hold bytes. For example, the SPI data register (SPDR) holds the byte which is about to be shifted out the MOSI line, and the data which has just been shifted in the MISO line.

Status registers change their state based on various microcontroller conditions. For example, the seventh bit of the SPI status register (SPSR) gets set to 1 when a value is shifted in or out of the SPI.

The SPI control register (SPCR) has 8 bits, each of which control a particular SPI setting.

Changed lines 48-52 from:

-Is data shifted in MSB or LSB first? -Is the data clock idle when high or low? -Are samples on the rising or falling edge of clock pulses? -What speed is the SPI running at?

to:
  • Is data shifted in MSB or LSB first?
  • Is the data clock idle when high or low?
  • Are samples on the rising or falling edge of clock pulses?
  • What speed is the SPI running at?
August 30, 2006, at 04:58 PM by Tom Igoe -
Changed lines 14-15 from:

Serial Peripheral Interface (SPI) is a synchronous serial data protocol used by Microcontrollers for communicating with one or more peripheral devices quickly over short distances. It can also be used for communication between two microcontrollers. With an SPI connection there is always one master device (usually a microcontroller) which controls the peripheral devices. Typically there are three lines common to all the devices, Master In Slave Out (MISO) - The Master line for sending data to the peripherals, Master Out Slave In (MOSI) - The Slave line for sending data to the master, and Serial Clock (SCK) - The clock pulses which synchronize data transmission generated by the master. Additionally there is generally a Slave Select pin allocated on each device which the master can use to enable and disable specific devices and avoid false transmissions due to line noise.

to:

Serial Peripheral Interface (SPI) is a synchronous serial data protocol used by Microcontrollers for communicating with one or more peripheral devices quickly over short distances. It can also be used for communication between two microcontrollers.

With an SPI connection there is always one master device (usually a microcontroller) which controls the peripheral devices. Typically there are three lines common to all the devices,

  • Master In Slave Out (MISO) - The Master line for sending data to the peripherals,
  • Master Out Slave In (MOSI) - The Slave line for sending data to the master,
  • Serial Clock (SCK) - The clock pulses which synchronize data transmission generated by the master, and
  • Slave Select pin - allocated on each device which the master can use to enable and disable specific devices and avoid false transmissions due to line noise.
August 30, 2006, at 01:51 AM by Heather Dewey-Hagborg -
Added lines 46-49:

The AT25HP512 is a 65,536 byte serial EEPROM. It supports SPI modes 0 and 3, runs at up to 10MHz at 5v and can run at slower speeds down to 1.8v. It's memory is organized as 512 pages of 128 bytes each. It can only be written 128 bytes at a time, but it can be read 1-128 bytes at a time. The device also offers various degerees of write protection and a hold pin, but we won't be covering those in this tutorial.

The device is enabled by pulling the Chip Select (CS) pin low. Instructions are 8 bit opcodes and are shifted in on the rising edge of the data clock. It takes the EEPROM about 10 milliseconds to write a page (128 bytes) of data, so a 10ms pause should follow each EEPROM write routine.

August 30, 2006, at 12:46 AM by Heather Dewey-Hagborg -
Changed lines 16-17 from:

The difficult part about SPI is that the standard is loose and each device implements it a little differently. Generally speaking there are three modes of transmission numbered 0 - 3. These modes control whether data is shifted in and out on the rising or falling edge of the data clock signal, and whether the clock is idle when high or low.

to:

The difficult part about SPI is that the standard is loose and each device implements it a little differently. This means you have to pay special attention to the datasheet when writing your interface code. Generally speaking there are three modes of transmission numbered 0 - 3. These modes control whether data is shifted in and out on the rising or falling edge of the data clock signal, and whether the clock is idle when high or low.

Changed lines 33-35 from:

The eighth bit sets the SPI interrupt, the seventh bit enables the SPI, the sixth bit chooses transmission with the most significant bit going first or Least Significant, the fifth bit puts the Arduino in Master mode, the fourth bit sets the data clock idle when it is low, the third bit sets the SPI to sample data on the rising edge of the data clock, and the second and first bits set the speed of the SPI to system speed / 4 (the fastest).

to:

This means that to write code for a new SPI device you need to note several things and set the SPCR accordingly: -Is data shifted in MSB or LSB first? -Is the data clock idle when high or low? -Are samples on the rising or falling edge of clock pulses? -What speed is the SPI running at?

Once you have your SPI Control Register set correctly you just need to figure out how long you need to pause between instructions and you are ready to go.

August 29, 2006, at 11:07 PM by Heather Dewey-Hagborg -
Changed lines 14-15 from:

Serial Peripheral Interface (SPI) is a synchronous serial data protocol used by Microcontrollers for communicating with peripheral devices quickly over short distances. It can also be used for communication between two microcontrollers. With an SPI connection

to:

Serial Peripheral Interface (SPI) is a synchronous serial data protocol used by Microcontrollers for communicating with one or more peripheral devices quickly over short distances. It can also be used for communication between two microcontrollers. With an SPI connection there is always one master device (usually a microcontroller) which controls the peripheral devices. Typically there are three lines common to all the devices, Master In Slave Out (MISO) - The Master line for sending data to the peripherals, Master Out Slave In (MOSI) - The Slave line for sending data to the master, and Serial Clock (SCK) - The clock pulses which synchronize data transmission generated by the master. Additionally there is generally a Slave Select pin allocated on each device which the master can use to enable and disable specific devices and avoid false transmissions due to line noise.

The difficult part about SPI is that the standard is loose and each device implements it a little differently. Generally speaking there are three modes of transmission numbered 0 - 3. These modes control whether data is shifted in and out on the rising or falling edge of the data clock signal, and whether the clock is idle when high or low.

All SPI settings are determined by the Arduino SPI Control Register (SPCR). The SPCR has 8 bits each of which control a particular SPI setting.

SPCR
| 7    | 6    | 5    | 4    | 3    | 2    | 1    | 0    |
| SPIE | SPE  | DORD | MSTR | CPOL | CPHA | SPR1 | SPR0 |

SPIE - Enables the SPI interrupt when 1
SPE - Enables the SPI when 1
DORD - Sends data least Significant Bit First when 1, most Significant Bit first when 0
MSTR - Sets the Arduino in master mode when 1, slave mode when 0
CPOL - Sets the data clock to be idle when high if set to 1, idle when low if set to 0
CPHA - Samples data on the falling edge of the data clock when 1, rising edge when 0
SPR1 and SPR0 - Sets the SPI speed, 00 is fastest (4MHz) 11 is slowest (250KHz)

The eighth bit sets the SPI interrupt, the seventh bit enables the SPI, the sixth bit chooses transmission with the most significant bit going first or Least Significant, the fifth bit puts the Arduino in Master mode, the fourth bit sets the data clock idle when it is low, the third bit sets the SPI to sample data on the rising edge of the data clock, and the second and first bits set the speed of the SPI to system speed / 4 (the fastest).

August 29, 2006, at 09:56 PM by Heather Dewey-Hagborg -
Added lines 14-15:

Serial Peripheral Interface (SPI) is a synchronous serial data protocol used by Microcontrollers for communicating with peripheral devices quickly over short distances. It can also be used for communication between two microcontrollers. With an SPI connection

August 29, 2006, at 09:45 PM by Heather Dewey-Hagborg -
Changed lines 33-34 from:

[@#define DATAOUT 11//MOSI

to:

[@

  1. define DATAOUT 11//MOSI
Changed lines 51-52 from:

[@byte eeprom_output_data;

to:

[@ byte eeprom_output_data;

Changed lines 61-62 from:

[@void fill_buffer()

to:

[@ void fill_buffer()

Changed lines 72-73 from:

[@char spi_transfer(volatile char data)

to:

[@ char spi_transfer(volatile char data)

Changed lines 86-87 from:

[@void setup()

to:

[@ void setup()

Changed lines 99-100 from:

[@ // SPCR = 01010000

to:

[@

  // SPCR = 01010000
Changed lines 111-112 from:

[@//fill buffer with data

to:

[@

  //fill buffer with data
Changed lines 121-122 from:

[@delay(10);

to:

[@

  delay(10);
Changed lines 139-140 from:

[@Serial.print('h',BYTE);

to:

[@

  Serial.print('h',BYTE);
Changed lines 147-148 from:

[@byte read_eeprom(int EEPROM_address)

to:

[@ byte read_eeprom(int EEPROM_address)

Changed lines 163-164 from:

[@void loop()

to:

[@ void loop()

Changed lines 178-179 from:

[@#define DATAOUT 11//MOSI

to:

[@

  1. define DATAOUT 11//MOSI
August 29, 2006, at 09:43 PM by Heather Dewey-Hagborg -
Changed lines 162-164 from:

Finally we get to our main loop, the simplest function in the program! Here we just read one byte at a time from the EEPROM and print it out the serial port plus a line feed and a pause for readability. Each time through the loop we increment the eeprom address to read. When the address increments to 128 we turn it back to 0 since we have only filled 128 addresses in the EEPROM with data.

to:

Finally we get to our main loop, the simplest function in the program! Here we just read one byte at a time from the EEPROM and print it out the serial port. We add a line feed and a pause for readability. Each time through the loop we increment the eeprom address to read. When the address increments to 128 we turn it back to 0 because we have only filled 128 addresses in the EEPROM with data.

August 29, 2006, at 09:42 PM by Heather Dewey-Hagborg -
Added lines 59-164:
void fill_buffer()
{
  for (int I=0;I<128;I++)
  {
    buffer[I]=I;
  }
} 

This function simply fills our data array with numbers 0 - 127 for each index in the array. This function could easily be changed to fill the array with data relevant to your application.

char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait for the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}

This function loads the output data into the data transmission register, thus starting the SPI transmission. It polls a bit to the SPI Status register (SPSR) to detect when the transmission is complete. It then returns any data that has been shifted in to the data register by the EEPROM.

The following setup function is long so we will take it in parts.

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

  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  digitalWrite(SLAVESELECT,HIGH); //disable device 

First we initialize our serial connection, set our input and output pin modes and set the SLAVESELECT line high to start. This deselects the device and avoids any false transmission messages due to line noise.

 // SPCR = 01010000
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on leading edge of clk,system clock/4 rate (fastest)
  SPCR = (1<<SPE)|(1<<MSTR);
  clr=SPSR;
  clr=SPDR;
  delay(10); 

Now we set the SPI Control register (SPCR) to the binary value 01010000. In the control register each bit sets a different functionality. The eighth bit disables the SPI interrupt, the seventh bit enables the SPI, the sixth bit chooses transmission with the most significant bit going first, the fifth bit puts the Arduino in Master mode, the fourth bit sets the data clock idle when it is low, the third bit sets the SPI to sample data on the rising edge of the data clock, and the second and first bits set the speed of the SPI to system speed / 4 (the fastest). After setting our control register up we clear any spurious data from the Status and Control registers.

//fill buffer with data
  fill_buffer();
  //fill eeprom w/ buffer
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(WREN); //write enable
  digitalWrite(SLAVESELECT,HIGH);

Here we fill our data array with numbers and send a write enable instruction to the EEPROM. The EEPROM MUST be write enabled before every write instruction. To send the instruction we pull the SLAVESELECT line low, enabling the device, and then send the instruction using the spi_transfer function. Note that we use the WREN opcode we defined at the beginning of the program. Finally we pull the SLAVESELECT line high again to release it.

delay(10);
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(WRITE); //write instruction
  address=0;
  spi_transfer((char)(address>>8));   //send MSByte address first
  spi_transfer((char)(address));      //send LSByte address
  //write 128 bytes
  for (int I=0;I<128;I++)
  {
    spi_transfer(buffer[I]); //write data byte
  }
  digitalWrite(SLAVESELECT,HIGH); //release chip
  //wait for eeprom to finish writing
  delay(3000); 

Now we pull the SLAVESELECT line low to select the device again after a brief delay. We send a WRITE instruction to tell the EEPROM we will be sending data to record into memory. We send the 16 bit address to begin writing at in two bytes, Most Significant Bit first. Next we send our 128 bytes of data from our buffer array, one byte after another without pause. Finally we set the SLAVESELECT pin high to release the device and pause to allow the EEPROM to write the data.

Serial.print('h',BYTE);
  Serial.print('i',BYTE);
  Serial.print('\n',BYTE);//debug
  delay(1000);

We end the setup function by sending the word "hi" plus a line feed out the built in serial port for debugging purposes. This way if our data comes out looking funny later on we can tell it isn't just the serial port acting up.

byte read_eeprom(int EEPROM_address)
{
  //READ EEPROM
  int data;
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(READ); //transmit read opcode
  spi_transfer((char)(EEPROM_address>>8));   //send MSByte address first
  spi_transfer((char)(EEPROM_address));      //send LSByte address
  data = spi_transfer(0xFF); //get data byte
  digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
  return data;
} 

This function allows us to read data back out of the EEPROM. First we set the SLAVESELECT line low to enable the device. Then we transmit a READ instruction, followed by the 16-bit address we wish to read from, Most Significant Bit first. Next we send a dummy byte to the EEPROM for the purpose of shifting the data out. Finally we pull the SLAVESELECT line high again to release the device after reading one byte, and return the data. If we wanted to read multiple bytes at a time we could hold the SLAVESELECT line low while we repeated the data = spi_transfer(0xFF); up to 128 times for a full page of data.

void loop()
{
  eeprom_output_data = read_eeprom(address);
  Serial.print(eeprom_output_data,DEC);
  Serial.print('\n',BYTE);
  address++;
  delay(500); //pause for readability
} 

Finally we get to our main loop, the simplest function in the program! Here we just read one byte at a time from the EEPROM and print it out the serial port plus a line feed and a pause for readability. Each time through the loop we increment the eeprom address to read. When the address increments to 128 we turn it back to 0 since we have only filled 128 addresses in the EEPROM with data.

Added lines 166-270:
#define DATAOUT 11//MOSI
#define DATAIN  12//MISO 
#define SPICLOCK  13//sck
#define SLAVESELECT 10//ss

//opcodes
#define WREN  6
#define WRDI  4
#define RDSR  5
#define WRSR  1
#define READ  3
#define WRITE 2

byte eeprom_output_data;
byte eeprom_input_data=0;
byte clr;
int address=0;
//data buffer
char buffer [128];

void fill_buffer()
{
  for (int I=0;I<128;I++)
  {
    buffer[I]=I;
  }
}

char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}

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

  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  digitalWrite(SLAVESELECT,HIGH); //disable device
  // SPCR = 01010000
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on leading edge of clk,system clock/4 rate (fastest)
  SPCR = (1<<SPE)|(1<<MSTR);
  clr=SPSR;
  clr=SPDR;
  delay(10);
  //fill buffer with data
  fill_buffer();
  //fill eeprom w/ buffer
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(WREN); //write enable
  digitalWrite(SLAVESELECT,HIGH);
  delay(10);
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(WRITE); //write instruction
  address=0;
  spi_transfer((char)(address>>8));   //send MSByte address first
  spi_transfer((char)(address));      //send LSByte address
  //write 128 bytes
  for (int I=0;I<128;I++)
  {
    spi_transfer(buffer[I]); //write data byte
  }
  digitalWrite(SLAVESELECT,HIGH); //release chip
  //wait for eeprom to finish writing
  delay(3000);
  Serial.print('h',BYTE);
  Serial.print('i',BYTE);
  Serial.print('\n',BYTE);//debug
  delay(1000);
}

byte read_eeprom(int EEPROM_address)
{
  //READ EEPROM
  int data;
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(READ); //transmit read opcode
  spi_transfer((char)(EEPROM_address>>8));   //send MSByte address first
  spi_transfer((char)(EEPROM_address));      //send LSByte address
  data = spi_transfer(0xFF); //get data byte
  digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer
  return data;
}

void loop()
{
  eeprom_output_data = read_eeprom(address);
  Serial.print(eeprom_output_data,DEC);
  Serial.print('\n',BYTE);
  address++;
  if (address == 128)
    address = 0;
  delay(500); //pause for readability
}

August 29, 2006, at 08:15 PM by Heather Dewey-Hagborg -
Added lines 30-61:

Now we will write the code to enable SPI communication between the EEPROM and the Arduino. In the setup routine this program fills 128 bytes, or one page of the EEPROM with data. In the main loop it reads that data back out, one byte at a time and prints that byte out the built in serial port. We will walk through the code in small sections.

#define DATAOUT 11//MOSI
#define DATAIN  12//MISO 
#define SPICLOCK  13//sck
#define SLAVESELECT 10//ss

//opcodes
#define WREN  6
#define WRDI  4
#define RDSR  5
#define WRSR  1
#define READ  3
#define WRITE 2 

Here we set up our pre-processor directives. Pre-processor directives are processed before the actual compilation begins. They start with a "#" and do not end with semi-colons.

First we define the pins we will be using for our SPI connection, DATAOUT, DATAIN, SPICLOCK and SLAVESELECT. Then we define our opcodes for the EEPROM. Opcodes are control commands.

byte eeprom_output_data;
byte eeprom_input_data=0;
byte clr;
int address=0;
//data buffer
char buffer [128]; 

Here we allocate the global variables we will be using later in the program. Note char buffer [128];. this is a 128 byte array we will be using to store the data for the EEPROM write.

For easy copy and pasting the full program text of this tutorial is below:


August 29, 2006, at 07:58 PM by Heather Dewey-Hagborg -
Added lines 21-28:

Insert the AT25HP512 chip into the breadboard. Connect 5V power and ground from the breadboard to 5V power and ground from the microcontroller. Connect EEPROM pins 3, 7 and 8 to 5v and pin 4 to ground.

PICTURE of pwr wires

Connect EEPROM pin 1 to Arduino pin 10 (Slave Select), EEPROM pin 2 to Arduino pin 12 (Master In Slave Out), EEPROM pin 5 to Arduino pin 11 (Master Out Slave In), and EEPROM pin 6 to Arduino pin 13 (Serial Clock).

PICTURE of SPI wires

August 27, 2006, at 08:17 PM by Heather Dewey-Hagborg -
Changed line 1 from:

Interfacing a serial EEPROM using SPI

to:

Interfacing a Serial EEPROM Using SPI

Changed lines 12-15 from:

Serial Peripheral Interface

Atmel 25HP512 EEPROM chip

to:

Introduction to the Serial Peripheral Interface

Introduction to Serial EEPROM

August 27, 2006, at 08:14 PM by Heather Dewey-Hagborg -
Added lines 14-18:

Atmel 25HP512 EEPROM chip

August 27, 2006, at 08:11 PM by Heather Dewey-Hagborg -
Changed lines 2-3 from:
to:

(IN PROGRESS)

Added lines 13-16:

Prepare the Breadboard

Program the Arduino

August 27, 2006, at 08:09 PM by Heather Dewey-Hagborg -
Added lines 1-11:

Interfacing a serial EEPROM using SPI

In this tutorial you will learn how to interface with an AT25HP512 Atmel serial EEPROM using the Serial Peripheral Interface (SPI) protocol. EEPROM chips such as this are very useful for data storage, and the steps we will cover for implementing SPI communication can be modified for use with most other SPI devices.

Materials Needed:

  1. AT25HP512 Serial EEPROM chip (or similar)
  2. Hookup wire
  3. Arduino Microcontroller Module

Serial Peripheral Interface

Share