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

C - UART, Atmega, funkcja atoi() i nieoczekiwany wynik

jarekz90 08 Sie 2012 21:28 1952 9
REKLAMA
  • #1 11188918
    jarekz90
    Poziom 13  
    Witam wszystkich, po paru godzinach walki siły me opadły i proszę Was o pomoc. Sprawa wygląda tak:
    Cel: wysyłam za pomocą terminala dane w kodzie ASCII które są następujące:
    :100; albo :44; albo :255; , przecinek pełni role początka ramki a średnik końca ramki tutaj kod odpowiedzialny za to:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Po otrzymaniu znaku średnika chce wykonać moje instrukcje za pomocą funkcji:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Oto kod funkcji:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Problem polega na tym, że co bym nie wysłać jakąkolwiek liczbę pomiędzy : i ; czy tez literkę poprzez terminal, zmienna zwracana przez funkcje atoi() daje NULL. I PWM zawsze ustawiany jest na 0, i konwertowana potem liczba wysyłana z powroten do terminala daje NULL.
    Nie potrafię się z tym uporać, temat był wałkowany, przejrzałem wiele tematów, ale ludzią to działa mi nie. Proszę o jakieś wskazówki, co robię źle gdzie jest kruczek. Pozdrawiam.
  • REKLAMA
  • #2 11189056
    szulat
    Poziom 23  
    Źle - zapisujesz łańcuch znakow pod adresem 0 (gdzie na pewnie jest jakas zmienna globalna ktorą w ten sposób psujesz)
    jarekz90 napisał:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    dobrze - łańcuch znaków trafia do bufora
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #3 11189104
    jarekz90
    Poziom 13  
    Po zmianie poprawiła się tylko wyświetlana wartość zera w terminalu, było <NULL> teraz jest 0. Najgorsze jest to, że nawet funkcja ustaw_PWM(); dostaje tylko 0. a powinna reagować na zmiany licz z zakresu od 0 do 255, wg. mnie funkcja atoi() jest winna bo nie zwraca tego co powinna, problemem może być złe przygotowanie wcześniej przeze mnie tego łańcucha znaków ale wydaje się znowu być w porządku.
  • #4 11189216
    szulat
    Poziom 23  
    A więc sprawdź czy to przypuszczenie jest słuszne: ramka_danych[0]='4'; ramka_danych[1]='2'; ramka_danych[2]=0; i zobaczysz czy wychodzi dobra liczba, a jeżeli wychodzi zła to kolejny etap - sprawdzenie czy linkuje ci odpowiednią wersję funkcji atoi
  • REKLAMA
  • #5 11189272
    jarekz90
    Poziom 13  
    Po wpisaniu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Terminal wyświetla tylko 4, ani 5 ani 2 nie widzi.
    Natomiast gdy zrobie:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Jak jest tak to jest wszystko ok i wyświetla normalnie liczbę 152.
    Po prostu czary mary inaczej tego nie można nazwać.
  • Pomocny post
    #6 11189443
    szulat
    Poziom 23  
    A może "buffor_danych" do którego wrzucasz kolejne bajty to też tylko wskaźnik zamiast tablicy (niezainicjowany lub ustawiony na 0)? To tłumaczyłoby dlaczego przypisanie ramka_danych do stałej tablicy znaków daje dobry wynik a ustawianie zawartosci kolejnymi bajtami się nie udaje. (podobnie do poprzedniego błędu)

    Przy okazji, sizeof(ramka_danych) to nie to co myślisz bo to tylko sizeof wskaźnika.

    Wszędzie gdzie masz char* przeanalizuj czy dany wskaźnik ma szansę wskazywać na jakiś istniejący bufor lub stałą tekstową. Bez tego operacje na tekstach nie będą działały.
  • REKLAMA
  • #7 11189488
    jarekz90
    Poziom 13  
    Dziękuje pomogło. Jestem ogromnie Tobie wdzięczny. Pozdrawiam i życze samych sukcesów.

    Dla zainteresowanych to była zmienna globalna:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Pomogła zmiana podpowiedziana przez użytkownika Szulat:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #8 11189512
    krru
    Poziom 33  
    Czy wysyłanie danych (USART_Transmit_string) też działa na przerwaniach i na odpowiedni bufor? Bo wywołujesz tą funkcję w przerwaniu od odbiornika i jeśli to czeka, to czeka tyle ile transmisja kilku znaków - w tym czasie gubisz przychodzące dane.
    Natomiast jak to masz na przerwaniach, to czy nadajnik posiada bufor, czy jedynie pamięta wskaźnik - w tym drugim przypadku próba wyświetlenia zmiennej lokalnej funkcji może dać dziwne rezultaty.
  • #9 11189723
    szulat
    Poziom 23  
    jarekz90 napisał:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Cieszę się że pomogło :)
    Przy okazji popraw też licznik++ bo w momencie gdy przekroczy 9 to kolejne znaki lub/i końcowy bajt zerowy będą trafiać poza tablicę. Najprościej daj ifa i ignoruj nadmiarowe dane.
  • #10 11189957
    jarekz90
    Poziom 13  
    Szulat napisał:
    Cytat:
    Przy okazji popraw też licznik++ bo w momencie gdy przekroczy 9 to kolejne znaki lub/i końcowy bajt zerowy będą trafiać poza tablicę. Najprościej daj ifa i ignoruj nadmiarowe dane.

    Racja, zdaje sobie z tego sprawę, to było w ramach testów, jakiś skromny protokół do swoich zastosowań zastosuje :)
    Krru napisał:
    Cytat:
    Czy wysyłanie danych (USART_Transmit_string) też działa na przerwaniach i na odpowiedni bufor? Bo wywołujesz tą funkcję w przerwaniu od odbiornika i jeśli to czeka, to czeka tyle ile transmisja kilku znaków - w tym czasie gubisz przychodzące dane.
    Natomiast jak to masz na przerwaniach, to czy nadajnik posiada bufor, czy jedynie pamięta wskaźnik - w tym drugim przypadku próba wyświetlenia zmiennej lokalnej funkcji może dać dziwne rezultaty.

    Tak w tym wypadku działa to na przerwaniach i jest dokładnie tak jak kolega mówi, to także w ramach testów było, bo dane wysyłałem tylko ja poprzez terminal. Wysyłanie danych będę chciał zrobić w pętli głównej, a uruchamiane będzie np. zmianą flagi przez odebranie danych jeśli będzie potrzeba echa.
REKLAMA