Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Przerwania ATmega32 w srodowisku IAR

pawel_5 09 Lis 2008 13:26 1254 3
  • #1 09 Lis 2008 13:26
    pawel_5
    Poziom 13  

    witam
    To moje pierwsze zetknięcia z AVR`ami stąd pytanie dla wielu może wydać się banalne lecz raczej nikt mi nie zarzuci, że nie szukalem ani nie czytalem. Przeszukałem całe forum ale o o środowiesku IAR jest bardzo mało postów. Wszystko to co wyczytałem pochodzi z user manulala Iar`a.

    Problem polega na tym, że po włączeniu licznika/ timera 1 oraz funkcji capture w T1 wszystko działa, tzn. licznik zlicza w góre po czym sie zeruje (sprwadziłem na porcie stany rejestrow licznika) oraz funkcja capture rowniez działa. Nie działa tutaj podprogram ktory wpisałem w przypadku przerwania od T1 - czyli przy przepelnieniu T1. Użyłem dyrektywy jak w user manulau i nic. Niestety nie umiem jeszcze symulacji i nie wiem jak ogolnie to sprawdzić.

    Oto fragment programu:


    Code:
    void start_przerwania()
    
      {
     // GICR_Bit0 = 0; - tutaj kombinowalem z tymi bitami ale na marne, zadnego efektu
     // GICR_Bit1 = 0;
     
      SREG_Bit7 = 1; //globalne odblokowanie przerwan
      TIMSK_Bit5 = 1; //odblokowanie Timera1 funkcji capture
      TCCR1B = 0x02;  //licznik wlaczony ,preskaler 8
      TCCR1A = 0x00; //tryb normalny
      }



    #pragma vector=0x12
    __interrupt void przepelnienie_T1(void)
    {
     
     PORTA = 0x55;  // PORTA wczesniej ustawiony jako wyjscie
       
    }



    Czy tu jest w programie jakis blad czy problemu szukac gdzie indziej?

    0 3
  • #2 09 Lis 2008 23:11
    pawel_5
    Poziom 13  

    Dodam jeszcze że kiedy wywalam na port stan rejestru licznika 1 TCNT1H to jest caly czas 0, a jak patrze na TCNT1L to liczy od 0 do 255, tak jakby licznik byl 8 bitowy.
    Nie wiem czemu, juz brakuje mi pomysłów. Aha i jeszcze jedną rzecz zauważyłem. Wektory dla obsługi przerwań są parzyste i tak dla ATmegi32 dla przerwania z przepełnienia T1 to jest 0x12 a funkcja przerwania od porownywania jest 0x10 i kiedy próbuję zrobić drugie przerwanie włąśnie w tym obok to wywala mi bład że sie nakładają adresy...dziwne:/

    0
  • Pomocny post
    #3 10 Lis 2008 23:44
    JarekC
    Poziom 28  

    Witam,

    Popełniłeś kilka błędów:
    - aby odblokować przerwania od przepełnienia timera 1 trzeba ustawić bit 2 a nie 5 w rejsestrze TIMSK
    - wektor przerwania od przepełniania timera 1 to nie 0x12 a 0x24

    Dobrze jest przy pisaniu w C korzystać z funkcji dostarczanych wraz z kompilatorem "intrinsic function"
    takich jak __interrupt_enable, __interrupt_disable, __sleep itd.
    Dzięki temu nie trzeba pamiętać dokładnie jaki bit w rejestrze odpowiada za zał./wył. określonej funkcjonalności.

    Dobrze jest też korzystać z predefiniowanych nazw bitów w rejestrach, zamiast z ich liczbowej reprezentacji.
    Bardzo to ułatwia zrozumienie kodu jak i wyłapywanie błędów.
    W Twoim przykładzie aby odblokować przerwanie od timera1 należy ustawić bit TOIE1 w rejestrze TIMSK i nie musimy pamiętać że jest to bit 2.

    Aby kompilator IAR rozpoznawał nazwy bitów należy zaznaczyć opcję "Enable bit definitions in I/O include files"
    w zakładce Project->Options->General_Options->System

    Podobnie z wektorami przerwań. Wszystkie wektory są zdefiniowane
    w pliku np: "iom32.h" dla procesora ATMEGA32.

    Poniżej przedstawiam poprawiony kod.

    Pozdrawiam
    JarekC

    Code:


    #include "iom32.h"
    #include "intrinsics.h"

    void init_timer (void);

    void main( void )
    {
      DDRA = 0xFF;       // port A jako wyjście
      init_timer();      // zainicjowanie timera
     
      while (1);
    }


    void init_timer(void)
      {
      TCCR1B = (1<<CS01);     //licznik wlaczony ,preskaler 8
      TCCR1A = 0x00;          //tryb normalny
      TIMSK  = (1<<TOIE1);   // odblokowanie przerwania od "overflow" dla timera 1
      __enable_interrupt();   // globalne odblokowanie przerwan
      }

    #pragma vector=TIMER1_OVF_vect
    __interrupt void przepelnienie_T1(void)
    {
      PORTA = 0x55;  // PORTA wczesniej ustawiony jako wyjscie
    }

    0
  • #4 11 Lis 2008 00:00
    pawel_5
    Poziom 13  

    Działa!!!!
    Jarek, jesteś wielki!!
    Bardzo dziękuję!!:):):)

    Dziękuję nie tylko za udzielenie wskazówek ale również za to w jaki sposób napisałeś. Mam nadzieję, że na forum bedziesz spotykał samych takich ludzi jak Ty sam, którzy nie chodzą z uniesionymi głowami lecz poprostu dzielą się swoją wiedzą, chcą pomóc.

    Wszystko to co napisałeś działa i masz u mnie 5+:)

    Informacje jak złoto dla potomnych!

    0