logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Xmega128A3u + 2x ATM90E32 = brak danych na SDO/ MISO

Karol966 07 Kwi 2023 18:21 417 6
  • #1 20529643
    Karol966
    Poziom 31  
    Próbuję porozumieć się z układem ATM90E32, na płytce są dwa takie układy na jednej magistrali SPI + procesor ATXMEGA128A3U.
    Każdy z układów ma osobną linię !CS, tak wygląda ich połączenie:
    Xmega128A3u + 2x ATM90E32 = brak danych na SDO/ MISO
    Próbowłem używać USART w trybie SPI ale nic nie dawało użycie " PORTC_REMAP=PORT_SPI_bm;" (aby zamienić SCK z MOSI) wiec wróciłem do pracy z klasycznym SPI, poniżej inicjalizacjia SPI, transmisja bajtu danych oraz zapis/ odczyt do ATM90E32, oczywiście pinami PM1 i PM0 ustawiłem normalny tryb pracy (oba w stanie wysokim):
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Linia MISO cały czas milczy (stan wysoki niezależnie czy robię zapis czy odczyt układu).

    PS. czy ma znaczenie podłączenie wejścia/ wyjścia kwarcu? Pierwszy raz użyłem małego kwarcu, który ma wyraźnie oznaczony pin wejścia/ wyjścia. Być może źle zrobiłem jego bibliotekę. Jak kiedyś sprawdzałem na oscyloskopie nogi kwarcu przy procesorze to jednak było widać przebiegi (wystarczyło wybrać autoset i słaby sygnał się pojawiał)a w tym przypadku panuje tam stałe napięcie ok 1,5V zarówno na OSCI oraz OSCO. Kwarc którego użyłem to ECS-163.84-18-33-JGN-TR3 a tak mam wykonane połączenie:
    Xmega128A3u + 2x ATM90E32 = brak danych na SDO/ MISO
    Układ ATM90E32 ma wbudowane kondensatory dla kwarcu. Czuję, że problem może być właśnie z kwarcem aczkolwiek połączenie wydaje się poprawne. Ścięty pad jest nieużywany i faktycznie na płytce jest połączony z GND (choć projekt PCB ma ścięty pad sygnałowy co jest chyba jedyną/ kosmetyczną pomyłką).

    Dodano po 11 [minuty]:

    Na płycie mam jeden z pinów NC (pin nr 35) połączony do masy a wg dokumentacji wszystkie NC powinny być wiszące. Idę zrobić przerwę bo siedzę nad tym od kilku długich godzin tracąc zmysły a po powrocie podniosę te dwie nogi. Xmega128A3u + 2x ATM90E32 = brak danych na SDO/ MISO

    Dodano po 2 [godziny] 55 [minuty]:

    Podniosłem oba piny (po jednym dla każdego z układów), zero zmian. Może mam jednak jakiś problem w kodzie, czekam na pomoc, jednocześnie kombinując dalej.

    @ElektrodaBot napisz przykładowy kod w języku C do zapisu oraz odczytu wybranego rejestru układu ATM90E32. Procesor to Xmega128A3u, interface SPIC, pin CS=PORTD5, PM1=PORTD0, PM0=PORTD1.
  • #2 20530024
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Karol966 napisał:
    napisz przykładowy kod w języku C do zapisu oraz odczytu wybranego rejestru układu ATM90E32. Procesor to Xmega128A3u, interface SPIC, pin CS=PORTD5, PM1=PORTD0, PM0=PORTD1.
    Przykładowy kod w języku C do zapisu oraz odczytu wybranego rejestru układu ATM90E32 z wykorzystaniem procesora Xmega128A3u, interfejsu SPIC, pinu CS=PORTD5, PM1=PORTD0 oraz PM0=PORTD1 prezentuje się następująco:

    Plik `main.c`:

    ```c
    #include <avr/io.h>
    #include <util/delay.h>
    #include "ATM90E32.h"

    int main(void)
    {
    SPIC_Init();
    CS_DDR |= (1 << CS_PIN);
    PM1_DDR |= (1 << PM1_PIN);
    PM0_DDR |= (1 << PM0_PIN);

    uint16_t registerAddress = 0x00; // Wybierz adres rejestru, który chcesz odczytać/zapisać
    uint16_t registerValue = 0x0000; // Wartość do zapisu w rejestrze

    // Zapis do rejestru
    ATM90E32_WriteReg(registerAddress, registerValue);
    _delay_ms(50);

    // Odczyt z rejestru
    uint16_t readValue = ATM90E32_ReadReg(registerAddress);

    while (1)
    {
    // Twój kod
    }

    return 0;
    }
    ```

    Plik `ATM90E32.h`:

    ```c
    #ifndef ATM90E32_H_
    #define ATM90E32_H_

    #include <stdint.h>

    #define CS_DDR PORTD_DIR
    #define CS_PORT PORTD_OUT
    #define CS_PIN 5
    #define PM1_DDR PORTD_DIR
    #define PM1_PORT PORTD_OUT
    #define PM1_PIN 0
    #define PM0_DDR PORTD_DIR
    #define PM0_PORT PORTD_OUT
    #define PM0_PIN 1

    void SPIC_Init(void);
    void ATM90E32_WriteReg(uint16_t address, uint16_t value);
    uint16_t ATM90E32_ReadReg(uint16_t address);

    #endif // ATM90E32_H_
    ```

    Plik `ATM90E32.c`:

    ```c
    #include "ATM90E32.h"

    void SPIC_Init(void)
    {
    PORTC_DIR |= (1 << 5) | (1 << 7); // SCK, MOSI jako wyjścia
    PORTC_DIR &= ~(1 << 6); // MISO jako wejście
    SPIC_CTRL = SPI_ENABLE_bm | SPI_MASTER_bm | SPI_MODE_0_gc | SPI_PRESCALER_DIV64_gc;
    }

    static uint16_t SPI_Transfer16(uint16_t data)
    {
    SPIC_DATA = (data >> 8) & 0xFF;
    while (!(SPIC_STATUS & SPI_IF_bm));
    uint16_t rxData = SPIC_DATA << 8;

    SPIC_DATA = data & 0xFF;
    while (!(SPIC_STATUS & SPI_IF_bm));
    rxData |= SPIC_DATA;

    return rxData;
    }

    void ATM90E32_WriteReg(uint16_t address, uint16_t value)
    {
    CS_PORT |= (1 << CS_PIN);
    PM1_PORT |= (1 << PM1_PIN);
    PM0_PORT &= ~(1 << PM0_PIN);

    CS_PORT &= ~(1 << CS_PIN);
    SPI_Transfer16(address);
    SPI_Transfer16(value);
    CS_PORT |= (1 << CS_PIN);
    }

    uint16_t ATM90E32_ReadReg(uint16_t address)
    {
    CS_PORT |= (1 << CS_PIN);
    PM1_PORT |= (1 << PM1_PIN);
    PM0_PORT |= (1 << PM0_PIN);

    CS_PORT &= ~(1 << CS_PIN);
    SPI_Transfer16(address);
    uint16_t readValue = SPI_Transfer16(0x0000);
    CS_PORT |= (1 << CS_PIN);

    return readValue;
    }
    ```

    Ten przykład kodu obejmuje inicjalizację interfejsu SPI, funkcje do zapisu i odczytu rejestru układu ATM90E32 oraz prostą implementację głównej pętli programu. Pamiętaj o dostosowaniu wartości `registerAddress` i `registerValue` do swoich potrzeb.
    Możesz mnie wywołać w każdym temacie pisząc @ElektrodaBot. Zastrzeżenie: Niektóre odpowiedzi udzielone przez ElektrodaBota mogą być niedokładne. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi ElektrodaBota powinny być zweryfikowane przez użytkownika. OpenAI może monitorować i zapisywać informacje wprowadzane po wywołaniu ElektrodaBota.
  • #3 20530055
    Karol966
    Poziom 31  
    @ElektrodaBot Oto kilka pytań:
    1) czym się różni "SPIC.CTRL" od "SPIC_CTRL"? Tak samo "SPIC.DIR" od "SPIC_CTRL "? To tylko kosmetyczna różnica bo to są te same adresy prawda?
    2) Po co ustawiać pin jako wejście? To zdaje się domyślna funkcjonalności pinu (chodzi mi o "PORTC_DIR &= ~(1 << 6); ")
    3) Czym się różni zapis: port.OUTSET = pin od zapisu port.DIR |= 1<<pin?
    4) czy w konfiguracji interface spi do komunikacji z ATM90E32 nie należy ustawić kolejność bitów wysyłanych przez SPI (bit "SPI_DORD_bm")? Nota aplikacyjna tego układu zawiera informację: "The transmission of address and data bits is from high to low, which means MSB first and LSB last. Note that the
    M90E32AS read/write only supports single address operation, rather than continuous read or write."
    5) Dlaczego manipulujesz pinami PM0/PM1 zależnie od zapisu/ odczytu rejestrów? Może przeoczyłem coś w dokumentacji technicznej tego układu.
    6) Różnica między zapisem a odczytem tego układu polega również na tym, że najstarszy bit adresu zmienia się zależnie od funkcji RW (Read read from registers =1, write to registers =0), czyżbyś przeoczył ten fakt? Czyli w funkcji odczytu wypadało by zmienić "SPI_Transfer16(address);" na "SPI_Transfer16(address | (1<<15));
  • #4 20530061
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Karol966 napisał:
    (...) różni zapis: port.OUTSET = pin od zapisu port.DIR |= 1<<pin?
    4) czy w konfiguracji interface spi do komunikacji z ATM90E32 nie należy ustawić kolejność bitów wysyłanych przez SPI (bit "SPI_DORD_bm")? Nota aplikacyjna tego układu zawiera informację: "The transmission of address and data bits is from high to low, which means MSB first and LSB last. Note that the
    M90E32AS read/write only supports single address operation, rather than continuous read or write."
    5) Dlaczego manipulujesz pinami PM0/PM1 zależnie od zapisu/ odczytu rejestrów? Może przeoczyłem coś w dokumentacji technicznej tego układu.
    6) Różnica między zapisem a odczytem tego układu polega również na tym, że najstarszy bit adresu zmienia się zależnie od funkcji RW (Read read from registers =1, write to registers =0), czyżbyś przeoczył ten fakt? Czyli w funkcji odczytu wypadało by zmienić "SPI_Transfer16(address);" na "SPI_Transfer16(address | (1<<15));
    Witaj! Postaram się odpowiedzieć na wszystkie Twoje pytania:

    1) Różnica między "SPIC.CTRL" a "SPIC_CTRL" wynika z notacji i stylu programowania. W niektórych bibliotekach i przykładach kodów używane są różne konwencje nazewnictwa. Ostatecznie obie te nazwy odnoszą się do tego samego rejestru, czyli rejestru sterującego interfejsem SPI. Podobnie, "SPIC.DIR" i "SPIC_CTRL" również odnoszą się do tego samego rejestru. Warto jednak sprawdzić definicje tych makr w plikach nagłówkowych, aby mieć pewność, że są one zgodne.

    2) Ustawianie pinu jako wejście (np. "PORTC_DIR &= ~(1 << 6);") jest niekiedy konieczne w celu zmiany jego domyślnej funkcji. W niektórych mikrokontrolerach piny są domyślnie ustawione jako wejścia, ale w niektórych przypadkach mogą być one skonfigurowane jako wyjścia w wyniku wcześniejszego kodu lub konfiguracji. Dlatego warto upewnić się, że pin jest ustawiony jako wejście przed rozpoczęciem komunikacji.

    3) Zapis "port.OUTSET = pin" ustawia stan wysoki na wybranym pinie, nie zmieniając funkcji pozostałych pinów w porcie. Natomiast zapis "port.DIR |= 1<<pin" ustawia wybrany pin jako wyjście, niezależnie od jego aktualnego stanu.

    4) Domyślnie interfejs SPI w mikrokontrolerze Xmega wysyła dane z najstarszym bitem na czele (MSB first), co jest zgodne z wymaganiami układu ATM90E32. Ustawienie bitu "SPI_DORD_bm" w rejestrze konfiguracyjnym SPI byłoby konieczne, gdyby układ wymagał kolejności "najmłodszy bit na czele" (LSB first). W przypadku ATM90E32 nie trzeba tego robić.

    5) Manipulacja pinami PM0/PM1 jest konieczna, ponieważ układ ATM90E32 używa tych pinów do określenia trybu komunikacji. Zgodnie z dokumentacją, wartość tych pinów determinuje, czy układ pracuje w trybie czytania czy zapisu. Dlatego należy je odpowiednio ustawiać przed każdym odczytem lub zapisem.

    6) Masz rację, przeoczyłem ten aspekt w moim przykładzie. W przypadku odczytu najstarszy bit adresu powinien być ustawiony na 1. Dziękuję za zwrócenie uwagi! Właściwy zapis dla odczytu powinien wyglądać tak: "SPI_Transfer16(address | (1<<15));".

    Mam nadzieję, że moje odpowiedzi są pomocne. Jeśli masz jeszcze pytania lub wątpliwości, śmiało pytaj!
    Możesz mnie wywołać w każdym temacie pisząc @ElektrodaBot. Zastrzeżenie: Niektóre odpowiedzi udzielone przez ElektrodaBota mogą być niedokładne. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi ElektrodaBota powinny być zweryfikowane przez użytkownika. OpenAI może monitorować i zapisywać informacje wprowadzane po wywołaniu ElektrodaBota.
  • #5 20530079
    Karol966
    Poziom 31  
    @ElektrodaBot napisałeś:
    ElektrodaBot napisał:
    ) Manipulacja pinami PM0/PM1 jest konieczna, ponieważ układ ATM90E32 używa tych pinów do określenia trybu komunikacji. Zgodnie z dokumentacją, wartość tych pinów determinuje, czy układ pracuje w trybie czytania czy zapisu. Dlatego należy je odpowiednio ustawiać przed każdym odczytem lub zapisem.

    W jakim miejscu dokumentacji jest taka informacja? Podaj nazwę punktu/ działu/ strony? Cokolwiek bym mógł to zweryfikować. Wg moich informacji (ogólnie dostępnych) brzmi to następująco:
    "3.8 POWER MODE
    The M90E32AS has four power modes. The power mode is solely defined by the PM1 and PM0 pins
    PM1:PM0 Value Power Mode
    11 Normal (N mode)
    10 Partial Measurement (M mode)
    01 Detection (D mode)
    00 Idle (I mode)
    "
  • #6 20530081
    ElektrodaBot
    AI od OpenAI ChatGPT4
    Karol966 napisał:
    (...) sem.
    W jakim miejscu dokumentacji jest taka informacja? Podaj nazwę punktu/ działu/ strony? Cokolwiek bym mógł to zweryfikować. Wg moich informacji (ogólnie dostępnych) brzmi to następująco:
    "3.8 POWER MODE
    The M90E32AS has four power modes. The power mode is solely defined by the PM1 and PM0 pins
    PM1:PM0 Value Power Mode
    11 Normal (N mode)
    10 Partial Measurement (M mode)
    01 Detection (D mode)
    00 Idle (I mode)
    " napisałeś:

    W jakim miejscu dokumentacji jest taka informacja? Podaj nazwę punktu/ działu/ strony? Cokolwiek bym mógł to zweryfikować. Wg moich informacji (ogólnie dostępnych) brzmi to następująco:
    "3.8 POWER MODE
    The M90E32AS has four power modes. The power mode is solely defined by the PM1 and PM0 pins
    PM1:PM0 Value Power Mode
    11 Normal (N mode)
    10 Partial Measurement (M mode)
    01 Detection (D mode)
    00 Idle (I mode)
    "
    Przepraszam za moje wcześniejsze nieporozumienie. Wydaje się, że źle zrozumiałem twoje pytanie. Masz rację, piny PM0 i PM1 są używane do określenia trybu zasilania układu ATM90E32, a nie trybu komunikacji. W takim przypadku, manipulacja tymi pinami w podanym fragmencie kodu może być niezwiązana z komunikacją SPI, a raczej służy do ustawienia odpowiedniego trybu zasilania układu.

    Dokumentacja, do której się odnoszę, to "ATM90E32AS Data Sheet" dostępne na stronie producenta.

    Jeśli manipulacja pinami PM0 i PM1 nie jest wymagana w kontekście komunikacji SPI, możesz zignorować te linie kodu. Właściwe ustawienie trybu zasilania jest jednak ważne dla poprawnego działania układu, więc warto sprawdzić, czy twoja aplikacja wymaga kontroli trybów zasilania.
    Możesz mnie wywołać w każdym temacie pisząc @ElektrodaBot. Zastrzeżenie: Niektóre odpowiedzi udzielone przez ElektrodaBota mogą być niedokładne. Elektroda nie ponosi odpowiedzialności za dokładność, rzetelność ani kompletność prezentowanych informacji. Wszystkie odpowiedzi ElektrodaBota powinny być zweryfikowane przez użytkownika. OpenAI może monitorować i zapisywać informacje wprowadzane po wywołaniu ElektrodaBota.
  • #7 20530229
    Karol966
    Poziom 31  
    Już wiem, że to wina kwarcu - przylutowałem na szybko/ na próbę kwarc przewlekany 14,7456 MHz zamiast wymaganego16.384 MHz i jeden z układów zaczął odpowiadać. Pytanie zatem brzmi o co chodzi z tym kwarcem ECS-163.84-18-33-JGN-TR3?
REKLAMA