initialisation carte sd par pic18f4550
Répondre à la discussion
Affichage des résultats 1 à 6 sur 6

initialisation carte sd par pic18f4550



  1. #1
    skydarc

    initialisation carte sd par pic18f4550


    ------

    bonjour,

    je suis nouveau dans la programmation des pic en C. je me lance dans une application a base de pic18f4550 et de carte sd. pour le moment je commence simplement par l'initialisation du port SPI. voici mon code :

    Code:
    #include <p18f4550.h> //head file.
    #include <spi.h>
    
    #define cs LATCbits.LATC6 //define sd pin.
    #define SSPIF PIR1bits.SSPIF
    
    unsigned char r1=0;
    
    void delay_100ms(void);
    void spi_init(void); //spi init
    void spi_low(void); //produce low band func(sd card init use.)
    void spi_high(void); //produce high band func(sd card init use.)
    unsigned char sd_reset(void); //sd card init func
    unsigned char SD_SendCommand(char CMD,char ARG1,char ARG2,char ARG3,char ARG4,char CRC); //write sd card command func
    unsigned char SPI_WriteByte(unsigned char val); //write one byte func.
    void delay(void); //delay func.
    
    /////////////////////////////////////////////////
    //main
    void main()
    {
    unsigned char loop,res;
    
    //On désactive l'acquisition analogique
    ADCON0=0x0f;
    ADCON1=0x0f;
    
    OpenSPI(SPI_FOSC_64, MODE_11, SMPEND);
    
    while(1)
    {
    res= sd_reset(); //sd card init.
    if(res) break; //if init is abnormal,exit and don't perform the next func.
    printlcd('3');
    
    }
    
    }
    
    ////////////////////////////////////////////////
    //spi init
    void spi_init()
    {
    //TRISCbits.TRISC7=0; // SDO declarer en sortie
    //TRISBbits.TRISB1=0; //SCK est declarer en sortie sur le maitre
    //TRISBbits.TRISB0=1; //SCK est declarer en sortie sur le maitre
    //TRISC=0xd0; //set SDI as input£¬other port c are output.
    //TRISD=0X00; //set port d as output.
    //TRISA=0X00; //set port a as output.
    //ADCON1=0X07; //set port a as ordinary i/o.
    SSPCON1=0x32; //high when idle.fosc/64
    SSPSTAT=0x80; // rising edge,send data.
    cs=1;
    //SSPSTAT = SSPSTAT & 0b00111111; // registre port spi mode 11 osc/64
    //SSPCON1 = 0b00110010; //clock middle
    //LATCbits.LATC0=0;
    //LATCbits.LATC1=0;
    //PORTA=0XFF;
    }
    
    unsigned char SD_SendCommand(char CMD,char ARG1,char ARG2,char ARG3,char ARG4,char CRC)
    {
    unsigned char r1;
    unsigned char retry1=0; //repeat count.
    cs=0; //enable cs signal.
    
    SPI_WriteByte(CMD); //write command.
    SPI_WriteByte(ARG1);
    SPI_WriteByte(ARG2);
    SPI_WriteByte(ARG3);
    SPI_WriteByte(ARG4);
    SPI_WriteByte(CRC); //CRC check sum.
    
    while((r1 = SPI_WriteByte(0xff)) == 0xff)//wait ack.
    if(retry1++ > 100) break; //overtime exit.
    
    cs=1; //clear cs.
    
    return r1; //return the status value.
    }
    
    
    ////////////////////////////////////////////////
    //set low band.
    void spi_low()
    {
    SSPCON1=0x32; //SPI clk use the system clk--fosc/64 0x32
    }
    
    ////////////////////////////////////////////////
    //set high band.
    void spi_high()
    {
    SSPCON1=0x31; //SPI clk use the system clk--fosc/64 0x31
    }
    
    ///////////////////////////////////////////////
    //write one byte.
    unsigned char SPI_WriteByte(unsigned char val)
    {
    SSPBUF = val; //load to send buffer
    while(!SSPIF); //wait to finish sending.
    SSPIF=0; //clear send finish flag.
    return SSPBUF; //read the receive buffer(even the data is unvalid,it is still need cleared.)
    }
    
    ////////////////////////////////////////////////
    //SD reset.
    unsigned char sd_reset()
    {
    unsigned char i,tmp;
    unsigned char retry; //repeat times.
    
    retry=0;
    
    spi_low(); //use low band.
    
    do
    {
    cs=1;
    for(i=0;i<10;i++) SPI_WriteByte(0xff);
    delay_100ms();
    cs=0;
    delay_100ms();
    r1=SD_SendCommand(0x40,0,0,0,0,0x95);
    
    retry++;
    //if(retry>10) return 1; //overtime exit.
    } while(r1 != 0x01); //wait IDLE command return.
    
    retry = 0;
    
    do
    {
    for(i=0;i<100;i++) SPI_WriteByte(0xff);
    
    //r1 = SD_SendCommand(1, 0); //send Active command.
    r1 = SD_SendCommand(0x41,0,0,0,0,0xff);
    retry++;
    if(retry>100) return 1; //overtime exit.
    } while(r1); //wait Active command exit.
    spi_high(); //use high band.
    
    
    return 0; //return normal.
    }
    
    ///////////////////////////////////////////////
    //
    void delay() //
    {
    int i; //
    for(i=0x100;i--;); //
    }
    
    void delay_100ms()
    {
    int i;
    for(i=0;i<=9;i++)
    {
    Delay10TCYx( 5);;
    
    }
    }






    je pense avoir tout fait comme il fallait, mais apparemment pas puisque cela ne marche pas. je précise que je code en MCC18. Que ce code et inspiré de nombreuses sources sur le net et qu'un programme fonctionnel pour pic16f877a.

    je me demande si le problème ne viendrait pas d'une erreur de config du port spi (histoire de fréquence ou quelque chose du genre).

    lorsque que j'exécute en mode debug sous mplab soit je ne reçois pas de confirmation du flag SSPIF, soit la réponse renvoyée par la carte n'est pas 0x01 m'indiquant le passage en mode IDLE.

    je suis un peu perdu avec tout ca. j'attends vos suggestion. soyez indulgent s'il vous plait et surtout compréhensif pour en un jeune padawan qui ne demande qu'a apprendre

    -----

  2. #2
    invitea613d208

    Re : initialisation carte sd par pic18f4550

    Salut,

    Il y a quelque chose qui me chagrine dans ton code. On dirai qu'il y a un melange de code pour MCC18 et pour CCS.

    Tu utilises une fonction predefinie à un moment dans ton code

    Code:
    SPI_WriteByte(CMD); //write command.
    SPI_WriteByte(ARG1);
    SPI_WriteByte(ARG2);
    SPI_WriteByte(ARG3);
    SPI_WriteByte(ARG4);
    SPI_WriteByte(CRC); //CRC check sum.
    Ce qui laisser presager que ton compilateur a pas mal de fonctions définies, mais ta fonction delai tu la fait toi même !?? Je pense qu'il y a un petit melange de code dans tout sa.

    OpenSPI(SPI_FOSC_64, MODE_11, SMPEND);
    Où as tu trouvé cette fonction ?

    Sinon il faut que tu reprennes le Datasheet pour ce PIC là et que tu regarde precisement la marche a suivre pour l'initialisation du SPI

    Bye

  3. #3
    skydarc

    Re : initialisation carte sd par pic18f4550

    merci pour la réponse. c'est très sympa.

    pour la fonction OpenSPI(), elle est tirée de l'include spi.h fournit avec MCC18, donc je ne pense pas que le problème vienne de la. même si je n'exclue pas un souci dans l"init du port SPI.

    pour les autres fonctions c'est vrai que c'est un peu le foutoir. je n'ai pas encore nettoyé le code (fonction init_spi() inusité remplacer par openspi() ). c'est pour cela que ca te semble le bordel lol.

    en tout ca je n'ai pas de problème a l'utilisation et je ne crois pas m'être inspiré de code ccs.

    je vais repotasser le datasheet du 4550 pour voir si il y a des infos qui me sont passées à coté.

    encore merci pour la reponse

  4. #4
    skydarc

    Re : initialisation carte sd par pic18f4550

    je reviens avec du neuf pour mon problème.

    après moult essais, j'ai tester mon programme avec une carte SDHC de 8giga (celle de mon eos ) et la miracle ca fonctionne.

    j'ai bien le retour R1 correspondant à 0x01 (cela dit lorsque j'envoie la commande CMD8 j'ai pour retour 0x05 et non 0x01 suivit de 32 bits).

    si je ne me trompe pas ce doit donc être un problème d'horloge c'est pour cela que la carte sdch étant plus véloce, celle-ci peut répondre... non?

    pourtant j'ai baissé la fréquence lors de l'init par :
    OpenSPI(SPI_FOSC_32, MODE_11, SMPEND); (ou d'autres config d'ailleurs)
    au lieu de
    OpenSPI(SPI_FOSC_64, MODE_11, SMPEND);

    mais rien n'y fait je n'est pas de retour correcte de r1

  5. A voir en vidéo sur Futura
  6. #5
    invite7a49d0d5

    Cool Re : initialisation carte sd par pic18f4550

    Salut

    Citation Envoyé par skydarc Voir le message
    (...)
    si je ne me trompe pas ce doit donc être un problème d'horloge c'est pour cela que la carte sdch étant plus véloce, celle-ci peut répondre... non?(...)
    comment est configurée l'horloge du 4550?
    quel quartz?
    quelle configuration des fusibles (HS,PLL,DIV...)?
    quelle Fosc espérée?

    vede
    ;O]
    _______
    ...

  7. #6
    invite7a49d0d5

    Cool Re : initialisation carte sd par pic18f4550

    ps :

    un exemple fonctionnel de configuration des fusibles du 4550 (édités avec MikroC PRO 3.8)
    pour fonctionner avec un quartz 4Mhz, et avoir une Fosc = 48Mhz (via PLL et DIV...)...
    http://vede.free.fr/electronique/fuses4550.gif
    ...

Discussions similaires

  1. [Blanc] LV Ariston LV 620 : initialisation carte bit 100 !
    Par invitedfbb856a dans le forum Dépannage
    Réponses: 15
    Dernier message: 23/02/2010, 16h50
  2. Initialisation à l'allumage
    Par invite6de5f0ac dans le forum Électronique
    Réponses: 3
    Dernier message: 30/04/2009, 13h40
  3. initialisation du PCF8583
    Par invite28559ad9 dans le forum Électronique
    Réponses: 3
    Dernier message: 23/12/2008, 21h44
  4. envoyer float par USB- PIC18f4550
    Par inviteb7e0a565 dans le forum Électronique
    Réponses: 9
    Dernier message: 28/07/2008, 21h18
  5. Initialisation d'un LCD
    Par Toufinet dans le forum Électronique
    Réponses: 12
    Dernier message: 24/05/2006, 21h30
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...