Skocz do zawartości

Obsługa modułu karty microSD dla STM32 (interfejs SPI i system plików FAT)


simba92

Pomocna odpowiedź

Cześć!

W swoim robocie z procesorem STM32F103VCT6 posiadam moduł karty microSD, po wielu próbach udało mi się zaimplementować obsługę karty na STM, ale... są pewne ograniczenia, którymi są np. zapis danych z jakiegoś czujnika w pliku plik.txt do 1245 linii i generowane jest przerwanie.

HardFault_Handler

Program napisałem najpierw w środowisku CooCox, a ostatnio przeniosłem do środowiska System Workbench for STM32 jak w kursie dla Stm32F1( zwiększyłem rozmiar stosu z 0x400 na 0x1000, w nadzieji że tu tkwi problem i go rozwiąże, nic z tego). Poniżej zamieszczam poszczególne najważniejsze fragmenty całego programu:

1) Funkcja main.c

#include "main.h"

int main(void)
{

system_init(); //główna funkcja inicjująca we/wy procesora, peryferia, zegary taktujące etc
system_IWDG_RST_check(); // sprawdzenie czy uruchomiono system od nowa po resecie od WatchDoga
iwdg_init(); //inicjalizacja watchdoga
microSD_volume_init(); //funkcja inicjująca moduł karty i tworząca foldery z plikami .txt


while(1)
{
	IWDG_ReloadCounter();
	microSD_write_mag_gyro_raw_data2(); //funkcja zapisujaca dane na karte co 100ms pod warunkiem wciśnięcia przycisku i zmiany flagi zezwolenia na zapis (patrz niżej)
}

}

2) Funkcja system_init()

void system_init(void)
{
rcc_system_init();
gpio_system_init();
peripheral_system_init();
//sensors_init();

}

3) Funkcja microSD_volume_init()

void microSD_volume_init(void)
{
FRESULT fresultmount, fresultunmount, fresultopen, fresultclose; //
FRESULT fresultlsm, fresultlsmm;
FRESULT fresultimu, fresultimuu;

delay_ms(100);

fresultmount = f_mount(0, &g_sFatFs); //montowanie dysku logicznego
if(fresultmount == 0)
{
	do
	{
		fresultlsm = f_mkdir("lsm303D"); //tworzenie katologu lsm303D
		fresultlsmm = f_mkdir("lsm303D/magnet"); //tworzenie podkatologu  magnet
		fresultimu = f_mkdir("IMU9v5");
		fresultimuu = f_mkdir("IMU9v5/gyro");
	}while((fresultlsm != 0) && (fresultimu != 0));

	do
	{
                fresultopen = f_open(&plik1, "lsm303D/magnet/dane.txt",FA_CREATE_ALWAYS); //otwieranie i tworzenie pliku dane.txt w podfolderze magnet
                fresultclose = f_close(&plik1); //zamykanie pliku
	}while((fresultopen != 0) && (fresultclose != 0));

	fresultunmount = f_mount(0, NULL); //wymontowanie dysku logicznego
	if(fresultunmount != 0) while(1);
}
else
{
while(1);
}

}

oraz funkcja microSD_write_mag_gyro_raw_data2()

void microSD_write_mag_gyro_raw_data2(void) 
{

if((microSD_mounted_flag == 0) && (microSD_write_flag == 1) ) // dysk wymontowany trzeba zamontowac, flaga zapis = 1 tj. zapis start
{
	microSD_volume_mount(); // montuje dysk i ustawia flage microSD_mounted_flag = 1 ze zamontowano
}

if((microSD_mounted_flag == 1) && (microSD_write_flag == 0) ) // dysk zamontowany trzeba wymontowac, flaga zapis = 0 tj. zapis stop PO WCIŚNIĘCIU innego PRZYCISKU wymontowanie dysku i KONIEC zapisu
{
	microSD_volume_unmount(); // wymontuje dysk i ustawia flage microSD_mounted_flag = 0 ze wymontowano
}

if((sekunda == 1) && (microSD_mounted_flag == 1) && (microSD_write_flag == 1)) // OK WSZYSTKIE WARUNKI spełnione i zapis co 100 ms, zamontowany dysk i zgoda na zapis
{

	if(t > 0) //jesli czas >0, dopisujemy na koncu pliku nowa linie danych
	{
		fresult_open = f_open (&plik1, "lsm303D/magnet/dane.txt", FA_WRITE); //plik otwarty do zapisu
		fresult_lseek = f_lseek(&plik1, plik1.fsize);
	}
	else
	{
		fresult_open = f_open (&plik1, "lsm303D/magnet/dane.txt", FA_WRITE);
		fresult_lseek = f_lseek(&plik1, 0); //jesli czas ==0, to oznacza to, ze zapis dopiero sie zaczyna i nalezy plik "obciac" i zaczac zapis od nowa
		fresult = f_truncate(&plik1);
	}
	//kolumna czasu
	Time = t;

	/*---------------------------pierwszy plik--------------------------------*/
	fresult_write1 = f_write(&plik1, (const void*)intToStr(Time), 8, &bajtowZapisanych); 
	fresult_write2 = f_write(&plik1, (const void*)"pomiar:", 8, &bajtowZapisanych); //wartosc dopisana
	fresult_write3 = f_write(&plik1, (const void*)"magnet", 6, &bajtowZapisanych);	 //wartosc dopisana
        	fresult_write4 = f_write(&plik1, (const void*)"\r\n", 2, &bajtowZapisanych); //nowa linia  (wg. standardu Windows)
	fresult_close = f_close (&plik1);

	t+=1;  //czas dla nastepnej wartosci

}
sekunda = 0; //zerowanie flagi zapisu co 100ms (bylo co 1s)
}

Podsumowując :

- program działa bez żadnego problemu do momentu zapisu 1245 linii na karcie w pliku lsm303D/magnet/dane.txt co generuje przerwanie

HardFault_Handler

dodam, że plik ma wtedy wartość około 32 KB

- to nie jest wina interfejsu SPI, obniżyłem prędkość transmisji do około 2 MHZ na przewodach o długości około 15 cm

- karta microSD sformatowana do systemu FAT32 z jednostką alokacji 512 bajtów

- funkcja zapisująca dane do pliku dane.txt za każdym razem otwiera i zamyka plik

- wszystkie operacje obsługi modułu fatfs z poziomu aplikacji np. funkcja f_open(), f_write(), które są typu FRESULT zwracają wartość 0 co potwierdza poprawność wykonania funkcji !

- zmienne użyte w funkcji microSD_write_mag_gyro_raw_data2(void) są prawie wszystkie globalne, więc nie chodzi tu o problem stosu

PS : utknąłem póki co w miejscu, a bardzo potrzebuję mieć stabilną obsługę karty na robocie, potrzebuje akwizycji dużej ilości danych.Czy ktoś mógłby mi pomóc i wyjaśnić skąd bierze się to przerwanie HardFault_Handler - zapalam diodę w obsłudze, więc to napewno to przerwanie, jakie mogą być tego przyczyny, gdzie tego szukać ? można debugować program od np. momentu zapisu 1244 linii i podejrzeć co się stanie w trakcie próby zapisu 1245 i dalej ??? korzystam z wspomnianego środowiska z kursu STM32F1. Proszę o pomoc i wszelkie wskazówki, dzięki ! Chętnie odpowiem na wszystkie pytania i niejasności.

PS2 : chyba nie ma sensu, żebym wrzucał więcej kodu programu, zamieściłem najważniejsze fragmenty.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.