Skocz do zawartości

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


Pomocna odpowiedź

Napisano

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.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...