PIC, SD Card and MikroC

General discussion on mikroC.
Post Reply
Author
Message
Velimir
Posts: 15
Joined: 02 Jun 2010 07:24

PIC, SD Card and MikroC

#1 Post by Velimir » 14 Aug 2010 18:05

Hello everyone.
I have a problem with the SD card. It is about using microcontrollers and AD convergence value reads and writes them on the card. I make every second reading.
The problem arises when I create several files on the card. If, for example to 3547 by entering the card is 3754 entries. I use ready-made functions mikroC-a: Mmc_Fat_Write and Adc_Read.

Does anyone have similar experience?
Any assistance would have come good.

I speak little English, I hope I'm able to explain what the problem is.

Thanks in advance.

Hello, Velimir.

Sobrietytest
Posts: 619
Joined: 05 Jul 2008 06:05
Location: Thailand

Re: PIC, SD Card and MikroC

#2 Post by Sobrietytest » 14 Aug 2010 22:31

Hi Velimir, what exactly is the problem? You have told us that something is wrong but you did not explain why! I can guess what is wrong but you should post your code so that we can help you.

ST.

Velimir
Posts: 15
Joined: 02 Jun 2010 07:24

Re: PIC, SD Card and MikroC

#3 Post by Velimir » 14 Aug 2010 23:05

Sobrietytest wrote:Hi Velimir, what exactly is the problem? You have told us that something is wrong but you did not explain why! I can guess what is wrong but you should post your code so that we can help you.

ST.
Thank you for your interest.
The task for me to create three files to the SD card, and each file to type certain information. I make every second entry.
When I create several files on the card are strange things happening, write some strange numbers. This is shown in the first text. document. Another document shows how the text should look like.
I have attached by the program and text documents.

[*][*]

Code: Select all

#include <built_in.h>

 //------------INICIJALIZACIJA PROMENLJIVIH--------------------;
 
unsigned short mmc_errort,brojac_ivica;
unsigned short loop,loop2,brzina;

char file_content_n[11];
char file_content_s[9];
char file_content_b[11];
char Ime_strujnog_Fajla[10];
char Ime_Fajla_Za_Brzinu[10];
char Ime_Naponskog_Fajla[10] ;
unsigned long tlong;
char ch;
unsigned long Mereni_Napon;
signed long Merena_Struja;
char txt[15], merena[15];

 //-------KREIRANJE FAJLA NA SD KARTICI U KOJI UPISUJE VREDNOSTI STRUJE---- ;
 void Kreiranje_Fajla_Struja() {
 //-------IME FAJLA--------------------------------------------------------- ;
  Ime_strujnog_Fajla[0] = 'S';
  Ime_strujnog_Fajla[1] = 'T';
  Ime_strujnog_Fajla[2] = 'R';
  Ime_strujnog_Fajla[3] = 'U';
  Ime_strujnog_Fajla[4] = 'J';
  Ime_strujnog_Fajla[5] = 'A';
  //------PROVERA DA LI FAJL POD OVIM IMENOM VEC POSTOJI, AKO POSROJI UPISUJE U NJEGA PODATKE,
  // A AKO NE POSTOJI KREIRA NOVI FAJL POD TIM IMENOM-----------------------;
 Mmc_Fat_Assign(&Ime_strujnog_Fajla, 0xA0);
   //--------- VRAÆA PROMENLJIVU NA NULI------------------------------------:
   Merena_Struja=0;

   //-----------AD ÈITANJE-----------;
     Merena_Struja=Adc_Read(0);
     Merena_Struja = Merena_Struja*5/1023;

     if (Merena_Struja >=2.5){                 // UKOLIKO JE STRUJA POZITIVNA
        Merena_Struja =(Merena_Struja -2.5)*200;

  file_content_s[0] = Merena_Struja/100;
  Merena_Struja = Merena_Struja%100;
  file_content_s[1] = Merena_Struja/10 ;
  Merena_Struja = Merena_Struja%10;
  file_content_s[2] = Merena_Struja;
  file_content_s[3] = '[';
  file_content_s[4] = 'A';
  file_content_s[5] = ']';
  file_content_s[6] = 32;
  Mmc_Fat_Write(file_content, 7);             // ROVERA DA LI FAJL POD OVIM IMENOM VEC POSTOJI, AKO POSROJI UPISUJE U NJEGA PODATKE,
                                              // A AKO NE POSTOJI KREIRA NOVI FAJL POD TIM IMENOM

     }
   else if (Merena_Struja <2.5){            // UKOLIKO JE STRUJA NEGATIVNA
       Merena_Struja =Merena_Struja*200 ;

    }
  file_content_s[0] = '-'
  file_content_s[1] = Merena_Struja/100;     // UPIS STOTICA
  Merena_Struja = Merena_Struja%100;
  file_content_s[2] = Merena_Struja/10 ;     // UPIS DESETICA
  Merena_Struja = Merena_Struja%10;
  file_content_s[3] = Merena_Struja;         // UPIS JEDINICA
  file_content_s[4] = '[';
  file_content_s[5] = 'A';
  file_content_s[6] = ']';
  file_content_s[7] = 32;
  Mmc_Fat_Write(file_content_s, 8);          // UPIS PODATAKA U POSTOJEÆI FAJL

}


 //-------KREIRANJE FAJLA NA SD KARTICI U KOJI UPISUJE VREDNOSTI BRZINE---- ;

 void Kreiranje_Fajla_Brzina() {
  Ime_Fajla_Za_Brzinu[0] = 'B';
  Ime_Fajla_Za_Brzinu[1] = 'R';
  Ime_Fajla_Za_Brzinu[2] = 'Z';
  Ime_Fajla_Za_Brzinu[3] = 'I';
  Ime_Fajla_Za_Brzinu[4] = 'N';
  Ime_Fajla_Za_Brzinu[5] = 'A';
  
   Mmc_Fat_Assign(&Ime_Fajla_Za_Brzinu, 0xA0);   //PROVERA DA LI FAJL POD OVIM IMENOM VEC POSTOJI, AKO POSROJI UPISUJE U NJEGA PODATKE,
                                                // A AKO NE POSTOJI KREIRA NOVI FAJL POD TIM IMENOM
   Izmerena_Brzina=brojac_ivica*2*(3/10)*22/7;
   Upisana_Brzina = Izmerena_Brzina*3600/1000;

  file_content_b[0] =Upisana_Brzina/100;      // UPIS STOTICA
  Upisana_Brzina = Upisana_Brzina%100;
  file_content_b[1] =Upisana_Brzina/10 ;      // UPIS DESETICA
  Upisana_Brzina = Upisana_Brzina%10;
  file_content_b[2] = Upisana_Brzina;         // UPIS JEDINICA

  file_content_b[3] = '[';
  file_content_b[4] = 'k';
  file_content_b[5] = 'm';
  file_content_b[6] = '/';
  file_content_b[7] = 'h';
  file_content_b[8] = ']';
  file_content_b[9] = 32;


  Mmc_Fat_Write(file_content_b, 10);           // UPIS PODATAKA U POSTOJEÆI FAJL ;

}



void Kreiranje_Fajla_Napon() {
 Ime_Naponskog_Fajla[0] = 'N';
 Ime_Naponskog_Fajla[1] = 'A';
 Ime_Naponskog_Fajla[2] = 'P';
 Ime_Naponskog_Fajla[3] = 'O';
 Ime_Naponskog_Fajla[4] = 'N';


 Mmc_Fat_Assign(&Ime_Naponskog_Fajla, 0xA0);

     Mereni_Napon=0;
     tlong=0;
     
     Mereni_Napon=Adc_Read(1);

   tlong = (long)Mereni_Napon * 100000;          // UPIS STOTICA
   tlong =tlong / 1023;

   file_content_n[0] = (tlong/10000) + '0';       // UPIS DESETICA
   tlong=tlong%10000;
   file_content_n[1] = (tlong/1000) + '0';       // UPIS JEDINICA

    file_content_n[2] = 46;                     // UPIS DECIMALNE TAÈKE

    tlong=tlong%1000;
    file_content_n[3] = tlong/100 +'0';         // UPIS CIFRE NA 1. MESTU IZA ZAREZA

    tlong=tlong%100;
    file_content_n[4] = tlong/10 +'0';         // UPIS CIFRE NA 2. MESTU IZA ZAREZA

    tlong=tlong%10;
    file_content_n[5] = tlong+'0';
    file_content_n[6] = '[';
    file_content_n[7] = 'V';
    file_content_n[8] =']';
    file_content_n[9] = 32;


  Mmc_Fat_Write(file_content_n,10);           // UPIS PODATAKA U POSTOJEÆI FAJL ;

}

//---------- PREKIDNA RUTINA-------------

unsigned cnt;              // DEFINISANJE LOKALNE PROMENLJIVE

void interrupt() {
  if(intcon.f2==1){
  cnt++;                   // Increment value of cnt on every interrupt
  TMR0L  = 96;
  INTCON = 0x20;           // Set T0IE, clear T0IF
  }
  else if (PIR1.CCP1IF == 1) {
  Brojac_Ivica++;
  PIR1.CCP1IF = 0;

   }
}

 //---- MAIN-----
void main(){
  //---- PODEŠAVANJE REGISTARA-----
  TRISA = 0xFF;             // PORTA ULAZNI
  TRISB = 0x00;             // PORTB IZLAZNI
  TRISC = 0x173;            // RC7,RC3 I RC2 SU IZLAZNI
  PORTB = 0xF0;             // RB7, RB6, RB5, RB4 = 1
  TMR0L = 96;               // POÈRTNA VREDNOST TAJMERA
  INTCON = 0xA0;            // DOZVOLA PREKIDA, DOZVOLA PREKIDA NA TAJMERU 0
  INTCON2 = 0x84;           // PREKIDI BEZ PRIORITETE

  ADCON1 = 0x80;            // PODEŠAVANJE AN PINOVA KAO ANALOGNI
  CMCON  |= 7;              // ISKLJUÈIVANJE KOMPARATORA
  Delay_100ms();            // PAUZA 100 mS
  T0CON = 0xC4;             // PODEŠAVANJE TAJMERA
  CCP1CON = 0x05;           // UKLJUÈIVANJE CAPTURE MODA NA PINU RC2
  
  PIE1 = 0x04;              // DOZVOLA PREKIDA NA PINU RC2 NA RASTUÆU IVICU SIGNALA
  PIR1 = 0x00;              // ISPITIVANJE PREKIDA

   cnt = 0;                 // RESETUJE BROJAÈ
  
  
  // SPI INICIJALIZACIJA
  
  Spi_Init_Advanced(MASTER_OSC_DIV64, DATA_SAMPLE_MIDDLE, CLK_IDLE_HIGH, LOW_2_HIGH);

  // MMC INICIJALIZACIJA
  
  while (Mmc_Init(&PORTC,0));

  Delay_100ms();              // PAUZA 100 mS
  PORTB = 0xA0;
  Delay_100ms();
  interrupt;                  // PREKIDI

   // MMC FAT INICIJALIZACIJA
   
    if (!Mmc_Fat_Init(&PORTC,0)){
      PORTB = 0xF0;
      Delay_100ms();

      // SPI INICIJALIZACIJA, POVECANA FREKVENCIJA OSCILATORA
      
      Spi_Init_Advanced(MASTER_OSC_DIV16, DATA_SAMPLE_MIDDLE, CLK_IDLE_HIGH, LOW_2_HIGH);

      PORTB = 0x50;
      Delay_100ms();
      }


  // ULAZAK U PETLJU

      do{
      if (cnt == 800) {     // KADA cnt DOÐE DO 800, PROTEKLO VREME JE 1s
      cnt = 0;              // RESETOVANJE BROJAÈA cnt
      PORTB = ~PORTB;      // PROMENA PORTA B (TEST)


      Kreiranje_Fajla_Napon();   // POZIVANJE FUNKCIJE ZA KREIRANJE FAJLA 1
      Kreiranje_Fajla_Brzina();  // POZIVANJE FUNKCIJE ZA KREIRANJE FAJLA 2
      Kreiranje_Fajla_Struja();  // POZIVANJE FUNKCIJE ZA KREIRANJE FAJLA 3
      }
      } while(1);


   }
Text file that is placed on the card :

59.62870.967[V] 71.065[V] [V]71.065[V] 70.967[V] 0.967[V] 70.967[V] 71.065[V] 70.967[V] ] 25.219[V] 25.219[V] 25.219[V] 25.219[V] 25.219[V] .219[V] 25.122[V] 25.122[V] 25.122[V] 39.882[V] 0.779[V] .967[V] 70.967[V] 70.967[V] 70.967[V] 71.065[V] 71.065[V] 71.065[V] 71.065[V] 70.967[V] 70.967[V] .065[V] 70.967[V] .065[V] 70.967[V] 70.967[V] 71.065[V] 71.065[V] 71.065[V] 71.065[V] 71.065[V] 70.967[V] 70.967[V] 70.967[V] 71.065[V] 71.065[V] 70.967[V] 71.065[V] 71.065[V] 71.065[V] 70.967[V] 70.967[V] 71.065[V] ] zzzz$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

And to be like this:

59.628[V] 71.065[V] 71.065[V] 70.967[V] 70.967[V] 70.967[V] 71.065[V] 70.967[V] ] 25.219[V] 25.219[V] 25.219[V] 25.219[V] 25.219[V] 25.219[V] 25.122[V] 25.122[V] 25.122[V] 39.882[V] 61.779[V] 70.967[V] 70.967[V] 70.967[V] 70.967[V] 71.065[V] 71.065[V] 71.065[V] 71.065[V] 70.967[V] 70.967[V] 71.065[V] 70.967[V] 71.065[V] 70.967[V] 70.967[V] 71.065[V] 71.065[V] 71.065[V] 71.065[V] 71.065[V] 70.967[V] 70.967[V] 70.967[V] 71.065[V] 71.065[V] 70.967[V] 71.065[V] 71.065[V] 71.065[V] 70.967[V] 70.967[V] 71.065[V]


I hope it is clearer now?

Sobrietytest
Posts: 619
Joined: 05 Jul 2008 06:05
Location: Thailand

Re: PIC, SD Card and MikroC

#4 Post by Sobrietytest » 15 Aug 2010 12:44

Ha! Serves me right for asking! :oops: Romanian?

Okay, which PIC device are you using and, more importantly, what is the clock speed? I'm interested because you have reinitialised the SPI at Fosc/16, if your clock is 8MHz your SPI clock would be 500kHz which is quite slow for an SD, I would try and have the SD's SPI clock running at 2.5MHz and the write time will be significantly faster.

If I have understood your code correctly, you are using the Timer to measure a 1 second interval (by counting 800 interrupts) and then write the data to the SD card. The problem is probably because the interrupt is being serviced while the data is still been written to the card - remember that the PIC can only perform one task at a time. Perhaps you should try disabling the interrupt until the SD functions have completed.

Then you will have another problem; each consecutive SD write takes longer than the last, I don't know for certain but I think this is because the MMC_Write function has to count up to the next free byte in the file. If you disable the interrupt until the write function has finished, the interval will eventually become longer than one second.

What I would try is this:

1. Speed up the SD SPI clock.
2. Change the way that the interrupt works so that the PIC can concentrate on the other routines.
3. Have you thought about using the _ToStr functions to convert your values?

ST

Velimir
Posts: 15
Joined: 02 Jun 2010 07:24

Re: PIC, SD Card and MikroC

#5 Post by Velimir » 15 Aug 2010 13:07

Sobrietytest wrote:Ha! Serves me right for asking! :oops: Romanian?

Okay, which PIC device are you using and, more importantly, what is the clock speed? I'm interested because you have reinitialised the SPI at Fosc/16, if your clock is 8MHz your SPI clock would be 500kHz which is quite slow for an SD, I would try and have the SD's SPI clock running at 2.5MHz and the write time will be significantly faster.

If I have understood your code correctly, you are using the Timer to measure a 1 second interval (by counting 800 interrupts) and then write the data to the SD card. The problem is probably because the interrupt is being serviced while the data is still been written to the card - remember that the PIC can only perform one task at a time. Perhaps you should try disabling the interrupt until the SD functions have completed.

Then you will have another problem; each consecutive SD write takes longer than the last, I don't know for certain but I think this is because the MMC_Write function has to count up to the next free byte in the file. If you disable the interrupt until the write function has finished, the interval will eventually become longer than one second.

What I would try is this:

1. Speed up the SD SPI clock.
2. Change the way that the interrupt works so that the PIC can concentrate on the other routines.
3. Have you thought about using the _ToStr functions to convert your values?

ST
Hello,
I use PIC18F4520, oscillator of 8 MHz, but I included HSPLL mod, as I understand it increases the frequency of four times?

I tried to increase the frequency, but nothing has changed.
Also, I tried _ToStr functions and does not work.
I have not tried to exclude interruptions, because I would not get a second. But I will try to exclude interruptions during data entry tab.

Thank you for your reply.
P.S. Serbian ... :?

Velimir

Sobrietytest
Posts: 619
Joined: 05 Jul 2008 06:05
Location: Thailand

Re: PIC, SD Card and MikroC

#6 Post by Sobrietytest » 17 Aug 2010 13:30

Hi Velimir,

As a matter of interest, what is the frequency that you have set in the Project settings? In case you don't already know, this setting should be the frequency after the PLL, so if you are using 8MHz with a 4xPLL then the Project setting should be 32MHz.

ST

Post Reply

Return to “mikroC General”