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

Arduino Pro - Resetowanie programu przy odczycie danych z LIS3DH przez TWI

Witwickies 21 Gru 2016 17:17 1347 3
  • #1 16141361
    Witwickies
    Poziom 2  
    Witam!
    Zwracam się do Was z drobnym pytaniem. Generalnie to mój pierwszy projekt na nieco większą skalę więc całkiem możliwe, że o wielu podstawowych rzeczach mogę nie wiedzieć. Chciałbym, aby mikrokontroler (Atmega328P w Arduino Pro) pobierała przyspieszenia przez TWI oraz wysyłała je przez USART do modułu karty microSD OpenLog.
    Spotkałem się z pewną trudnością (jak udało mi się ustalić) przy komunikacji TWI. W momencie jej nastąpienia program niejako się resetuje. Lepiej będzie wytłumaczyć na podstawie kodu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Wynikowy plik .txt zawiera same kolumny, w których napisane jest "AccelX AccelY AccelZ". Błąd nie może być spowodowany komunikacją USART, gdyż specjalnie rozbiłem zapis tego na kilka komend - druga to enter, trzecia to cr. Po odblokowaniu przerwań następuje wywołanie dwóch funkcji związanych z akcelerometrem. Po ich przejściu do .txt powinno zapisać się "No dalej.... ;)" lecz... nie zapisuje się. Dioda na OpenLogu miga co ok. 5 sekund (ma oznaczać zapisanie danej) prawdopodobnie z powodu delaya umieszczonego na początku maina.
    Pisząc te funkcje do obsługi akcelerometru korzystałem z biblioteki TWI_Master dostarczonej przez Atmel . Jej dokumentacja jest w języku angielskim, toteż mogłem coś źle zrozumieć (darmowa, więc umieściłem ją w załączniku).
    Plik Akcelerometr.h:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    I funkcja z pliku Akcelerometr.c : (Druga jest baaaaardzo podobna)
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Jeśli chodzi o plik TWI_Master.h oraz TWI_Master.c dodałem je w załączniku (również chyba nie naruszam praw autorskich) wraz z przykładowym main.c. W pierwszym z nich zmieniłem wartość dotyczącą prędkości transmisji na 100kHz.

    Bardzo prosiłbym o pomoc. Nie mam pojęcia gdzie popełniłem błąd.
    EDIT: Czy to możliwe, iż powodem może być zasilanie? Arduino Pro mam w wersji 3,3V, podczas gdy w schemacie (w załączniku) akcelerometru na linii CS jest napisane 5,0V?
    Pozdrawiam,
  • #2 16142991
    Janusz_kk
    Poziom 38  
    Witwickies napisał:

    EDIT: Czy to możliwe, iż powodem może być zasilanie? Arduino Pro mam w wersji 3,3V, podczas gdy w schemacie (w załączniku) akcelerometru na linii CS jest napisane 5,0V?


    Zasilanie nie, ale nie wiem czy zauważyłeś że ten akcelerometr jest także zasilany z 3,3V, więc wszystkie konwersje są zbędne, wtedy ten CS, SDA i SDC łączysz na krótko do proca, co do programu widzę że włączasz przerwania dopiero po transmisji uart, dlaczego nie wcześniej?
  • #3 16143625
    Witwickies
    Poziom 2  
    Hmm, tak właściwie to nie wiem ;) Przesunąłem sei() w górę i znajduje się teraz tuż po USART_Initialise(). Generalnie to nic nie dało, wynikowy plik w .txt wciąż wygląda tak:
    AccelX AccelY AccelZ
    AccelX AccelY AccelZ
    i tak dalej... :/
    Zmiana portu na PB7 również nie przyniosła skutku. Domyślam się, iż niepoprawnie wykorzystuję bibliotekę do obsługi TWI. Jedyne pojawiające się w Atmel Studio ostrzeżenie dotyczy znaku w funkcji itoa (program chce dostać wskaźnik do unsigned char-a), lecz programowi daleko do wejścia w pętlę while().
    Znacie może jakieś inne biblioteki do obsługi TWI na AVR-ach? Większość z odnajdywanych przeze mnie dedykowana była innym rodzajom mikrokontrolerów.
  • #4 16152182
    Janusz_kk
    Poziom 38  
    No to popraw w kodzie TWI rejestry tak jak są w twoim procku, bo jeżeli np: ustawiasz bit który jest w innym rejestrze to kompilator nie pokaże błędu ale i program nie będzie działał, musisz zatem sprawdzić cały kod inicjacji czy bity i rejestry się zgadzają z Twoim prockiem

    Janusz

    Jeszcze jedno, po co ustwiasz 3 bit portu C? o to mam na myśli
    DDRC |= (1<<3);
    PORTC |= (1<<3);

    abstrahując od tego że taki kod jest nieczytelny, powinieneś to zrobić tak

    DDRC |= _BV(PC2);
    PORTC |= _BV(PC2);

    aby po pewnym czasie wiedzieć o co autorowi chodziło :)
REKLAMA