simba92 Napisano Luty 14, 2018 Udostępnij Napisano Luty 14, 2018 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. Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
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!