logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Atmega16][WinAVR] Obsługa karty SD FAT32 a przerwania

kwikam 13 Lut 2011 21:42 2333 0
REKLAMA
  • #1 9147977
    kwikam
    Poziom 10  
    Mam program, w którym uruchamiam przerwanie z pinu ICP. I wszystko działa jak należy, program jest przetestowany. Postanowiłem połączyć go z programem do obsługi karty pamięci pobranym z DharmaniTech Fat 32. I tu mam problem, przerwanie od ICP zdechło. Szukam, edytuje próbuje i nic. Pomysły już mi się skończyły. Program w już dość poszatkowanym ale działającym stopniu wygląda tak:

    //***********************************************************
    // **** MAIN routine FOR Interfacing microSD/SDHC CARD ****
    //***********************************************************
    //Controller: ATmega32 (Clock: 8 Mhz-internal)
    //Compiler	: AVR-GCC (winAVR with AVRStudio)
    //Version 	: 2.3
    //Author	: CC Dharmani, Chennai (India)
    //			  www.dharmanitech.com
    //Date		: 08 May 2010
    //***********************************************************
    
    //Link to the Post: http://www.dharmanitech.com/2009/01/sd-card-interfacing-with-atmega8-fat32.html
    
    #define F_CPU 8000000UL		//freq 8 MHz
    #include <avr/io.h>
    #include <avr/pgmspace.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #include <stdlib.h>  
    #include "SPI_routines.h"
    #include "SD_routines.h"
    #include "UART_routines.h"
    #include "LCD_routines.h"
    #include "FAT32.h"
    #include "konfig.h"
    
    volatile unsigned char fileName[14]= "pom000.txt";
    volatile bool flImpuls=false; 
    volatile uint16_t SzerImpulsu;
    volatile uint16_t skladana;
    volatile char Bufor;
    static uint16_t OstatniPomiar = 0;
    
    volatile char 	komenda;
    
    
    //************************************************************************************
    //************************************************************************************
    //************************************************************************************
    
    ISR(TIMER1_CAPT_vect) //przerwanie zewnętrzne timera - pomiar z enkodera
    
    {
    
    SzerImpulsu = ICR1 - OstatniPomiar;			//oblicza czas pomiędzy dwoma impulsami na ICP1
    OstatniPomiar = ICR1; 
    ICR1 = 0;
    flImpuls=true; 	 
    transmitString_F(PSTR(" przerwanko "));
    DEBUG_LED1;
    }
    //************************************************************************************
    //-----------------------------------------------------------------------------------
    ISR(USART_RXC_vect)   //pobiera literke przez USART
    {
    komenda=UDR;
    }
    
    //-----------------------------------------------------------------------------------
    //************************************************************************************
    //************************************************************************************
    //Function: to create a file in FAT32 format in the root directory if given 
    //			file name does not exist; if the file already exists then append the data
    //Arguments: pointer to the file name
    //return: none
    //************************************************************************************
    void writeFile2 (void)
    {
    unsigned char j, data, error, fileCreatedFlag = 0, start = 0, sectorEndFlag = 0, sector = 0, bufor[2];
    unsigned int i, firstClusterHigh = 0, firstClusterLow = 0;
    struct dir_Structure *dir;
    unsigned long cluster, nextCluster, prevCluster, firstSector, clusterCount, extraMemory;
    unsigned int n = 0;
    
    
      
    
    
    j = readFile (VERIFY, fileName);
    
    
      transmitString_F(PSTR(" skonvert: "));
      UART_putstr(fileName);
      TX_NEWLINE;
    
    
    
    while(j)	//zmienia filename na kolejna iteracje
    {
    
    unconvertFileName(fileName);
    
    
    for(j=0; j<13; j++)		//szuka na którym 'j' jest kropka
    if(fileName[j] == '.') break;
    
    
    itoa(n,bufor,10);
    
    
    if (n<10)    		//pom001.txt - pom009.txt
    {
    fileName[j-3] = '0';		//kasuje miejsce z kropką i wstawia 0
    fileName[j-2] = '0';
    fileName[j-1] = bufor[0];
    }
    
    else if (n>=10 && n<100)	//pom010.txt - pom099.txt 
    {
    
    fileName[j-3] = '0';
    fileName[j-2] = bufor[0];
    fileName[j-1] = bufor[1];
    
    }
    
    else if (n>=100 && n<1000)	//pom100.txt - pom999.txt 
    {
    
    fileName[j-3] = bufor[0];
    fileName[j-2] = bufor[1];
    fileName[j-1] = bufor[2];
    }
    
    fileName[j] = '.';
    fileName[j+1] = 't';
    fileName[j+2] = 'x';
    fileName[j+3] = 't';
    
    n++;
    
      transmitString_F(PSTR(" po next: "));
      UART_putstr(fileName);
      TX_NEWLINE;
    
    
    j = readFile (VERIFY, fileName);
    
    
    if (n >= 1000)
    	{	
    	  transmitString_F(PSTR(" Brak wolnych indeksow nazw plikow.."));	
    	  transmitString_F(PSTR(" Kasowanie .."));	
    		
    		//deleteFile(fileName);
    
    
    	  n = 0;
    	}
    }
    
    
    
    
    
    if(j == 2) 
       return; //invalid file name
    
    
    
    else
    {
      TX_NEWLINE;
      transmitString_F(PSTR(" Tworzenie pliku.."));
    
      cluster = getSetFreeCluster (NEXT_FREE, GET, 0);
      if(cluster > totalClusters)
         cluster = rootCluster;
    
      cluster = searchNextFreeCluster(cluster);
       if(cluster == 0)
       {
          TX_NEWLINE;
          transmitString_F(PSTR(" No free cluster!"));
    	  return;
       }
      getSetNextCluster(cluster, SET, EOF);   //last cluster of the file, marked EOF
       
      firstClusterHigh = (unsigned int) ((cluster & 0xffff0000) >> 16 );
      firstClusterLow = (unsigned int) ( cluster & 0x0000ffff);
      fileSize = 0;
    
        TX_NEWLINE;
    
    }
    //************************************************************************************
    
      transmitString_F(PSTR(" Tworzenie pliku o nazwie: "));
      unconvertFileName(fileName);
      UART_putstr(fileName);
      TX_NEWLINE;
      convertFileName(fileName);
    
    while(1)
    {
       if(start)
       {
          start = 0;
    	  startBlock = getFirstSector (cluster) + sector;
    	  SD_readSingleBlock (startBlock);
    	  i = fileSize % bytesPerSector;
    	  j = sector;
       }
       else
       {
          startBlock = getFirstSector (cluster);
    	  i=0;
    	  j=0;
       }
       
    
       TX_NEWLINE;
       transmitString_F(PSTR(" Enter text (end with ~):"));
       
       do
       {
    
    	sectorEndFlag = 0;
    
    	 data = komenda;
    
    
    	 transmitByte(data);
         buffer[i++] = 223;//data;
    	 fileSize++;
    
    
    
    	
    	if (flImpuls)				//jeśli odebrano przerwanie z ICP1
    	{
    
    
    UART_putint(SzerImpulsu); UART_putchar(';');
    
    	flImpuls=false; 
    	}
    
    	 
    
    
    	 
         if(i >= 512)   //though 'i' will never become greater than 512, it's kept here to avoid 
    	 {				//infinite loop in case it happens to be greater than 512 due to some data corruption
    	   i=0;
    	   error = SD_writeSingleBlock (startBlock);
           j++;
    	   if(j == sectorPerCluster) {j = 0; break;}
    	   startBlock++; 
         }
    	}while (data != '~');
    
    //******************************
    
    
       if(data == '~') 
       {
          fileSize--;	//to remove the last entered '~' character
    	  i--;
    	  for(;i<512;i++)  //fill the rest of the buffer with 0x00
            buffer[i]= 0x00;
       	  error = SD_writeSingleBlock (startBlock);
    
          break;
       } 
    
       prevCluster = cluster;
    
       cluster = searchNextFreeCluster(prevCluster); //look for a free cluster starting from the current cluster
    
       if(cluster == 0)
       {
          TX_NEWLINE;
          transmitString_F(PSTR(" No free cluster!"));
    	  return;
       }
    
       getSetNextCluster(prevCluster, SET, cluster);
       getSetNextCluster(cluster, SET, EOF);   //last cluster of the file, marked EOF
    }        
    
    getSetFreeCluster (NEXT_FREE, SET, cluster); //update FSinfo next free cluster entry
    
    
    prevCluster = rootCluster; //root cluster
    
    while(1)
    {
       firstSector = getFirstSector (prevCluster);
    
       for(sector = 0; sector < sectorPerCluster; sector++)
       {
         SD_readSingleBlock (firstSector + sector);
    	
    
         for(i=0; i<bytesPerSector; i+=32)
         {
    	    dir = (struct dir_Structure *) &buffer[i];
    
    		if(fileCreatedFlag)   //to mark last directory entry with 0x00 (empty) mark
    		 { 					  //indicating end of the directory file list
    		   dir->name[0] = 0x00;
               return;
             }
    
            if((dir->name[0] == EMPTY) || (dir->name[0] == DELETED))  //looking for an empty slot to enter file info
    		{
    		  for(j=0; j<11; j++)
      			dir->name[j] = fileName[j];
    		  dir->attrib = ATTR_ARCHIVE;	//settting file attribute as 'archive'
    		  dir->NTreserved = 0;			//always set to 0
    		  dir->timeTenth = 0;			//always set to 0
    		  dir->createTime = 0x9684;		//fixed time of creation
    		  dir->createDate = 0x3a37;		//fixed date of creation
    		  dir->lastAccessDate = 0x3a37;	//fixed date of last access
    		  dir->writeTime = 0x9684;		//fixed time of last write
    		  dir->writeDate = 0x3a37;		//fixed date of last write
    		  dir->firstClusterHI = firstClusterHigh;
    		  dir->firstClusterLO = firstClusterLow;
    		  dir->fileSize = fileSize;
    
    		  SD_writeSingleBlock (firstSector + sector);
    		  fileCreatedFlag = 1;
    
    		  TX_NEWLINE;
    		  TX_NEWLINE;
    		  transmitString_F(PSTR(" Plik utworzony!"));
    
    		  freeMemoryUpdate (REMOVE, fileSize); //updating free memory count in FSinfo sector
    	     
            }
         }
       }
    
       cluster = getSetNextCluster (prevCluster, GET, 0);
    
       if(cluster > 0x0ffffff6)
       {
          if(cluster == EOF)   //this situation will come when total files in root is multiple of (32*sectorPerCluster)
    	  {  
    		cluster = searchNextFreeCluster(prevCluster); //find next cluster for root directory entries
    		getSetNextCluster(prevCluster, SET, cluster); //link the new cluster of root to the previous cluster
    		getSetNextCluster(cluster, SET, EOF);  //set the new cluster as end of the root directory
          } 
    
          else
          {	
    	    transmitString_F(PSTR("End of Cluster Chain")); 
    	    return;
          }
       }
       if(cluster == 0) {transmitString_F(PSTR("Error in getting cluster")); return;}
       
       prevCluster = cluster;
     }
     
     return;
    }
    
    //************************************************************************************
    
    void port_init(void)
    {
    PORTA = 0x00;
    DDRA  = 0x00;
    PORTB = 0xEF;
    DDRB  = 0xBF; //MISO line i/p, rest o/p
    PORTC = 0xFF;
    DDRC  = 0xFF;
    PORTD = 0x00;
    DDRD  = 0xFF;
    }
    
    
    //call this routine to initialize all peripherals
    void init_devices(void)
    {
    // cli();  //all interrupts disabled
     port_init();
     spi_init();
     uart0_init();
    // MCUCR = 0x00;
    // GICR  = 0x00;
     sei();        // włącz obsługę przerwań
    
    //KONFIGURACJA REJESTRÓW TIMERA TC1:
    
    
       TIMSK = _BV(TICIE1)|_BV(TOIE2)|_BV(TOIE0); //Enable Input Capture Interrupt
     //  TCCR1B = _BV(ICNC1)|_BV(ICES1)|_BV(CS10);// taktowanie T1 CK/1
    					// opadające zbocze i filtracja zakłóceń na ICP
    					
       
    	TCCR1B = _BV(ICNC1)|_BV(ICES1)|_BV(CS10);// taktowanie T1 CK/256
    					// opadające zbocze i filtracja zakłóceń na ICP
    
    
    
    
    
    
    
     //all peripherals are now initialized
    }
    //************************************************************************************
    //*********************************************** MAIN *******************************
    //************************************************************************************
    int main(void)
    {
    unsigned char option, error, data, FAT32_active;
    unsigned int i;
    
    
    _delay_ms(100);  //delay for VCC stabilization
    
    init_devices();
    
    
    
    TX_NEWLINE;
    transmitString_F (PSTR("    Mobilne urzadzenie pomiarowe v.1  "));
    TX_NEWLINE;
    
    
    cardType = 0;
    
    for (i=0; i<10; i++)
    {
      error = SD_init();
      if(!error) break;
    }
    
    if(error)
    {
      if(error == 1) transmitString_F(PSTR("Wykryto karte SD.."));
      if(error == 2) transmitString_F(PSTR("Inicjalizacja nie udala sie.."));
    
      while(1);  //wait here forever if error in SD init 
    }
    
    switch (cardType)
    {
      case 1:transmitString_F(PSTR("Standard Capacity Card (Ver 1.x) Detected!"));
      		 break;
      case 2:transmitString_F(PSTR("High Capacity Card Detected!"));
      		 break;
      case 3:transmitString_F(PSTR("Standard Capacity Card (Ver 2.x) Detected!"));
      		 break;
      default:transmitString_F(PSTR("Unknown SD Card Detected!"));
      		 break; 
    }
    
    
    SPI_HIGH_SPEED;	//SCK - 4 MHz
    _delay_ms(1);   //some delay
    
    
    FAT32_active = 1;
    error = getBootSectorData (); //read boot sector and keep necessary data in global variables
    if(error) 	
    {
      TX_NEWLINE;
      transmitString_F (PSTR("Nie znaleziono FAT32!"));  //FAT32 incompatible drive
      FAT32_active = 0;
    }
    
    while(1)
    {
    TX_NEWLINE;
    transmitString_F(PSTR("Nacisnij dowolny klawisz..."));
    DEBUG_LED1;
    TX_NEWLINE;
    option = receiveByte();
    
    TX_NEWLINE;	transmitString_F(PSTR("> 1 : Zapis do pliku"));
    TX_NEWLINE;	transmitString_F(PSTR("> 2 : Odczyt z biezacego pliku"));
    TX_NEWLINE;
    
    option = receiveByte();
    transmitByte(option);
    
    TX_NEWLINE;
    
    
    
    switch (option)
    {
    
    case '1': //error = SD_erase (block, tcks);otalBlo
    //convertFileName (fileName);
    writeFile2();
              break;
    
    case '2': //error = SD_erase (block, tcks);otalBlo
    unconvertFileName(fileName);
    readFile( READ, fileName);
              break;
    
    default: TX_NEWLINE;
             TX_NEWLINE;
             transmitString_F(PSTR(" Niewlasciwa opcja!"));
             TX_NEWLINE;
    }
    
    TX_NEWLINE;
    }
    //return 0;
    }
    
    
    



    Skupiałem się na uruchomieniu tego przerwania, które w takiej postaci w osobnym programie działa bez zarzutu. A tu nie. Proszę o pomoc co może być nie tak?

    Dodam jeszcze, że jeśli chodzi o obsługę karty to wszystko działa jak należy. Po prostu program w ogóle nie słucha przerwania.
  • REKLAMA
REKLAMA