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

gdzie jest błąd, tablica->led

20 Kwi 2005 20:21 2220 7
  • Poziom 13  
    Witam
    Przesiadłem się z bascom na C i wymodziłem taki programik do sterowania wyświetlaczem led. W/g mnie wszystko jest w porządku, kompiluje się bez żadnych ostrzeżeń (avr-gcc), a symulator (AVR Studio 4) nie wystawia nic na portc alabo wystawia głupoty. Poniżej zamiszczam fragment kodu, może ktoś rzuci na to nowe światło.

    Code:

    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>

    #define FACTOR 0x6a
    #define KRESKA 0xb0
    #define BLANK  0xa0

    unsigned char pozycja=1;
    unsigned char led[2];

    // kody wyswietlacza 7-segmentowego
    unsigned char cyfry[12] =
    {
       0x20, 0xed, 0xd0, 0xc4, 0x8d, 0x86, 0x82, 0xec, 0x80, 0x84, 0xff, 0xdf
    };


    void port_init(void)
    {
       DDRA  = 0xe7;
       PORTA = 0x19;
       DDRC  = 0xff;
       PORTC = 0xff;
    }

    void timer_init(void)
    {
       TCCR0 = 0x00;
       TCNT0 = FACTOR;
       TCCR0 = 0x03;
    }

    void inicjalizacja(void)
    {
       cli();
       port_init();
       timer_init();
       MCUCR = 0x00;
       TIMSK = 0x02;
       sei();
    }

    SIGNAL (SIG_OVERFLOW0)
    {
       TCNT0 = FACTOR;
       PORTC = 0xff;
       PORTA &= ~(0x03);
       if (pozycja>2) pozycja=1;
       PORTA|=(pozycja);
       PORTC=(cyfry[led[pozycja]]);
       pozycja++;
    }


    int main(void)
    {
       led[1]=KRESKA;
       led[2]=KRESKA;
       inicjalizacja();
       while(1);
    }


    Grzesiek
  • Pomocny post
    Poziom 39  
    Błąd jest(są) tu:
    Code:

    jest ...
    unsigned char pozycja=1;
    unsigned char led[2];
    ... powinno być
    volatile unsigned char pozycja=1;
    volatile unsigned char led[2];

    dalej...
    Code:

    ...
    PORTC=(cyfry[led[pozycja]]); //index dla tablicy cyfry ma wartość "KRESKA"
                                                // tzn. 0xb0 , a tablica cyfry składa się tylko z 12 elementów.
    ...


    Piotrek
  • Poziom 13  
    Dzięki, jednak to nie to, dalej nie działa.
    Oto co wyczytałem o volatile:
    Cytat:

    Przy włączonej optymalizacji zmienne globalne, które chcemy zmieniać w obsłudze przerwań muszą koniecznie posiadać atrybut volatile. W przeciwnym razie kompilator zignoruje zmiany.

    "led" nie jest zmieniana w przerwaniu tylko będzie w petli głownej, a "pozycja" działa nawet bez volatile (tzn. na PORTA są wystawiane naprzemiennie bity PA0 i PA1). Natomiast PORTC jest cały czas w stanie wysokim, nie działa to przypisanie z tablicy.

    Grzesiek.
    PS. Z kreską to była literówka - powinno być 0x0b, zresztą podobnie jak z balnkiem 0x0a - dzięki za zwrócenie uwagi.[/quote]
  • Poziom 18  
    Witam.
    1/ Utworzyles tablice dwuelementowa led[2] wiec jesli chcesz uzywac elementu 1 i 2 musisz indeksowac ja jako 0 i 1. Nie ma elementu led[2] ! Stad pewnie biora sie te glupoty na porcie C. Zmien to w signal (sig_overflow0).
    2/ Nie wiem jak sterujesz zalaczaniem poszczegolnych cyfr (sprzetowo) ale podejrzewam ,ze za pomoca tranzystora pnp wiec wlaczasz go ustwiajac na wyjsciu portu A =0 a ty w twoim przerwaniu ustawiasz 1. Zaznaczam,ze powyzsze dotyczy jedynie tak opisanego przypadku.

    Co do definicji kreski to wypowiedzial sie juz kolega zumek. Ps. lepiej konwersji danej cyfry na kod 7seg dokonywac w programie glownym a nie w przerwaniu, bedziesz mogl wowczas wykorzystac wyswietlacz do pokazwyania innych znakow poza cyframi np. a , c itd.
    pozdrawiam.
  • Poziom 13  
    Dzieki
    ad1. pewnie jest tak jak mówisz, ale mimio wszystko dla indeksu 1 powinno coś wyświetlić, a nie wyświetla nic.
    ad2. części sprzętowej bym się nie czepiał, pod bascom działa, jest to wyswietlacz ze wspolną anoda, a steruje przez tranzystor pnp podając jedynke na PA0 lub PA1 a na portC wystawiam zero zaświecając wybrany segment.
    Z wyświetlaniem innych symboli niż cyfry też nie widze problemu, wytarczy zdefiniować nowy znak w tablicy cyfry[] w petli glownej przypisac go do led[0] i led[1]. W przerwaniu zrealizowany jest tylko multiplex.
    tylko jak zrobić by go z tej tablicy pobrać :(
    Code:
    PORTC=(cyfry[led[pozycja-1]]);           //tu doszukuje sie problemu

    Próbowałem podstawiać też bezpośrednio np. PORTC=cyfry[1]; i też nie idzie, nie przychodzi mi już nic do głowy.
    Grzesiek.
  • Poziom 18  
    Co do twojego hardwaru. Jesli masz tranzystory pnp to aby podac napiecie + na wspolna anode wyswietlacza , na jego baze ,musisz podac 0, a wiec pa0 lub pa1 = 0. A ty w twoim przerwaniu wpierw wlaczasz 2 tranzystory instrukcja : PORTA&=~(0x03) a następnie wylaczasz instrukcją PORTA |=pozycja. W ten sposob wyswietlacz jest zalaczony na czas kliku instrukcji.A to nie wsytarczy aby oko to zobaczylo :) Sproboj tak a bedzie dzialac :
    SIGNAL (SIG_OVERFLOW)
    {
    TCNT0=FACTOR;
    PORTA|=0x03; // wylaczmy wyswietlacze
    PORTC=led[pozycja]; // wystawiamy dana z buforu led[] na portc
    if (pozycja==1) // zalaczmy pa1
    {
    PORTA&=~_BV(PA1);
    pozycja=0;
    }
    else // lub pa0
    {
    PORTA&=~_BV(PA0);
    pozycja=1;
    }
    }
    a w main :

    led[0]=cyfry[KRESKA]; // KRESKA(0x0b) to nr pozycji w tablicy cyfry[] gdzie znajduja sie wzory znakow 7 seg. Po tym w led[0] bedzie 0xdf
    led[1]=cyfry[KRESKA];

    to wszytsko :)
  • Poziom 13  
    Tak jak pisałem, nie czepiajmy się peryferiów, bo skoro działa pod bascomem takie sterowanie to i pod C powinno.
    Problem polega na tym, że do PORTC nie ląduje zawartość pola tablicy o indeksie pozycja, zarówno w moim przykładzie jak i w Twoim. Swoje spostrzeżenia opieram na obserwacji symulacji pod AVR Studio. Nie wydaje mi się aby coś z nim było nie tak, podobnie jak z gcc. Może problem leży w deklaracji tablic, zmiennych? Dodałem volatile jak sugerowal Zumek, ale to nic nie pomogło. Ma ktoś jeszcze jakieś sugestie?

    Pozdrawiam, Grzesiek.

    -------------------------------------------------
    Dziękuje serdecznie wszystkim za okazaną pomoc, problem rozwiązany.
    Wystarczyło podać przed deklaracją tablicy const:
    Code:
    const unsigned char cyfry[12] =
    
    {
       0x20, 0xed, 0xd0, 0xc4, 0x8d, 0x86, 0x82, 0xec, 0x80, 0x84, 0xff, 0xdf
    };


    :)
  • Pomocny post
    Poziom 18  
    Jesli twoj sposob sterowania dziala to gratuluje. Byc moze odkryles jakas nowosc ;) A i zapewniam ,ze w moim przykladzie w tablicy led znajduje sie kod twojej kreski ...