Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Liczba HEX (10 znaków) z tablicy char na liczbę DEC w innej tablicy.

AdamFilipek 16 Jan 2020 19:51 747 11
  • #1
    AdamFilipek
    Level 20  
    Witam.

    Mam taki oto nieskomplikowany kod:

    Code: c
    Log in, to see the code


    Atmega328p poprzez moduł RDM6300 odczytuje "pastylki" RFID i zapisuje do tablicy receivedCharArray.
    Ostatnie dwa znaki to suma kontrolna, czyli przy konwersji nie będę ich brać pod uwagę.
    Potrzebuję zamienić zawartość 10 komórek tej tablicy na wartość dziesiętną zapisaną w drugiej tablicy char - poproszę o wskazówki.


    Ewentualnie coś prostszego - jak skonwertować uint64_t do tablicy char?
    (być może znalazłem rozwiązanie jak przeliczyć hexa do zmiennej własnie tego typu, ale mam problem z wysłaniem jej na wyświetlacz i nie mogę tego zweryfikować, mój programator nie ma opcji debugowania)
  • #2
    BlueDraco
    MCUs specialist
    Nie potrzebujesz. Nie wiem, jaki pożytek mógłbyś mieć z 12-cyfrowej liczby dziesiętnej - co niby dalej miałbyś z nią robić?
    Przy okazji - masz błędny wzór na UBRR, a ten switch() jest świetnym przykładem na to, jak nie należy programować.
  • #3
    AdamFilipek
    Level 20  
    Zapewniam Cię, że wiem czy potrzebuję, czy nie.
    Aplikacja VISO od systemu kontroli dostępu pozwala wprowadzić "pastylkę" do systemu poprzez wprowadzenie liczby w postaci dziesiętnej.
    Docelowo rozwiązanie ma emulować klawiaturę HID i odczytaną wartość dziesiętną wysłać do pc.

    I nie 12 cyfrową bo maksymalna wartość 10 znakowej liczby szestnastkowej to 1099511627775, czyli 13 cyfr.

    Co do błędnego wzoru - pdf atmegi strona 179:
    Liczba HEX (10 znaków) z tablicy char na liczbę DEC w innej tablicy.

    Gdzie jest błąd we wzorze?
    (obsługę uart skopiowałem z jakiegoś rozwiązania znalezionego w necie)

    Co do konstrukcji switch() - tu masz rację, była to kompletna bzdura, poprawiłem. Dziękuję.

    Przypominam - prosiłem o pomoc przy konwersji, nie o ocenę kodu, nie o ocenę wzoru, ani tym bardziej o weryfikację przydatności liczby dziesiętnej.
    Parafrazując fragment postu kolegi BlueDraco - post kolegi BlueDraco jest świetnym przykładem na to, jak nie należy odpowiadać...
  • #4
    miszczo997
    Level 28  
    Nie wiem czy dobrze Cię rozumiem, ale czy nie chodzi Ci przypadkiem o funkcje typu lltoa(), sscanf(), czy też strol()? W ten sposób ze stringa zrobisz wartość, a później żeby przerobić to na stringa z wartością dziesiętną sprintf().
  • #5
    AdamFilipek
    Level 20  
    miszczo997 wrote:
    Nie wiem czy dobrze Cię rozumiem, ale czy nie chodzi Ci przypadkiem o funkcje typu lltoa(), sscanf(), czy też strol()? W ten sposób ze stringa zrobisz wartość, a później żeby przerobić to na stringa z wartością dziesiętną sprintf().


    Tak, dokładnie o to mi chodzi.
    Te funkcje świetnie się spisują dla: int, long, long long, ale potrzebuję aby zadziałały dla uint64_t.
  • #6
    Sareph
    Level 24  
    AdamFilipek wrote:
    Te funkcje świetnie się spisują dla: int, long, long long, ale potrzebuję aby zadziałały dla uint64_t.
    strtoull? Long long int ma przypadkiem 64bit.
  • #8
    BlueDraco
    MCUs specialist
    Błąd we wzorze na UBRR powoduje obcinanie zamiast zaokrąglania, co w efekcie daje niewłaściwą szybkość transmisji. Temat był wałkowany - trzeba do dzielnej dodać połowę szybkości.
    Tak długie liczby są mało wygodne do przetwarzania - łatwiej traktować to jako ciąg znaków reprezentacji szesnastkowej ew. sekwencję krótkich liczb (tak, jak adresy IP). Mały procesor zarżnie się na konwersji do i z 64 bitów, a i człowiek przy czytaniu i wpisywaniu z klawiatury raczej nie lubi 13-cyfrowych liczb bez separatorów/podziału na grupy. Mało to sensowne.
  • #9
    Janusz_kk
    Level 34  
    BlueDraco wrote:
    Błąd we wzorze na UBRR powoduje obcinanie zamiast zaokrąglania, co w efekcie daje niewłaściwą szybkość transmisji. Temat był wałkowany - trzeba do dzielnej dodać połowę szybkości.

    Możesz podać temat gdzie to wyjaśnione jest?
  • #10
    AdamFilipek
    Level 20  
    BlueDraco wrote:
    Błąd we wzorze na UBRR powoduje obcinanie zamiast zaokrąglania, co w efekcie daje niewłaściwą szybkość transmisji. Temat był wałkowany - trzeba do dzielnej dodać połowę szybkości.
    Tak długie liczby są mało wygodne do przetwarzania - łatwiej traktować to jako ciąg znaków reprezentacji szesnastkowej ew. sekwencję krótkich liczb (tak, jak adresy IP). Mały procesor zarżnie się na konwersji do i z 64 bitów, a i człowiek przy czytaniu i wpisywaniu z klawiatury raczej nie lubi 13-cyfrowych liczb bez separatorów/podziału na grupy. Mało to sensowne.

    Oczywiście masz rację co do wygody wprowadzania liczb 13 cyfrowych, ale ten system tak ma.
    Pastylkę można wprowadzić poprzez odczyt z czytnika przy drzwiach, poprzez odczyt z czytnika USB (nie dysponujemy takim) lub poprzez wprowadzenie właśnie wartości dziesiętnej z klawiatury.
    Do tej pory chodziliśmy do czytnika przy drzwiach, ale gdy pojawił się ten artykuł: Link, to przyszedł mi do głowy pomysł, aby zrobić coś samemu. Dużo wygodniej będzie przyłożyć pastylkę do pudełeczka na biurku zamiast iść do drzwi.
    Dzisiaj rano trochę grzebałem i udało mi się to przekonwertować i wysłać na LCD. Wykonałem kilkanaście prób i póki co nie było problemu ani z przeliczaniem, ani z niewłaściwą prędkością transmisji.
    Za sugestią kolegi Sareph użyłem zmiennej typu long long, zamiast uint64_t.

    przeliczanie:
    Code: c
    Log in, to see the code


    metoda HexDigitToDecValue:
    Code: c
    Log in, to see the code

    (teraz jak na to patrzę, to chyba niepotrzebne jest tam to rzutowanie na int)


    konwersja long long do tablicy char:
    Code: c
    Log in, to see the code


    metoda lltoa:
    Code: c
    Log in, to see the code


    cały kod:
    Code: c
    Log in, to see the code
  • #11
    BlueDraco
    MCUs specialist
    long long to to samo, co int64_t - u Ciebie dane powinny być bez znaku, czyli uint64_t. A pętla skanowania powinna wyglądać tak - z 500 razy szybsze wykonanie:
    Code: c
    Log in, to see the code
  • #12
    AdamFilipek
    Level 20  
    OK, dzięki - potestuję wieczorem.