Skocz do zawartości

STM32 F411 Timer interrupt nie działa


DeadGeneratio

Pomocna odpowiedź

Jak w temacie, płytka to blackpill f411, ustawiłem częstotliwość pracy płytki na 16MHz, timer 2 posiada clock source = internal source, prescaler = 1600-1, counter period = 10000-1, auto-reload preload = enable. Powinna wyjść zatem sekunda. W ustawieniach NVIC timer 2 global interrupt zaznaczony, w kodzie w main.c oczywiście wystartowanie timera:

HAL_TIM_Base_Start_IT(&htim2);

w pętli while nic się nie dzieje, za to w user code begin 4 mam to:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
	checkTempAndHumSTH31();
}

void checkTempAndHumSTH31() {
	uint8_t txBuff [2] ={0x24, 0x00};
	uint8_t rxBuff [6];
	uint16_t raw_temp = 0;
	uint16_t raw_hum = 0;
	HAL_I2C_Master_Transmit(&hi2c1, STH31_ADDR, txBuff,	sizeof(txBuff), HAL_MAX_DELAY);
	HAL_Delay(50);
	HAL_I2C_Master_Receive(&hi2c1, STH31_ADDR, rxBuff, sizeof(rxBuff), HAL_MAX_DELAY);
	HAL_Delay(50);
	raw_temp = rxBuff[0] << 8 | rxBuff[1];
	raw_hum = rxBuff[3] << 8 | rxBuff[4];
	temperature = -45.0f + 175.0f * (raw_temp / 65535.0f);
	humidity = 100.0f * (raw_hum / 65535.0f);
}

Kod odczytujący temperaturę oraz wilgotność działał w pętli while z dodanym HAL_Delay(1000);, ale jest to bardzo nieporęczna metoda uzyskiwania danych, zwłaszcza, że będę wpinał inne czujniki. Na chwilę obecną raz przerwanie się pojawi w momencie startu i nie jest prawdopodobnie nawet dokończone - debugger zatrzymuje się na HAL_Delay(50); i przechodzi do działania while od razu.

 

Dodatkowe pytanie - czy ktoś ma pomysł jak mogę usprawnić ten kod? I dodatkowo czy istnieje jakiś prosty w tłumaczeniu poradnik jak zrobić własny plik .c oraz .h? W internecie nie znalazłem nigdzie sensownie działających plików do tego czujnika, to mam ochotę samemu zrobić taki.

Link do komentarza
Share on other sites

(edytowany)

Okej, jak opóźnić zatem odbiór danych z i2c, pozostawienie tego bez żadnej zwłoki powoduje wysypanie się komunikacji - czujnik musi przetworzyć dane oraz je wysłać. Istnieje może wskaźnik jakiś czy w buforze znajdują się dane do odebrania jak jest to w wypadku uarta?

Edytowano przez DeadGeneratio
Link do komentarza
Share on other sites

W procedurze obsługi przerwania nie może znajdować się kod, który wprowadza jakiekolwiek opóźnienia (wywołania HAL_Delay(), wywołania jakichkolwiek blokujących funkcji API itd.). Przerwanie od timer-a może Ci posłużyć do zainicjowania procesu komunikacji z czujnikiem, ale nie możesz tam umieścić całego "algorytmu", o ile nie jest to operacja "natychmiastowa".

Z lotu ptaka to wygląda tak, że w przerwaniu od timer-a wysyłasz żądanie odczytu, natomiast o tym, że dane są gotowe i można je odebrać, dowiadujesz się za jakiś czas (np. za pięć milisekund) w przerwaniu od urządzenia, które obsługujesz. Tu trzeba by poszperać po kodzie HAL-a i poczytać o trybie przerwaniowym w I2C. Do płytki STM32F4 powstał nawet dokument (UM1725) - dokumentacja driverów HAL. Zbyt wylewny to ten dokument nie jest, ale na szczęście nie jest to tylko lista nagłówków funkcji API:
https://www.st.com/resource/en/user_manual/um1725-description-of-stm32f4-hal-and-lowlayer-drivers-stmicroelectronics.pdf

W prostym projekcie hobbystycznym warto pomyśleć, czy skórka jest warta wyprawki. W pętli głównej możesz zrobić za pomocą kilku zmiennych namiastkę "maszyny stanów". Wkładasz do pętli głównej jeden HAL_Delay(X), gdzie X jest "kwantem czasu", co jaki Twoja pętla budzi się do działania, i w każdym obiegu pętlli, dzięki "zmiennym stanu" sprawdzasz, w którym jesteś kroku i jaką masz podjąć akcję. Można w ten sposób np. prosto obsłużyć cykl komunikacji z kilkoma czujinkami typu:
żadanie1 -> odczyt1 -> żądanie2 -> odczyt2 -> żądanie3 -> odczyt3-> .......... -> żądanie1 -> odczyt1 -> ...                   

 

Edytowano przez ReniferRudolf
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

13 godzin temu, ReniferRudolf napisał:

W procedurze obsługi przerwania nie może znajdować się kod, który wprowadza jakiekolwiek opóźnienia (wywołania HAL_Delay(), wywołania jakichkolwiek blokujących funkcji API itd.).

To nie do końca prawda w przypadku STM32. HAL_Delay to zwykły polling na rejestrze SysTicku, może być przerwany prze każde inne, o lepszym priorytecie przerwanie. Tam jest wielopoziomowy system priorytetów i wywłaszczeń dzięki, któremu zasada taka znana choćby z AVR nie jest tak ścisła. W AVR _delay wyłącza przerwania, w STM32 tak nie jest. Przy poprawnie zaprojektowanym urządzeniu w przerwaniach mogą być dowolnie długo trwające procedury.

Oczywiście w szczególnych przypadkach należy trzymać się zasady krótkiego "kodu" w przerwaniach i pewnie w tym przypadku, dla mniej wprawionego programisty, będzie to dobra i skuteczna zasada.

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.