Modifier horloge SPI

Bonjour, je cherche, avec un ARDUINO UNO R3 Rev3 ,a accéder a une carte sd par le spi avec une fréquence d’horloge plus élevé car le fichier à lire dans la carte sd est lourd. J’ai essayé SPI.setClockDivider(SPI_CLOCK_DIV2) (j’ai vu que par défaut la fréquence d’horloge du spi est 1/4 de clock), mais ca ne bouge pas. Quelqu’un peut-il m’aider ?

Merci.

Si ce n’est pas prévu par les fonctions Wiring/Arduino il ne reste qu’une solution : lire la datasheet du micro-contrôleur et le paragraphe traitant du SPI, tout y est décrit.
C’est comme cela que je procèderai, mais je n’ai jamais eu besoin de le faire donc je ne l’ai jamais fait.

hello voir le tableau en page 170 de la data sheet registre SPCR BIT 0 ET 1 ==> SPR1 et SPR0 doivent être à 0 pour une division par 2 [u]si[/u] le bit 0 ( SPI2X ) du registre SPSR est à 1.

à n'utiliser que si uno est en mode maitre

En même temps, pas certain que cela change grand chose. Je ne suis pas certain que la vitesse de lecture de la carte soit le goulot d'étranglement dans cette histoire.

oui, de plus, je viens de tester SPI.setClockDivider(SPI_CLOCK_DIV2); mets bien SPI2X à 1 mais la vitesse ne semble pas suivre

Quand tu parles de vitesse tu entends par là l'horloge ou la vitesse à laquelle les fichiers sont lus par l'Arduino?

le temps avec micros() pour ecrire ou lire un meme fichier avec ips à 1/4 (par defaut) et à 2 par contre je viens de voir que lorsque l'on passe ISP en mode maitre ( bit4 (MSTR) du registre SPCR, il faut que SS\ ( PB2) soit en entrée. je vais poursuivre dans ce sens page 167 de la data sheet. en anglais, ce qui ne me facilite pas les choses :)

C'est pas ça. Lorsque tu es en Master:

  • si la broche SS est en sortie sont état n'affecte pas le fonctionnement du SPI
  • si la broche SS est en entrée si la broche SS est au niveau haut, le SPI fonctionne comme maître si la broche SS est au niveau bas, alors l'automate interne considère qu'un autre maître essaye de prendre la main sur le bus en sélectionnant le SPI et il bascule le mode en esclave.

@FDN merci de ton aide

regarde ce code il ne fait que de l’écriture sur SD dans un fichier test.txt
lance le et regarde ton moniteur

j’ai du mal à croire ce que je voie :slight_smile:

#include <SPI.h>
#include <SD.h>


const int chipSelect = 4;
unsigned long debut = 0;
unsigned long fin = 0;
void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) 
  {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) 
  {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("test.txt");
  debut = micros();
  // if the file is available, write to it:
  if (dataFile)
  {
    dataFile.println("testing 1, 2, 3.");
    // close the file:
    dataFile.close();
  }
  dataFile.close();
  fin = micros(); Serial.println("");
  Serial.print("ecriture 1 ligne en ");Serial.print(fin - debut);Serial.println("  micros");

  // if the file isn't open, pop up an error:
Serial.println("parametres d origine ");
  Serial.print("SPCR : "); Serial.println(SPCR);
  Serial.print("SPSR : "); Serial.println(SPSR);
  Serial.print("DDRB : "); Serial.println(DDRB, HEX);
  SPCR |= ((1 << SPIE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0));
  //DDRB &= ~((1 << DDB0) | (1 << DDB1) | (1 << DDB2) | (1 << DDB3) | (1 << DDB4) | (1 << DDB5));;
  DDRB = B11111111;
  SPSR |= (1 << SPI2X);
  //SPI.setClockDivider(SPI_CLOCK_DIV2);
  Serial.println("parametres modifies");
  Serial.print("SPCR : "); Serial.println(SPCR, HEX);
  Serial.print("SPSR : "); Serial.println(SPSR, HEX);
  Serial.print("DDRB : "); Serial.println(DDRB, HEX);
  //File dataFile = SD.open("test.txt");
  debut = micros();
  // if the file is available, write to it:
  if (dataFile)
  {
    dataFile.println("testing 1, 2, 3.");
    // close the file:
    dataFile.close();
  }
  dataFile.close();
  fin = micros(); Serial.println("");
  Serial.print("ecriture 1 ligne en ");Serial.print(fin - debut);Serial.println("  micros");
  Serial.println("etat des parametres apres ecriture ");
  
  Serial.print("SPCR : "); Serial.println(SPCR, BIN);
  Serial.print("SPSR : "); Serial.println(SPSR, HEX);
  Serial.print("DDRB : "); Serial.println(DDRB, HEX);

}
void loop()
{
  // nothing happens after setup
}

Ach, c’était trop beau :slight_smile:

je n’ouvrais pas le fichier en écriture . retour à la case départ
après modif des paramètres, une écriture eur SD remet les paramètres à leur valeur précédente

#include <SPI.h>
#include <SD.h>


const int chipSelect = 4;
unsigned long debut = 0;
unsigned long fin = 0;
void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) 
  {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) 
  {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
 //File dataFile = SD.open("test.txt");
 File dataFile = SD.open("test.txt", FILE_WRITE);
  debut = micros();
  // if the file is available, write to it:
  if (dataFile)
  {
    dataFile.println("testing 1, 2, 3.4.5.6");
    // close the file:
    dataFile.close();
  }
  dataFile.close();
  fin = micros(); Serial.println("");
  Serial.print("ecriture 1 ligne en ");Serial.print(fin - debut);Serial.println("  micros");

  // if the file isn't open, pop up an error:
Serial.println("parametres d origine ");
  Serial.print("SPCR : "); Serial.print(SPCR,HEX);Serial.print(" ou ");Serial.println(SPCR, BIN);
  Serial.print("SPSR : "); Serial.print(SPSR, HEX);Serial.print(" ou ");Serial.println(SPSR, BIN);
  Serial.print("DDRB : "); Serial.print(DDRB, HEX);;Serial.print(" ou ");Serial.println(DDRB, BIN);
  SPCR |= ((1 << SPIE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0));
  //DDRB &= ~((1 << DDB0) | (1 << DDB1) | (1 << DDB2) | (1 << DDB3) | (1 << DDB4) | (1 << DDB5));;
  DDRB = B11111111;
  SPSR |= (1 << SPI2X);
  //SPI.setClockDivider(SPI_CLOCK_DIV2);
  Serial.println("parametres modifies");
  Serial.print("SPCR : "); Serial.print(SPCR, HEX);Serial.print(" ou ");Serial.println(SPCR, BIN);
  Serial.print("SPSR : "); Serial.print(SPSR, HEX);Serial.print(" ou ");Serial.println(SPSR, BIN);
  Serial.print("DDRB : "); Serial.print(DDRB, HEX);Serial.print(" ou ");Serial.println(DDRB, BIN);
  //File dataFile = SD.open("test.txt");
  dataFile = SD.open("test.txt", FILE_WRITE);
  debut = micros();
  // if the file is available, write to it:
  if (dataFile)
  {
    dataFile.println("testing 1, 2, 3.");
    // close the file:
    dataFile.close();
  }
  dataFile.close();
  fin = micros(); Serial.println("");
  Serial.print("ecriture 1 ligne en ");Serial.print(fin - debut);Serial.println("  micros");
  Serial.println("etat des parametres apres ecriture ");
  
  Serial.print("SPCR : "); Serial.print(SPCR, HEX);Serial.print(" ou ");Serial.println(SPCR, BIN);
  Serial.print("SPSR : "); Serial.print(SPSR, HEX);Serial.print(" ou ");Serial.println(SPSR, BIN);
  Serial.print("DDRB : "); Serial.print(DDRB, HEX);Serial.print(" ou ");Serial.println(DDRB, BIN);

}
void loop()
{
  // nothing happens after setup
}

c’est mieux :slight_smile:

#include <SPI.h>
#include <SD.h>


const int chipSelect = 4;
unsigned long debut = 0;
unsigned long fin = 0;

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) 
  {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

   //SPI.begin();
   //SPI.setClockDivider(SPI_CLOCK_DIV2);
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) 
  {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
 //File dataFile = SD.open("test.txt");
 File dataFile = SD.open("test.txt", FILE_WRITE);
  debut = micros();
  // if the file is available, write to it:
  if (dataFile)
  {
    dataFile.println("testing abcdefghijklmnopqrstuvwxyz");
    // close the file:
    dataFile.close();
  }
  dataFile.close();
  fin = micros(); Serial.println("");
  Serial.print("ecriture 1 ligne en ");Serial.print(fin - debut);Serial.println("  micros");

  // if the file isn't open, pop up an error:
Serial.println("parametres d origine ");
  Serial.print("SPCR : "); Serial.print(SPCR,HEX);Serial.print(" ou ");Serial.println(SPCR, BIN);
  Serial.print("SPSR : "); Serial.print(SPSR, HEX);Serial.print(" ou ");Serial.println(SPSR, BIN);
  Serial.print("DDRB : "); Serial.print(DDRB, HEX);;Serial.print(" ou ");Serial.println(DDRB, BIN);
  SPCR |= ((1 << SPIE) | (1 << MSTR) | (0 << SPR1) | (0 << SPR0));
  DDRB = B00000000;
  SPSR |= (1 << SPI2X);
  //SPI.setClockDivider(SPI_CLOCK_DIV2);
  Serial.println("parametres modifies");
  Serial.print("SPCR : "); Serial.print(SPCR, HEX);Serial.print(" ou ");Serial.println(SPCR, BIN);
  Serial.print("SPSR : "); Serial.print(SPSR, HEX);Serial.print(" ou ");Serial.println(SPSR, BIN);
  Serial.print("DDRB : "); Serial.print(DDRB, HEX);Serial.print(" ou ");Serial.println(DDRB, BIN);
  //File dataFile = SD.open("test.txt");
  dataFile = SD.open("test.txt", FILE_WRITE);
  debut = micros();
  // if the file is available, write to it:
  if (dataFile)
  {
    dataFile.println("testing abcdefghijklmnopqrstuvwxyz");
    // close the file:
    dataFile.close();
  }
  dataFile.close();
  fin = micros(); Serial.println("");
  Serial.print("ecriture 1 ligne en ");Serial.print(fin - debut);Serial.println("  micros");
  Serial.println("etat des parametres apres ecriture ");
  
  Serial.print("SPCR : "); Serial.print(SPCR, HEX);Serial.print(" ou ");Serial.println(SPCR, BIN);
  Serial.print("SPSR : "); Serial.print(SPSR, HEX);Serial.print(" ou ");Serial.println(SPSR, BIN);
  Serial.print("DDRB : "); Serial.print(DDRB, HEX);Serial.print(" ou ");Serial.println(DDRB, BIN);

}
void loop()
{
  // nothing happens after setup
}

Merci pour vos conseils,

Je vais étudier tout cela ce soir, et je vous tiens au courant.

Bonjour,

J'ai testé ton code dfgh en apportant quelques modifications: - mon fichier doit s'ouvri uniquement en lecture ( dataFile = SD.open("test.txt", FILE_READ); - le chip select est sur la broche 10 (SD.begin(10))

J'ai le résultat suivant :

Initializing SD card...card initialized. Test=1 Ouverture du fichier en lecture 73671

lecture fichier en 2918 millis parametres d origine SPCR : 50 ou 1010000 SPSR : 0 ou 0 DDRB : 2C ou 101100 parametres modifies SPCR : D0 ou 11010000 SPSR : 1 ou 1 DDRB : FF ou 11111111 Test=1 Ouverture du fichier en lecture

lecture fichier en 2916 millis etat des parametres apres lecture SPCR : 50 ou 1010000 SPSR : 0 ou 0 DDRB : FF ou 11111111

Rien n'a bougé. J'ai beau lire le datasheet, je n'y comprend pas grand chose. Merci de m'aider !

le code (en écriture, je ne me suis pas occupé de la lecture)

#include <SPI.h>
#include <SD.h>

const int chipSelect = 4;
unsigned long debut = 0;
unsigned long fin = 0;

void setup()
{
  Serial.begin(115200);
  while (!Serial)
  {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  Serial.print("Initializing SD card...");
  pinMode(10, OUTPUT);
  if (!SD.begin(chipSelect))
  {
    Serial.println("Card failed, or not present");
    return;
  }
  Serial.println("card initialized.");
  //1ère ecriture
  File dataFile = SD.open("test.txt", FILE_WRITE);
  debut = micros();
  if (dataFile)
  {
    dataFile.println("testing abcdefghijklmnopqrstuvwxyz");
    dataFile.close();
  }
  dataFile.close();
  fin = micros(); Serial.println("");
  Serial.print("ecriture 1 ligne en "); Serial.print(fin - debut); Serial.println("  micros");
  Serial.println("parametres d origine ");
  Serial.print("SPCR : "); Serial.print(SPCR, HEX); Serial.print(" ou "); Serial.println(SPCR, BIN);
  Serial.print("SPSR : "); Serial.print(SPSR, HEX); Serial.print(" ou "); Serial.println(SPSR, BIN);
  Serial.print("DDRB : "); Serial.print(DDRB, HEX); Serial.print(" ou "); Serial.println(DDRB, BIN);
  SPCR |= ((1 << SPIE) | (1 << MSTR) | (0 << SPR1) | (0 << SPR0));
  DDRB = B00000000;
  SPSR |= (1 << SPI2X);
  //SPI.setClockDivider(SPI_CLOCK_DIV2);
  Serial.println("parametres modifies");
  Serial.print("SPCR : "); Serial.print(SPCR, HEX); Serial.print(" ou "); Serial.println(SPCR, BIN);
  Serial.print("SPSR : "); Serial.print(SPSR, HEX); Serial.print(" ou "); Serial.println(SPSR, BIN);
  Serial.print("DDRB : "); Serial.print(DDRB, HEX); Serial.print(" ou "); Serial.println(DDRB, BIN);
//2ème ecriture
  dataFile = SD.open("test.txt", FILE_WRITE);
  debut = micros();
  if (dataFile)
  {
    dataFile.println("testing abcdefghijklmnopqrstuvwxyz");
    dataFile.close();
  }
  dataFile.close();
  fin = micros(); Serial.println("");
  Serial.print("ecriture 1 ligne en "); Serial.print(fin - debut); Serial.println("  micros");
  Serial.println("etat des parametres apres ecriture ");
  Serial.print("SPCR : "); Serial.print(SPCR, HEX); Serial.print(" ou "); Serial.println(SPCR, BIN);
  Serial.print("SPSR : "); Serial.print(SPSR, HEX); Serial.print(" ou "); Serial.println(SPSR, BIN);
  Serial.print("DDRB : "); Serial.print(DDRB, HEX); Serial.print(" ou "); Serial.println(DDRB, BIN);
}
void loop()
{
  // nothing happens after setup
}

et une copie écran

SD.png

OK,

Tu mets tous le bits de DDRB à 0, or j'ai lu dans le datasheet que les bits 5,4,3,2 servent à mettre les pins SCK,MISO,MOSI et SS en input ou output. En mode Master : SCK en output, MOSI en output. Pourquoi ca marche quand tu mets tous les bits de DDRB à 0 ?