Dernière mise à jour le 05/01/2021

Présentation


Dans cette rubrique nous allons nous intéresser sur la lecture d’une carte SD (fichier .txt uniquement) et d’envoyer ces données sur le port USB.
j’ai refait un copié collé de ce qui avait été dis précédemment sur la carte MMC/SD ce copié collé n’est là uniquement que pour rappel. Si vous voulez sauter cette étape allez directement voir le schéma.

Besoin de plus de mémoire supplémentaire que l’EEPROM? La carte MMC / SD dispose d’un emplacement pour carte MMC / SD pour les cartes MMC ou SD. Nous allons nous intéresser, sur comment faire pour écrire sur une carte SD via le MMC/SD Board de MikroElectronika que vous voyez ci-dessus. Cette carte permet de connecter une carte SD type MMC (ou SD) (voir ci-dessous).

 

Vous pouvez bien sûr mettre une mini SD à condition d’avoir l’adaptateur qui lui est souvent livré lors de l’achat de la mini SD (encore ci-dessous).

Nous allons voir comment réaliser un tel montage electronique via la platine EasyPic V7 en utilisant un PIC 18F4550, puis nous ferrons quelques branchement via des fils de liaison afin d’interconnecté la carte MMC/SD sur les broches du PIC.

Raccordement du MMC/SD sur la platine EasyPIC V7



(Clique pour agrandir)

La carte dispose d’une nappe qui comporte un connecteur (CN11 tout à gauche en haut) 10 broches puis un switch (SW1 tout à gauche en bas) avec 8 postions possibles. Ces postions qui vont nous concerner sont les positions 1/4/6 – (P1/P5/P3)  et ces petits interrupteurs doivent se retrouver en position haut dirigées vers le “ON” pour l’utilisation de PICs . Les autres interrupteurs ne nous concerne pas car la carte MMC/SD peut être utilisée pour d’autres microcontrôleurs type AWR8081 ou bien des dsPIC.

Une fois nos 3 petits switchs (1/4/6) en position “ON” regardons de plus prêt le connecteur CN11 qui je le dis au passage sera raccordé sur le PORTD de la platine EasyPic V7.

ATTENTION – CN11 !!

Il faut faire attention lors du branchement afin de ne pas inverser le toron et de vous retrouver avec le +VCC relié à la masse ! pour éviter cet incident, le branchement doit se faire à ce que votre platine EasyPicV7 soit en face de vous, et que la carte MMC/SD soit mis dans une position à ce que le cavalier (+5V/3,3V) soit positionné vers le  bas comme le montre la photo ci-dessous:


(Clique pour agrandir)

Branchement des fils de liaisons – MMC/SD vers PIC18F4550


Les fils de couleurs ci-dessus, ne correspondent pas à la photos ci-dessous, j’aurais dû faire une effort pour que le fils entre RD3 et RB1 soit (noir), que le fil entre RD5 et RC7 soit (rouge), entre RD4 et RB0 soit (bleu) et pour finir RD0 et RC0 soit (vert). Nous allons maintenant aborder la partie connexion entre le PIC 18F4550 et notre carte MMC/SD. Nous avons uniquement branché le connecteur CN11 sur le PORTD de notre platine (pour ceux qui auraient sauté une étape je le rappel au passage ;-)), mais il reste maintenant à relier vers les broches du PIC.  Pour cela il faut vous munir de 4 fils femelles avec ce type de connexion ci-dessous:

  • Relier broches RD0 à RC0
  • Relier broches RD4 à RB0
  • Relier broches RD3 à RB1
  • Relier broches RD5 à RC7

Pour connecter le connecteur CN11 sur la platine, j’ai été dans l’obligation de réaliser (en fils volant) l’alimentation des différents PORTS de ma platine afin d’effectuer les connexions sur les différents broches du PIC 18F4550.


  (Clique pour agrandir)       (Clique pour agrandir)

FAT 12/16 ou FAT32 ? qu’est-ce que c’est?


En anglais FAT (File Allocation Table – table d’allocation de fichiers).La table d’allocation de fichiers est en fait un index qui liste le contenu du disque, afin d’enregistrer l’emplacement des fichiers sur celui-ci. Etant donné que les blocs qui constituent un fichier ne sont pas toujours stockés de manière contiguë sur le disque (c’est ce que l’on appelle la fragmentation), la table d’allocation permet de conserver la structure du fichier en créant des liens vers les blocs constitutifs du fichier. Le système FAT est un système 16 bits permettant de décrire un fichier par un nom d’une longueur de 8 caractères et une extension qui en comporte 3. On appelle ainsi ce système FAT16.
Pour améliorer ce point, la version originale de Windows 95 (employant le système FAT16) a été dotée d’une prise en charge améliorée de la FAT, il s’agit du système VFAT (Virtual FAT). La VFAT est un système 32 bits permettant d’enregistrer un fichier avec un nom de 255 caractères de long. Les programmeurs ont toutefois dû veiller à la compatibilité ascendante, de telle façon a pouvoir accéder à ces fichiers à partir d’environnements 16 bits (DOS). La solution a donc été d’affecter un nom pour chaque système. C’est la raison pour laquelle il est possible d’utiliser des noms longs sous Windows 95, tout en pouvant y accéder sous DOS.


Le système de fichiers FAT est un système 16 bits, cela signifie qu’il ne peut pas adresser les clusters sur plus de 16 bits. Le nombre maximum de clusters repérables avec le système FAT est ainsi de 216, soit 65536 clusters. Or, étant donné qu’un cluster est constitué d’un nombre fixé (4,8,16,32, …) de secteurs de 512 octets contigüs, la taille maximale d’une partition FAT se trouve en multipliant le nombre de clusters par la taille d’un cluster. Avec des clusters d’une taille 32Ko, la taille maximale d’une partition FAT est donc de 2Go.


D’autre part, un fichier ne peut occuper qu’un nombre entier de clusters, c’est-à-dire que si un fichier occupe plusieurs clusters, le dernier sera occupé en partie, et la place inoccupée restante est autant de place perdue. Par conséquent plus la taille d’un cluster est réduite, moins il y a de gaspillage de place. On estime qu’un fichier gaspille en moyenne la moitié d’un cluster, cela signifie que sur une partition de 2Go 16Ko seront perdus par fichier… Le formatage des cartes mémoire est recommandé par presque tous les experts en technologie du monde entier.


Les cartes SD sont principalement utilisées dans les appareils photo numériques et les téléphones cellulaires. Les fabricants d’appareils photo numériques recommandent le formatage à l’intérieur de l’appareil photo lui-même. C’est un moyen d’initialiser la carte SD.


Faisons simple !

Si la carte est de 2 Go ou inférieure à 2 Go, vous pouvez la formater en FAT 12/16 ou FAT(tout court) mais si la carte est supérieure à 2 Go, vous devez la formater (bien sûr il faut que votre ordinateur soit équipé d’un lecteur de carte SD !) en FAT 32. Il suffit de faire un clique droit sur votre carte SD et de selectionner “Formater” (windows 10 vous rendre dans “CE PC” et normalement vous derviez voir voir carte SD connectée, il suffit de faire un clique droit sur cette dernière et de selectionner “formater” )

Schéma



(Clique pour agrandir)

On remarque sur ce schéma qu’il y’a en entrée la carte MMC/SD de Mikroelectronika (à gauche), au milieu le coeur du montage cadencé par un quartz de 8Mhz afin de faire tourner le PIC1

Le logiciel disponible sur ce lien Interface UsbHid Affichage texte qui je tiens à signalé à été amélioré, vous permettrons de voir les données que le port USB va envoyer sur le bus USB.

Il s’agit ici d’un exemple, car la lecture du fichier (.txt) est réalisée uniquement si et seulement si le fichier se nomme “Carte_SD_TXT”. Oui, puisque c’est bien celui-ci qui est appelé dans le programme.

Programmation materiel – MikroC


Niveau réglages de l’horloge, ce rendre dans la barre des taches de MikroC faire “Project” ensuite “Edit Project” et régler l’horloge interne avant d’exécuter le code qui va suivre pour le bon fonctionnement de l’ecrture de la carte SD. Ne pas oublier de désactiver la broche MCLR 😉 (voir capture ci-dessous). et pour finir je vous laisse vous rendre sur ce lien Configuration port USB – VID/PID pour le VID PID (pour ma part je ne change pas j’utilise toujours PID = 1234 et VID = 0001)

// Lecteur carte MMC/SD UsbHid – MikroC – Electronique71.com

#define TRUE 1
#define FALSE 0

unsigned char readbuff[64] absolute 0x500;// Les tampons doivent être dans la RAM USB
unsigned char writebuff[64] absolute 0x540;

// Module de connection de la carte MMC/SD
sbit Mmc_Chip_Select at LATC0_bit;
sbit Mmc_Chip_Select_Direction at TRISC0_bit;

unsigned char Stop_Ecriture_HID = FALSE;
int iCountChar = 0;
char Lecture;
int i;

void interrupt()
{
  USB_Interrupt_Proc(); // La maintenance USB est effectuée à l'intérieur de l'interruptio
}


void init()
{
  // On configure de toutes les broches en digital (numérique 0 ou 1)
  PCFG0_bit = 1;
  PCFG1_bit = 1;
  PCFG2_bit = 1;
  PCFG3_bit = 1;

  CMCON = 0x07; // On désactive les comparateurs

  ADON_bit = 0; // On désactive le module de convertion analogique/numérique

  TRISA = 0xC2; // RA2 config comme entrée pour ecrire sur la carte + RA6/RA7
  PORTA = 0x00;
  LATA = 0x00;

  HID_Enable(&readbuff,&writebuff); // Initalisation USB

  Delay_ms(100); // On attend un peu la fin de l'initialisation de l'activation USB

  // Initialisation du module SPI1;
  SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV64,
                     _SPI_DATA_SAMPLE_MIDDLE,
                     _SPI_CLK_IDLE_LOW,
                     _SPI_LOW_2_HIGH);

  Lecture = FALSE; // Ecriture non réalisée

  Delay_ms(100); // Attendre l'initialisation de la liaison SPI (pour carte SD)
}


// Fonction pour l'écriture caractère par caractère sur le port USBHID
void Ecriture_Char(unsigned char* buffer_USBHID)
{

  // On boucle sur un seul éléments du tableau (buffer_USBHID)
  for(i = 0 ; i < 1  ; ++i)
  {
    writebuff[i] = buffer_USBHID[i]; // On copie dans le buffer USBHID
  }

  HID_Write(&writebuff,64); // Ecriture sur le port USB
}


// Fonction pour la lecture carte SD
void Lecture_SD()
{
  unsigned char i;
  unsigned long size; // Correspond à la taille du fichier (.txt)
  unsigned char character;
  unsigned char buffer_USBHID[1] = {0}; // Buffer pour 1 seul élement

  // On initialise la carte SD lors de la connection
  if (!Mmc_Fat_Init())
  {
    Mmc_Fat_Assign("Card_SD.TXT",0x01); //Card_SD.TXT -> doit être de 11 caractères MAXI
    Mmc_Fat_Reset(&size); // On récupère la taille du fichier (.txt)

    for (i = 0; i < size ; i++)
    {
      Mmc_Fat_Read(&character); // Lecture de la carte SD (par pointeur !)

      buffer_USBHID[0] = character;

      Delay_ms(20); // attendre minimum 20ms pour chargement caractère dans Buffer

      Ecriture_Char(buffer_USBHID); // Ecriture

      buffer_USBHID[0] = 0; // On remet à zéro le buffer
    }
  }
}


// Programme principal
void main()
{
  init();

  while (1)
  {
     if ((PORTA.RA1 == 1) && (Lecture == FALSE))
     {
       Lecture = TRUE;
       Lecture_SD(); // Lecture carte SD
     }
     else if ((PORTA.RA1  == 0) && (Lecture == TRUE))
     {
       Lecture = FALSE;
     }
   }
}


Fonctionnement général

Le principe de fonctionnement est le suivant. Chaque fois que vous pressez le bouton RA1 du PORTA, la lecture et l’écriture est réalisée, et vous pouvez d’ailleurs observer l’affichage des données via ce logiciel téléchargeable directement en cliquant ici.

Fonctionnement détaillé

Côté programmation en C nous allons regarder ça de plus prêt:

Programme principal (void Main)

Dans cette fonction nous y trouvons tout d’abord la fonction init() qui dans un 1er temps va initialiser le PIC18F4550 c’est la 1er fonction qui sera exécutée à la mise sous tension de microcontrôleur (PORT/SPI/USB)
Ensuite, nous allons rentrer dans la boucle while(1) qui celle-ci tournera en permanence avant l’arrêt complet du PIC (mis hors tension).
Lorsque nous allons appuyer sur le bouton RA1 de la platine EasyPICV7, nous allons passer la variable « Lecture » à TRUE en indiquant qu’une lecture sera sur le point d’être lancée ce qui empêchera à la boucle while (qui tourne très vite) de retourner là ou nous nous situons en ce moment (la variable Lecture qui était à FALSE est maintenant à TRUE).
Ensuite viens l’appel de la fonction « Lecture_SD » qui comme vous l’aurez compris va faire le travail sur la partie lecture de la carte SD (voir détails plus bas).
Lorsque vous relâcher le bouton – avant/pendant ou après la lecture, vous allez repasser la variable “Lecture” à l’état FALSE cette fois-ci (cela concerne la ligne précédente du code).
Il faudra donc appuyer une 2ème fois pour relancer la lecture si et seulement si la lecture de la carte SD est terminée. Bien entendu cette lecture peut durer quelque minutes avant de pouvoir la relancer de nouveau.



Fonction Lecture (void Lecture_SD)

Dans cette fonction, nous y retrouvons ;

Mmc_Fat_Assign(“Card_SD.TXT”,0x01)
qui est une fonction pour assigner ou plutôt dirais-je de récupérer le fichier existant sur la carte SD en l’occurrence (“Card_SD.TXT”) avec 0x01 pour dire que nous faisons simplement une lecture seule du fichier sans le modifier (ouverture du fichier en lecture seule).

Mmc_Fat_Reset(&size)
permet de récupérer la taille du fichier plus précisément cela donne le nombre de caractère présent dans le fichier (*.txt) il peut y en avoir très peut comme il peut en avoir beaucoup ce qui fera gonfler la taille du fichier (.txt)

Mmc_Fat_Read(&character)
Lit un octet du fichier actuellement attribué ouvert en lecture (via Mmc_Fat_Assign) . Lors de l’exécution de la fonction, les pointeurs (&) du fichier seront positionnés sur le caractère. Ainsi lors de l’exécution de cette fonction, l’octet de lecture est renvoyé via ce paramètre nommé character (son nom peut bien sûr être modifié).

buffer_USBHID[0] = character
on va gentiment recopier ce caractère qui concerne le 1er octet de 8 bits dans le buffer à l’emplacement[0]

Delay_ms(20)
  on ralentit de 20 ms entre la réception du caractère récupérer dans le fichier et l’écriture sur le port USB. Pour ne pas compliquer je ne suis pas passé par les interruptions et préféré faire ainsi ! la diminution de cette tamporisation de 20ms risque de faire dérailler l’ecriture et provoquer des caractèred un peu bizarre… je vous laisse essayer…

Ecriture_Char(buffer_USBHID[0])
On envoi le buffer dans la fonction et on fait appel à celle-ci.



Fonction Lecture (Ecriture_Char(unsigned char* buffer_USBHID))

La dernière étape qui est une boucle sur 1 seul élément du tableau, oui forcément buffer_USBHID = buffer_USBHID[0] soit 1 élement du tableau recopier dans le buffer du port USB.

writebuff[i] = buffer_USBHID[i]
de nouveau on place le caractère de 1 octet (8bits) dans le buffer du port USB.

HID_Write(&writebuff,64
) et pour finir on envoi notre caractère sur le port USB qui comporte quant à lui 64 élements … Laissons maintenant faire le logiciel « Interface UsbHid Affichage texte » qui fera le travail derrière

Test sur platine EasyPicV7


Oui testé bien entendu!!, et testé aussi avec un fichier (.txt) à condition qu’il se nomme “Carte_SD.TXT” (bien entendu vous pouvez changer de nom à condition que la totalité des caractères soient de 11 et pas un de plus!), j’ai visualisé l’affichage mais étant données que le traitement des données sont de 20ms ça peut devenir long si vous lisez un gros fichier. Ne pas diminuer cette petite temporisation car la sychronisation entre MMC/SD et l’ecriture sur le port USB ne sera plus synchronisé et vous allez aperçevoir de drôles de symboles…

Historiques


05/01/2021
-1er mise à disposition