Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

LPC1768, Keil - Czyszczenie flagi przerwania TIM0, startup i inne

piterrr_ 30 Jul 2015 18:53 1242 4
Computer Controls
  • #1
    piterrr_
    Level 11  
    Witam,
    Jestem początkujący jeśli chodzi o programowanie ARM wiec proszę o wyrozumiałość.
    Mam problem z procesorem LPC 1768, konkretnie jest to płytka Mini DK-2. Od pewnego czasu walczę z problemami w przerwaniach i nie mogę sobie poradzić. Przewertowałem setki tematów na forach polskich i zagranicznych, być może źle szukałem, wiec każda wskazówka i link będą mile widziane. Podejrzewam ze gdzieś w pliku startup coś może być źle zadeklarowane, niestety na assemblerze i plikach startupow w ogóle sie nie znam, próbowałem czytać różne tutoriale oraz informacje na stronie keila, NXP a także podmieniać startupa z gotowych projektów, ale nie pomogło.
    Do rzeczy- do programowania używam Keila oraz programator J-Link. W przykładowym kodzie w przerwaniu z Timera0 instrukcje niekoniecznie wykonywane są poprawnie i co zauważyłem zależne jest to od miejsca w którym czyszczę flagę przerwania. Jeśli zrobię to na początku wszystko jest OK, jeśli na końcu nie wykonuje się pierwszy warunek if. Jeśli sprawdzam debuggerem krok po kroku wszystko działa OK. Optymalizacje kodu mam wyłączona. Miałem też inne problemy z wykonywaniem kodu w przerwaniu timera0 (efektem tego były jakieś dziwne wartości zmiennych- wszystkie oczywiście zadeklarowane jako volatile). Zależnie od ustawień prescalera i wartosci MR0 timera niektóre wartości nie były prawidłowo wpisywane- ale najpierw zajmijmy się najprostszym przykładem przedstawionym w kodzie.
    W razie potrzeby mogę załączyć/wysłać cały spakowany projekt.

    Plik startup.s:
    Code: C
    Log in, to see the code


    System_LPC17xx.c:
    Code: C
    Log in, to see the code


    Program main:
    Code: C
    Log in, to see the code


    Interrupts.c
    Code: C
    Log in, to see the code


    Interrupts.h:
    Code: C
    Log in, to see the code


    GPIO_CFG.c:
    Code: C
    Log in, to see the code


    GPIO_CFG.h:
    Code: C
    Log in, to see the code


    timer_param.c:
    Code: c
    Log in, to see the code


    Timer_param.h
    Code: C
    Log in, to see the code


    Kod był tysiące razy zmieniany, mam nadzieje, że nigdzie nie zapomniałem czegoś odznaczyć/poprawić.

    Pozdrawiam
    piterrr_
  • Computer Controls
  • #2
    KamilCWK
    Level 11  
    1. W obsłudze przerwania flaga powinna być czyszczona jako jedna z pierwszych.
    2. Należy sprawdzać od, którego rejestru porównyjącego wystąpiło przerwanie i na tej podstawie podejmować dalsze działanie.

    piterrr_ wrote:
    Zależnie od ustawień prescalera i wartosci MR0 timera niektóre wartości nie były prawidłowo wpisywane- ale najpierw zajmijmy się najprostszym przykładem przedstawionym w kodzie.

    Napisz jakie to wartości
  • Computer Controls
  • #3
    BlueDraco
    MCUs specialist
    Nie wykonuj operacji logicznych na rejestrach FIOSET i FIOCLR. Powinno być:

    LPC_GPIO3->FIOCLR3 = 1 << 1 | 1 << 2;

    Trzymasz włączony reset timera - nie wiem, czy w tym stanie reaguje on poprawnie na zapisz rejestrów.

    Znacznik przerwania należy kasować na początku obsługi, po wykryciu, że jest ustawiony.
  • #4
    piterrr_
    Level 11  
    Dziękuję za pomocne wskazówki. Pomogły, czyszczenie flagi na początku obsługi przerwań i tego się będę trzymał- czy dotyczy to obsługi wszystkich peryferiow? (np. PWM).
    Zmieniłem inicjalizacje timera, aby reset nie był w ten sposób trzymany włączony. A jeśli chodzi o wartości prescalera i timera tutaj tez problem się wyjaśnłl- źle sterowałem (wyłączałem) PWM, który był u mnie zależny (zmieniany) w przerwaniu timera.
  • #5
    KamilCWK
    Level 11  
    piterrr_ wrote:
    Dziękuję za pomocne wskazówki. Pomogły, czyszczenie flagi na początku obsługi przerwań i tego się będę trzymał- czy dotyczy to obsługi wszystkich peryferiow? (np. PWM).

    Tak dotyczy to wszystkich peruferjów, dodatkowo powinno się sprawdzać źródło przerwania w obsłudze przerwania bo przerwanie TIM0 może wywołać któryś z rejestrów porywnujących MRx