Skocz do zawartości

Kurs STM32L4 – #12 – zewnętrzna pamięć EEPROM (I2C)


Komentator

Pomocna odpowiedź

Kurs STM32L4 – #12 – zewnętrzna pamięć EEPROM (I2C)

Do tej pory omówiliśmy dwa interfejsy szeregowe na STM32L4, czyli UART i SPI. Pierwszy wymagał dwóch linii, ale był dość powolny. Drugi pracował szybciej, ale wykorzystywał więcej wyprowadzeń. Teraz zajmiemy się I2C, czyli kolejnym interfejsem komunikacyjnym, dzięki któremu do tych samych linii możemy łatwo podłączyć wiele urządzeń.

UWAGA, to tylko wstęp! Dalsza część artykułu dostępna jest na blogu.

Przeczytaj całość »

Poniżej znajdują się komentarze powiązane z tym wpisem.

  • Lubię! 1
Link do komentarza
Share on other sites

Przypominamy: w komentarzach do kursów rozmawiamy wyłącznie na tematy związane z konkretnym kursem. Mile widziane są również informacje od osób, które korzystały wcześniej z naszych poradników. Wszystko po to, aby kursanci, którzy mają zamiar korzystać z tego kursu nie musieli "przedzierać" się przez dziesiątki postów na inne tematy. Pytania na tematy, które nie są związane z kursem można zadawać na naszym forum o mikrokontrolerach.

Link do komentarza
Share on other sites

Zachęcam do lektury kolejnej części kursu STM32L4 - to już dwunasty odcinek! Tym razem o komunikacji przez I2C na przykładzie małej pamięci EEPROM. W następnym odcinku wykorzystamy tę widzę do komunikacji z precyzyjnym czujnikiem wysokości, dzięki czemu będzie mogli mierzyć wysokość (tak jak robią to np. sportowe zegarki) 😉

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

@ethanak może najpierw małe wyjaśnienie - celem tej części kursu było głównie pokazanie sposobu działania interfejsu I2C oraz jego obsługi z poziomu biblioteki HAL dla STM32. Sama pamięć EEPROM jest tylko prostym i popularnym przykładem. Masz oczywiście w pełni rację odnośnie bufora zapisu, postanowiliśmy jednak świadomie nie opisywać tego w tej części kurs. Ograniczyliśmy się tylko do uwagi: "Na dodatek, przesyłając więcej niż jeden bajt, należy brać pod uwagę wielkość licznika oraz adresowanie stron. Szczegóły na ten temat znaleźć można oczywiście w dokumentacji tego układu". Po prostu nie chcieliśmy już dodawać tutaj informacji, które nie są związane ściśle z głównym bohaterem kursu, czyli STM32. Temat, który przytoczyłeś sprawdzi się jednak świetnie w kwestii zadania domowego lub ewentualnej kontynuacji tego kursu 😉 

  • Lubię! 1
Link do komentarza
Share on other sites

@Elvis a więc niech mój post pozostanie inspiracją dla młodych padawanów ST 🙂

@Treker robiłeś coś przy edytorze? Bo coraz ładniej wygląda z coraz mniej można z niego korzystać (np. na moim FX-sie nie mogę wywalić nowej linii między nickiem Elvisa a moim tekstem, XUbuntu 20.04)

 

  • Lubię! 1
Link do komentarza
Share on other sites

33 minuty temu, Treker napisał:

linijkę normalnie usunąłem za pomocą klawisza delete (Chrome)

Czyli najnowszy Firefox ma jakieś własne zdanie - zauważyłem to już wcześniej, edytor wariuje nawet jak wstawię emotkę i potrafi nie reagować np. na klawisze kursora. Czyli trzeba się przyzwyczaić.

Link do komentarza
Share on other sites

Kolejna część kursu jest już dostępna - tym razem mowa o czujniku ciśnienia atmosferycznego (również I2C). Staraliśmy się pokazać coś więcej oprócz standardowego pobrania danych z sensora 😉 Zachęcam do lektury: Kurs STM32L4 – #13 – czujnik ciśnienia, pomiar wysokości (I2C)

Link do komentarza
Share on other sites

Mam jedną uwagę praktyczną do tej części kursu, a można by to wykorzystać jeszcze w innych miejscach. Chodzi mi o możliwość podglądu zapisu przebiegów z analizatora. Prezentacja w formie pliku graficznego ma swoje ograniczenia, a ładując zapisany plik do własnego programu analizującego można lepiej analizować dane, szczególnie dla takich przypadków, gdy na pliku graficznym ciężko o szczegóły. Wiem że to dodatkowa praca i pewnie jedna osoba na dziesięć z skorzysta, ale może warto to rozważyć

 

  • Lubię! 1
Link do komentarza
Share on other sites

@Emtorek witam na forum 🙂 

9 godzin temu, Emtorek napisał:

I dlaczego typ void

void możesz napisać gdy nie podajesz w zmiennej żadnych argumentów. Ale tobie chyba chodzi o coś innego.

Wydaje mi się, że pytasz o wskaźnik na zmienną void *. Oznacza to wskaźnik na zmienną – jej adres, który nie ma informacji o tym jaki typ danych jest w tej pamięci więc nie ma informacji ile bajtów zajmują zmienne.

HAL_StatusTypeDef eeprom_read(uint32_t addr, void* data, uint32_t size)
{
    eeprom_wait();
    return HAL_I2C_Mem_Read(&hi2c1, EEPROM_ADDR, addr, 1, data, size, HAL_MAX_DELAY);
}

Widać to w kodzie, data to bufor (tablica) zmiennych typu void *, czyli wskazujemy początek obszar o rozmiarze size ale nieznanym typie danych. Dzięki temu możemy w kodzie odwołać się do dowolnego typu danych, np. 4 bajtowego countera:

eeprom_read(0x10, &counter, sizeof(counter))

I poinformować funkcję ile ma zarezerwować miejsca używajac operatora sizeof, który zwraca liczbę bajtów zajmowaną przez zmienną/typ danych ewentualnie długość tablicy jak jest bezpośrednio podana. Dla uściślenia pierwsza zmienna addr oznacza adres w przestrzeni eepromu, adres daty wskazuje na miejsce w pamięci operacyjnej STM.

Wątpliwość jak rozumiem budzi to, że w funkcji HAL jest uint8_t, to pytanie już do @Elvis

Edytowano przez Gieneq
  • Lubię! 1
Link do komentarza
Share on other sites

37 minut temu, Gieneq napisał:

Wątpliwość jak rozumiem budzi to, że w funkcji HAL jest uint8_t

Po prostu w C (ale nie C++) typ void * oznacza "wskaźnik na cokolwiek" i można go użyć w miejsce dowolnego wskaźnika. Przykładowo jeśli mamy funkcje:
 

int cośtam(uint8_t *data, size_t count);
char *cośinnego(int size);

możemy je wywołać np. tak:
 

void *data;
int wynik;
data = cośinnego(10);
wynik = cośtam(data, 10);

W C++ już ten numer nie przejdzie 🙂

A uint8_t jest pewnie dlatego, że wygodnie się go używa (np. w iteracjach).

 

Link do komentarza
Share on other sites

@ethanak tak zgadza się. Tylko tu podejrzane jest przejście z czegoś szczegółowego do ogólnego ale od zewnątrz. Zazwyczaj nabudowuje się w przeciwnym kierunku. Np w Javie funkcje ogólnego przeznaczenia miały u mnie argument List (interfejs, tj. abstrakcyjny), a dopiero w konkretach zastępowałem np. ArrayList który już miał swój obiekt.

 Odesłałem do wyższej instancji, bo nie jestem ekspertem, ale jednak zaryzykuję i ocenię, że w tej funkcji HAL powinien być void *. Tak przynajmniej kojarzę z prac przy OpenGl, że jak coś się wysyłało do pamięci (tam do pamięci karty graficznej) to do adresowania danych jako zlepek bytów używało się void *.

image.thumb.png.f52b2349cebc492d647cc1fc8bd8ddf8.png

Ale chyba to nie ma większego znaczenia, bo jak jesteśmy w C to void * można iterować tak jak uint8_t co 1B więc to jest chyba tylko dylemat dot. estetyki kodu.

Link do komentarza
Share on other sites

42 minuty temu, Gieneq napisał:

void * można iterować tak jak uint8_t co 1B

Prawie... a prawie robi wielką różnicę.

Nie można np. zrobić dereferencji, a to może utrudnić życie.

Przykładowo (taka teoretyczna funkcja):
 

wypisz(void *d, int count)
{
    while (count-->0) wypisz_znak(*d++);
}

raczej słabo się skompiluje...

 

  • Lubię! 1
Link do komentarza
Share on other sites

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...

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.