Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

STM32F107VCT6 - Komunikacja I2C między I2C1 a I2C2

gierzu 19 Sty 2013 16:22 2484 20
  • #1 19 Sty 2013 16:22
    gierzu
    Poziom 8  

    Witam,

    Staram się napisać komunikację I2C w obrębie jednego mikrokontrolera. Potem oczywiście planuję wykorzystać kod do komunikacji między dwoma podobnymi mikrokontrolerami. Niestety kod nie działa i nie wiem czemu, jeśli ktokolwiek pisał podobną rzecz bez wykorzystania biblioteki to bardzo proszę o rady. Poniżej zamieszczam kod programu. Muszę zaznaczyć że nie do końca rozumiem metodę wyliczania CCR oraz TRISE.


    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    0 20
  • #2 19 Sty 2013 16:28
    tadzik85
    Poziom 38  

    Na początek wartości konfiguracyjne warto wziąć z przykładów a manuala. Po 2 obsługa I2c w STM jest skomplikowana, a twój kod wygląda na całkowicie uproszczony. Proponuję zapoznać się z odpowiednim aplication note. Opisano tam dokładnie algorytm obsługi I2C.

    Istotne jest dokładne zapoznanie się ze zdarzeniami EV i flagami jakie są ustawiane oraz metodą ich kasowania.

    0
  • #3 19 Sty 2013 16:36
    gierzu
    Poziom 8  

    Tak właśnie zrobiłem, bardzo dokładnie prześledziłem aplication note, i wszystkie zdarzenia. Funkcje wysyłania i warunki w przerwaniu odpowiadają akcjom opisanym w tym dokumencie. Co więcej jestem pewien że obsługa przerwania jest poprawna gdyż została zaimplementowana do przykładu wykorzystującego bibliotekę.

    0
  • #4 19 Sty 2013 16:41
    tadzik85
    Poziom 38  

    A adresowanie układu? jakoś za krótkie u ciebie te funkcje.

    0
  • #5 19 Sty 2013 16:58
    gierzu
    Poziom 8  

    Co to znaczy za krótkie funkcje ? Takie są bo piszę bezpośrednio na rejestrach nie używając biblioteki która wszystko rozwleka na setki linijek. Adresowanie jest 7 bitowe, I2C1 ma adres "4" a I2C2 ma adres "2"

    0
  • #6 19 Sty 2013 17:00
    tadzik85
    Poziom 38  

    Sam nie korzystam z SPLa, a za krótkie mam na mysli fakt ze brak w nich paru szczegółów, choćby wysłania przez master adresu slave. A do tego nie jest wykorzystywane rejest adresu. Lub źle adresu ustawiłeś, wysyłasz 2 a adresu jak twierdzisz masz ustawione na 4 i 8

    0
  • #7 19 Sty 2013 17:03
    1417134
    Użytkownik usunął konto  
  • #8 20 Sty 2013 18:47
    m.ki
    Poziom 15  

    Jak dla mnie, zaraz po wysłaniu START master powinien wysłać adres slave'a.
    U Ciebie master to I2C1, a slave to I2C2, tak?
    No to dlaczego master wysyła jako adres "2":

    Kod: c
    Zaloguj się, aby zobaczyć kod

    zaś adres slave'a to 4:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    I w ogóle czemu jest ustawiony bit 0x4000? On chyba jest reserved?
    Na dodatek, jeśli master pisze coś do slave, to chyba powinien ustawić najmłodszy bit adresu, no nie?
    Czyli jak dla mnie, ta pierwsza instrukcja wysyłająca adres powinna wyglądać:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    To tak na szybko, nie szukałem innych błędów.

    Pozdrowienia,
    MKi

    0
  • #9 22 Sty 2013 18:05
    gierzu
    Poziom 8  

    Hej, na początek - dzięki za konstruktywną odpowiedź m.ki . Jeśli chodzi o adresowanie to właśnie tu jest problem nie do końca przebijam się przez dokumentację w której w dość niejasny sposób jest powiedziane jak adresować w trybie 7 i 10 bitowym. Ale może w tym tkwi problem. Na pewno spróbuję coś z tym pokombinować. A bit 0x4000 w rejestrze adresu tak jak napisałeś jest zarezerwowany, ale jednocześnie w dokumentacji napisane jest że należy do softwaru aby został on utrzymany na poziomie logicznej jedynki.

    0
  • #10 22 Sty 2013 18:29
    tadzik85
    Poziom 38  

    Spójrz dokładnie na strukturę rejestru adresowego I2C w STM

    w trybie 7-bitowym masz ze bity 7:1 odpowiadają bitom 7:1 adresu. TU nie ma przesunięć! Przecież ostatni bit adresu układu świadczy o kierunku transmisji więc w tym rejestrze jest nieistotny.

    0
  • #11 23 Sty 2013 19:02
    m.ki
    Poziom 15  

    Z tego

    gierzu napisał:
    Adresowanie jest 7 bitowe, I2C1 ma adres "4" a I2C2 ma adres "2"

    wynika, że nie do końca czujesz protokół I2C.

    W I2C jeden układ zawsze jest master, pozostałe są slave. Master NIE ma adresu - on inicjuje komunikację wysyłając w szynę adres tego slave'a, z którym chce pogadać. Slave odpowiada przez ACK, co dla mastera jest informacją, że na szynie jest slave o tym adresie i można zacząć rozmawiać.

    A, tak mi się jeszcze pomyślało - jeśli masz problem z ogarnięciem adresacji - bo hasło "adresowanie 7-bitowe" jest deczko mylne. Adresowanie jest de facto 8-bitowe. Najmłodszy bit adresu mówi o kierunku transmisji (1 - od master do slave, 0 - od slave do master). Siedem starszych bitów to jest ten "adres 7-bitowy". Można to rozumieć tak, że każde urządzenie slave ma dwa adresy - jeden do czytania (zawsze parzysty), drugi do pisania (zawsze nieparzysty).
    W dokumentacji czasem podaje się tylko te 7 najstarszych bitów i to może być mylące.

    Pozdrowienia,
    m.ki

    0
  • #12 23 Sty 2013 19:36
    gierzu
    Poziom 8  

    Informacja o tym jednym bicie przyda się bo tego nie doczytałem w nocie a do dokumentacji samego protokołu jakoś nie miałem siły zaglądać. A nadanie adresu I2C1 nie jest błędem choć w tym przykładzie go nie wykorzystuję.

    0
  • #13 23 Sty 2013 21:50
    m.ki
    Poziom 15  

    gierzu napisał:
    do dokumentacji samego protokołu jakoś nie miałem siły zaglądać.

    Obawiam się więc, że masz małe szanse na sukces. Protokół nie jest skomplikowany, ale konieczna jest podstawowa znajomość, choćby co znaczą w poszczególnych momentach ACK i NACK. Znajdziesz sporo nawet po polsku, więc sugeruję jednak lekturę.

    gierzu napisał:
    A nadanie adresu I2C1 nie jest błędem choć w tym przykładzie go nie wykorzystuję.

    Ja nie mówię, że to błąd, tylko że sam fakt użycia sugeruje, że nie znasz protokołu.

    (Tak już zupełnie elementarnie: dałeś podciągnięcia 3k do linii I2C?)

    Pozdrowienia,
    m.ki

    0
  • #14 23 Sty 2013 22:40
    gierzu
    Poziom 8  

    Tak, jej naprawdę nie rozumiem czemu to tak zawsze wygląda na forum, jak prosisz o pomoc to zawsze będą ci chcieli udowodnić że jesteś pajacem. A pierwszą odpowiedź dotyczącą "zbyt krótkich funkcji" oraz "wartości konfiguracyjne warto wziąć z przykładów" zostawię bez większego komentarza. Mogę tylko powiedzieć że zazwyczaj ludzie umieszczający jakiś problem na forum mają nadzieję na odpowiedź kogoś kompetentnego kto przepatrzy dokładnie kod i sam ma doświadczenie w podobnej lub identycznej sprawie. Znachorzy zaczynający dyskusję od wypytywania "co to?", "dlaczego tak a nie siak?" itp. naprawdę nie pomagają. Ja umieściłem problem na forum po raz pierwszy bo to jest jedyny protokół z podstawowych który sprawia mi problem na tym mikrokontrolerze. Zaznaczę że zrobiłem już w nim połączenie z modułem zegara (jako master odczytując rejestry zegara), problem pojawił się gdy chciałem połączyć dwa mikrokontrolery tego samego typu za pomocą tego protokołu.

    0
  • #15 23 Sty 2013 23:24
    Freddie Chopin
    Specjalista - Mikrokontrolery

    gierzu napisał:
    Tak, jej naprawdę nie rozumiem czemu to tak zawsze wygląda na forum...

    Dokładnie zawsze tak to wygląda jak nie czytasz dokumentacji. Nikt tutaj nie będzie Ci jej przepisywał.

    gierzu napisał:
    Znachorzy zaczynający dyskusję od wypytywania "co to?", "dlaczego tak a nie siak?" itp. naprawdę nie pomagają.

    Czyli jak masz coś totalnie źle, bez sensu, od złej strony, ze złymi założeniami to już nie można zasugerować zmiany? No więc po co pytasz na forum, skoro kod który przedstawiłeś jest bez zarzutu?

    gierzu napisał:
    Mogę tylko powiedzieć że zazwyczaj ludzie umieszczający jakiś problem na forum mają nadzieję na odpowiedź kogoś kompetentnego kto przepatrzy dokładnie kod i sam ma doświadczenie w podobnej lub identycznej sprawie.

    Ja zawsze przestaję patrzeć jak znajdę pierwszą głupotę. Z tego co widzę powyżej takich "ciekawostek" w Twoim kodzie znaleziono już kilka, wg Ciebie wszystko jest dobrze... No to skoro jest dobrze, to po co w ogóle ten temat?

    Pozatym właściwa odpowiedź już padła. No chyba że oczekujesz, że ktoś Ci poprawi kod i wrzuci tutaj, abyś Ty tylko mógł sobie go skompilować?

    gierzu napisał:
    Zaznaczę że zrobiłem już w nim połączenie z modułem zegara (jako master odczytując rejestry zegara), problem pojawił się gdy chciałem połączyć dwa mikrokontrolery tego samego typu za pomocą tego protokołu.

    Pewnie dlatego, że - jak już ktoś zauważył - nie rozumiesz protokołu. Połączyłeś się jako Master z zegarkiem który był Slave. Jak się chcesz połączyć z innym mikrokontrolerem, to jeden z nich musi mieć praktycznie zupełnie inny kod niż ten który napisałeś dla zegarka.

    Nie mówiąc już o wyjątkowo wesołym pomyśle na obsługę LCD w przerwaniu i to jeszcze ze sprintf()...

    4\/3!!

    0
  • #16 24 Sty 2013 07:44
    gierzu
    Poziom 8  

    Wiesz co przeprogramowałem kod wg. instrukcji i nie działa. Dobrze zapytam inaczej, który z was postawił na mikrokontrolerze z tej serii komunikację przy pomocy protokołu I2C bez użycia biblioteki? Po drugie przeczytałem cały dział Reference manual RM0008 dotyczący tej komunikacji na tym mikrokontrolerze. W teorii jest tam opisany ten protokół i wszystkie możliwe zdarzenia na linii, co należy robić w danym momencie itp. Ale albo ja nie umiem czytać albo ktoś poważnie schrzanił sprawę pisząc to. A odnosząc się do ostatniej wypowiedzi, chciałbym zapytać co jej autor ma na myśli mówić o wesołym pomyśle na obsługę wyświetlacza w przerwaniu ? Używałem tego już wiele razy do debugowania programu i nigdy nie sprawiało to problemu.

    0
  • #17 24 Sty 2013 08:54
    Freddie Chopin
    Specjalista - Mikrokontrolery

    gierzu napisał:
    Wiesz co przeprogramowałem kod wg. instrukcji i nie działa.

    To może warto go wrzucić ponownie i opisać czy coś się zmieniło?

    gierzu napisał:
    Dobrze zapytam inaczej, który z was postawił na mikrokontrolerze z tej serii komunikację przy pomocy protokołu I2C bez użycia biblioteki?

    A co można wygrać w tym quizie? (;

    gierzu napisał:
    A odnosząc się do ostatniej wypowiedzi, chciałbym zapytać co jej autor ma na myśli mówić o wesołym pomyśle na obsługę wyświetlacza w przerwaniu ? Używałem tego już wiele razy do debugowania programu i nigdy nie sprawiało to problemu.

    To że nie widzisz problemu nie znaczy że go tam nie ma. Załóżmy że obsługa wyświetlacza wraz z wywołaniem sprintf() trwa 1ms, oraz że w urządzeniu przychodzi Ci jedno zdarzenie na 100us. Nie wiem o jakim kompilatorze i jakiej bibliotece mowa, ale sprintf() z newlib zajmuje sobie całkiem sporo stosu, więc równie dobrze nie-działanie Twojego programu może wynikać z nadpisywania jakichś zmiennych...

    Nie mówiąc już o tym, że zarówno w main() jak i w przerwaniu wywołujesz te same funkcje, a czy one są reentrant? Czy może takie pojęcie Ci nic nie mówi wiec założyłeś, że problemu nie ma?

    Zawsze myślałem, że jak się rozwiązuje "magiczny" problem, to się dąży do NAJPROSTSZEJ problematycznej postaci kodu, a nie sprintf() i LCD obsługiwany jednocześnie przez dwa zupełnie różne wątki...

    4\/3!!

    0
  • #18 24 Sty 2013 09:26
    gierzu
    Poziom 8  

    Jeżeli nie wiesz o jakiej bibliotece mówię to tylko tracisz swój i mój czas bo oznacza to że najprawdopodobniej nigdy nie programowałeś mikrokontrolerów z serii STM32F10**. A jeśli chodzi o reentrant to w napisanym programie nie ma możliwości aby doszło do tego typu zdarzenia a czas wykonywania instrukcji nie ma znaczenia. I przestań cytować wypowiedzi bo nie są na tyle długie żeby istniała potrzeba odnoszenia się do konkretnej części. Wygląda to śmiesznie i sugeruje to że chcesz poniżyć przedmówcę.

    0
  • #19 24 Sty 2013 09:36
    Freddie Chopin
    Specjalista - Mikrokontrolery

    gierzu napisał:
    Jeżeli nie wiesz o jakiej bibliotece mówię to tylko tracisz swój i mój czas bo oznacza to że najprawdopodobniej nigdy nie programowałeś mikrokontrolerów z serii STM32F10**.

    No - masz mnie (;

    Możesz mi jednak wskazać, w którym miejscu zasugerowałem Ci, że nie wiem o jakiej bibliotece mówisz? Może być cytat (;

    gierzu napisał:
    A jeśli chodzi o reentrant to w napisanym programie nie ma możliwości aby doszło do tego typu zdarzenia a czas wykonywania instrukcji nie ma znaczenia.

    Skoro z taką pewnością o tym piszesz to na pewno tak jest.

    gierzu napisał:
    I przestań cytować wypowiedzi bo nie są na tyle długie żeby istniała potrzeba odnoszenia się do konkretnej części. Wygląda to śmiesznie i sugeruje to że chcesz poniżyć przedmówcę.

    Ups, I did it again... Zawsze możesz nie czytać moich wypowiedzi - widzisz mojego avatara to od razu zamykasz okienko lub przechodzisz dalej.

    4\/3!!

    0
  • #20 24 Sty 2013 14:06
    McMonster
    Poziom 32  

    gierzu napisał:
    Jeżeli nie wiesz o jakiej bibliotece mówię to tylko tracisz swój i mój czas bo oznacza to że najprawdopodobniej nigdy nie programowałeś mikrokontrolerów z serii STM32F10**.

    Jest cała masa ludzi, którzy dzięki artykułom, materiałom, bezpośredniej pomocy Freddiego, a nawet dzięki jego programatorowi nauczyło się programować mikrokontrolery ARM, w szczególności STM32. Nie kwapisz się do czytania dokumentacji, nie spróbowałeś nawet skorzystać z wyszukiwarki forum, oczekujesz podania na tacy informacji w taki sposób, w jaki ci się podoba. Ignorujesz przy tym masę bardzo istotnych uwag, które są kierowane do ciebie wcale nie z czystej złośliwości, ale o które dopraszasz się sam roszczeniowym tonem wypowiedzi.

    Cytat:
    A jeśli chodzi o reentrant to w napisanym programie nie ma możliwości aby doszło do tego typu zdarzenia a czas wykonywania instrukcji nie ma znaczenia. (...)

    Może nie ma teraz, a może po prostu tego nie widzisz. Już zostało wspomniane, dlaczego w toku wprowadzania zmian, albo nawet wykorzystania układu w trochę inny, niż przewidywany sposób. Stąd uczulenie wielu użytkowników forum na taki sposób wykorzystania przerwań, ponownie nie z czystej złośliwości. Denerwujesz się na to, że ktoś chce ci przekazać dobrą radę.

    0
  • #21 24 Sty 2013 17:45
    m.ki
    Poziom 15  

    gierzu napisał:
    Tak, jej naprawdę nie rozumiem czemu to tak zawsze wygląda na forum, jak prosisz o pomoc to zawsze będą ci chcieli udowodnić że jesteś pajacem.

    Czy pijesz do mojego postu?
    Jeśli tak to chyba uczyliśmy się innego języka polskiego.
    Czy moje twierdzenia o nieznajomości protokołu traktujesz jako udawadnianie pajacostwa?

    Pozwolę sobie dodać: napisałem już parę kawałków kodu obsługującego I2C, z obsługą "na piechotę" i z wykorzystaniem sprzętu, z przerwaniami i bez, na procesory 8 i 32 bitowe, z biblioteką ST i bez. I twierdzę, że zacząć trzeba od poznania protokołu. Jeszcze żeby opis nie był po polsku dostępny...

    Pozdrowienia,
    m.ki

    0
  Szukaj w 5mln produktów