Skocz do zawartości

Kurs STM32 F4 - #5 - Pomiar napięcia (ADC), DMA, STMStudio


Pomocna odpowiedź

Witam.

Ja natomiast spotkałem się z bardzo dziwnym zjawiskiem,
w funkcji main nie aktualizuje zmiennych globalnych typu float.

Zmienna PomiarADC działa ok i otrzymuję wartości w zakresie ponad 1000

a jak "podgrzeję" to dochodzi ponad 1050

zmienne Vsense i Temperature maja stałe wartości

Vsense = -2.2E-15

Temperature = 2.0175

Już nawet zapisałem coś takiego:

/* USER CODE BEGIN WHILE */
 	Vsense = 5;
 	Temperature = 10;
 	while (1)
 {

 		Vsense = 7;
 		Temperature = 17;
//dalsza część z zakomentowanym obliczeniem Vsense i Temperature

Mam płytkę Discovery z procesorem F401 VCT6U

Wcześniej myślałem, że przetwornik nie działa i odłożyłem na jakiś czas, teraz wróciłem

i okazało się, ze to wina zmiennych typu float.

Na pewno wczytuję odpowiedni plik elf, kompiluję na wszystkie możliwe sposoby

build/rebuild/build all.

Pozdrawiam

Zuk

Link do komentarza
Share on other sites

W tym przykładzie jako napięcie odniesienia dla adc jest PowerSupply, które jest równe 3.0V. Troche mnie to dziwi dlaczego nie jest 3.3V!?. Druga sprawa czy jest możliwość wybrania jakiegoś wewnętrznego źródła odniesienia? albo zewnetrznego na jakimś pinie?

Pozdrawiam Janusz

Link do komentarza
Share on other sites

Witajcie.

Mam Nucleo 446RE. Robię wszystko jak w przykładzie ale CUBE nie dodaje mi DMA

Czyli brakuje linii

static void MX_DMA_Init(void); oraz MX_Init.

Ale po wejściu do Cube i ustawieniu w zakładce ADC1 Configuration -> DMA Settings

DMA Request na ADC1, Stream na DMA2 Stream0 Direction na Peripherial to Memory

pojawiła się inicjalizacja DMA, ale nie działa odczyt ciągły temperatury.

Link do komentarza
Share on other sites

Cześć.

Dręczą mnie dwie kwestie, mianowicie:

1. Kolega Sowa zadał pytanie:

A jak zrobić pomiar z kilku kanałów ADC1 w trybie blokującym?

Czy mógłby ktoś pomóc w tym temacie (można by rozszerzyć to jeszcze o tryb z przerwaniami)?

2. Jak zmienić przeznaczenie pinu w trakcie działania programu, tzn. chciał bym aby na danym pinie mógł wystawić stan niski/wysoki, a w innej części programu, tym piniem pomierzyć napięcie. Istnieje taka opcja?

Bardzo był bym wdzięczny za jakąkolwiek wskazówkę.

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

iwi, w komentarzach do kursów piszemy wyłącznie o sprzęcie takim, jaki używany jest w kursie. Inaczej prowadzi to do zamieszania. Jeśli masz problem z inną płytką to stwórz osobny temat w stosownym dziale.

Link do komentarza
Share on other sites

Cześć!

Mój problem wygląda następująco, częściowo pokrywa się z poprzednikami tj.

Cześć, mam problem już na samym początku, error związany z termometrem.

Obrazek

Zaimportowałem do wokrbencha pliki pobrane od autora, zbudowałem je i wczytałem zmienne do STM studio, teoretycznie ładnie je wczytało ale również jak poprzednicy 2 z nich przyjęły stałą wartość a zmienna "PomiarADC" liczy czas ograniczony do rozmiaru zmiennej (65k).

15033642_1266580303414322_672297954_n.png?oh=0f01b936c70a50ddf6040917c4d15bb8&oe=582A82A0

Podobnie sie dzieje jak podłączam joystick. Jedna z wartości tablicy Joystick robi się stała (około 180) a druga odlicza czas w ms do 65k.

W żadnym z wymienionych przypadków nie ma żadnej reakcji na warunki zewnętrzne, tj. wychylenie joysticka lub wymuszony wzrost temperatury.

Jakiś pomysł?

EDIT.

Dodam, że właśnie przetestowałem to takim naocznym debuggerem. Podłączyłem analogowy czujnik optoelektroniczny SHARP'a do mojego discovery i uzależniłem mruganie wbudowanymi diodami od odczytanego napięcia. Odpowiedzi są dobre, dlatego postawiłbym, że coś jest źle z ostatnim ogniwem czyli STM studio.

__________

Komentarz dodany przez: Treker

Link do komentarza
Share on other sites

W przykładach z artykułu brakuje właściwie dwóch rzeczy. Pierwsza to volatile przy wszystkich zmiennych, które są używane zarówno przez przerwania lub DMA, jak i główny program.

Słowo kluczowe volatile to informacja dla kompilatora, żeby nie optymalizował odwołań do danej zmiennej.

Wyobraźmy sobie następujący program - chcemy czekać, aż odczyt z przetwornika osiągnie określoną wartość:

while (PomiarADC < 100) { }

My wiemy, że PomiarADC jest ustawiane przez DMA, ale kompilator tego nie wie... Jeśli używamy niskiego poziomu optymalizacji, to pewnie program zadziała. Jednak zmiana ustawień na silniejszą optymalizację może sprawdzić, że optymalizator zmieni kod na:

while (1) {} 

Wbrew pozorom to poprawne zachowanie. Zapomnijmy na moment o DMA. Wtedy nasza pętla byłaby nieskończona - o ile na wejściu PomiarADC < 100, to nic w pętli tej zmiennej nie modyfikuje, więc pętla jest nieskończona.

Dopiero dodanie volatile informuje kompilator, żeby nie próbował sztuczek ze zmienną.

Druga sprawa w przypadku DMA to pamięć cache i buforowanie. Cortex-M4 ma na szczęście małą pamięć cache, ale i tak powinno się na to zwracać uwagę - inaczej mogą pojawić się problemy podobne do używania volatile.

Link do komentarza
Share on other sites

Witam. Mam problem z pomiarem w trybie blokującym. W STM Studio po imporcie zmiennych nie pojawiają mi się PomiarADC, VSense, Temperature. Jaki może być powód?

Link do komentarza
Share on other sites

Witam,

Postanowiłem dołożyć uśrednianie temperatury.

uint8_t div_temp = 5;
float Temperature_instantaneous;
float Temperature;
float Temperature_average;

  if( HAL_ADC_PollForConversion(&hadc, 10) == HAL_OK){// Oczekiwanie na zakonczenie konwersji
	  PomiarADC = HAL_ADC_GetValue(&hadc);// Pobranie zmierzonej wartosci
	  Vsense = (SupplyVoltage*PomiarADC)/ADCResolution;// Przeliczenie wartosci zmierzonej na napiecie
	  Temperature_instantaneous = ((Vsense-V30)/Avg_slope)+30;// Obliczenie temperatury chwilowej

	  Temperature_average = Temperature_average*(div_temp-1) + Temperature_instantaneous;
	  Temperature= Temperature_average/div_temp;

	  HAL_ADC_Start(&hadc);// Rozpoczecie nowej konwersji
  }

Efektem takiego kodu jest zwrot wartości Temperature_average oraz Temperature w STMStudio jako "Infinit".

Macie może pomysł co tutaj jest źle ?

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.