Claro que sí, puedo intentarlo.
Antes que nada, quiero aclararte que cuando copié el código cometí el error de pegarlo y no me di cuenta que iba a ser interpretado como código html. En la línea for(i=0;i<512;i++)data=0x20; no aparece lo que ves en rojo en esta línea for(i=0;i<512;i++)data
[i]=0x20;
lo que está en rojo fue interpretado como código html (que indica que la letra aparezca en cursiva
) y desapareció de la pantalla.
Esa sola línea es todo el bucle for, y por ser una sola línea no es obligatorio poner llaves. Lo que hace esa línea es llenar el vector data con el valor 0x20.
La línea sd_Write(0x1fa00,&data); está fuera del bucle for.
Lamento el error.
Por otra parte, y creo que de ahí viene tu pregunta, lo que se aplica en la línea sd_Write(0x1fa00,&data); es el concepto de punteros, que es una característica fundamental del lenguaje C. Es sin duda lo que provoca los mayores dolores cuando empiezas con este lenguaje, pero cuando lo manejas bien es una gran herramienta.
Cuando pones el operador "&" antes de una variable (en este caso un vector, &data), le estas diciendo al compilador que lo que querés no es el valor que contiene la variable sino la dirección de memoria en donde esta está almacenado el valor de esa variable. Esto es muy útil, ya que a priori, no sabemos en que posición de memoria el compilador ubicará a esa variable.
ejemplo:
supongamos que defino un par de variables
char mi_variable=15;
int tmp;
y supongamos que el compilador ubica la variable "mi_variable" en la posición 0x0f8.
Luego, si escribo este código:
tmp=mi_variable; tmp contiene el valor 15
pero si escribo este código:
tmp=&mi_variable; tmp contiene el valor 0x0f8
Si mi_variable fuese un vector, 0x0f8 sería la dirección de memoria del primer elemento del vector.
En el caso de la función sd_Write(0x1fa00,&data); yo estoy pasando como argumento de la función, dos valores, uno es una constante 0x1fa00, y el otro es la dirección de memoria del primer elemento del vector data[];
Esto es el primer paso.
Ahora, lo que no ves en este código es la definición de la función sd_Write y ahí está la otra parte del truco.
El prototipo de esta función es asi:
sd_Write(unsigned long long dir,unsigned long long *buffer );Como ves, "dir" es una variable local "normal". En este caso recibe el valor 0x1fa00 que le paso como primer argumento cuando llamo a la función. El segundo argumento (buffer) tiene delante un *. Esto le dice al compilador que lo que quiero usar no es el vaor que recibo, sino que lo que recibo es la direción de memoria donde se encuentra almacenado el valor que quiero usar. Es decir, buffer apunta (puntero) a la dirección de memoria donde está el valor que necesito usar. A ver si lo puedo resumir
en la llamada sd_Write(0x1fa00,&data);
el segundo argumento no es el valor de data, sino la dirección de memoria en donde está almacenado. Luego *buffer le dice al compilador: en "esta dirección" (buffer) está el valor que quiero usar, ve y tráelo.
Ahora, ¿por qué es tan útil este enriedo? porque si incremento (*buffer) estoy apuntando a la siguiente posición de memoria, estoy accediendo a la memoria donde se encuentra el segundo valor del vector data[]. Y si haces algo como esto.
for(j=0;j<512;j++){
WriteSPI( *(buffer + j) );
}
Estás mandando por SPI secuencialmente cada valor del vector data[], ya que (una vez más), *buffer indica la dirección donde ir a buscar el valor que me interesa.
Nunca me resulta fácil explicar esto, pero lo sigo intentando
Pero si no entendiste nada, no te desanimes, no es difícil, sólo es cuestión de dar con la explicación adecuada. Hay excelentes tutoriales en este foro y en toda la web, con miles de ejemplos más claros que este. Espero haber ayudado.