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

Atmega16 i AVR Studio - problem z multipleksowaniem i funkcją inkrementacji

lukasb9 17 Paź 2006 01:41 1273 2
REKLAMA
  • #1 3124549
    lukasb9
    Poziom 28  
    Posty: 1421
    Pomógł: 56
    Ocena: 69
    Witam prosze mi powiedziec co źle robie... bo albo trace wiare w cokolwiek...
    napisalem program, zegarka, nieskonczony, tak czy inaczej w chwili obecnej odmierza i pokazuje czas, na timerze 0 multipleksowanie, na timerze 2 w trybie asynchronicznym odmierzana jest jedna sekunda, kwarc zewnetrzny zegarkowy, schody zaczynaja sie gdy w petli głównej, patrz nizej, wpisanie wywołania funkcji (tu akurat nazywa sie to umnie inkrementacja) zupelnie niszczy mi multipleksowanie, po wyswietlaczach biega puste miejsce, cyferki lataja jak głupie, a co najsmieszniejsze wywoływana funcka jest pusta... , chcialem doniej wrzucic sprawdzanie warunków sekund minut itd, to co jest najnizej w petli, ale okazało sie ze ze sa problemy, po usunieciu wszystkiego z niej problemy dalej sa, znikaja kiedy usune wywołanie tej funkcjii, deklarowana jest jako void inkrementacja (void), ja dopiero rozpoczynam przygode z C pomózcie bo siedze nad tym od 18 a jest juz blisko 2 i bez efektów....



    while(1) //pentla glowna programu
    {
    for (i=0;i<7;i++)
    wyswietl[i]=tablicaczasu[i];


    inkrementacja(); <- TU JEST PROBLEM


    if (tablicaczasu[5] == 10)
    {tablicaczasu[5]=0;
    tablicaczasu[4]++;}
    if (tablicaczasu[4] == 6)
    {tablicaczasu[4] = 0;
    tablicaczasu[3]++;}
    if (tablicaczasu[3] == 10)
    {tablicaczasu[3] =0;
    tablicaczasu[2]++;}
    if (tablicaczasu[2] ==6)
    {tablicaczasu[1]++;
    tablicaczasu[2]=0;}
    if (tablicaczasu[1] ==10)
    {tablicaczasu[1] = 0;
    tablicaczasu[0]++;}
    if ((tablicaczasu[0] ==2)&&(tablicaczasu[1]==4))
    {tablicaczasu[0] = 0;
    tablicaczasu[1]=0;}
    }


    }




    dodaje w załaczniku całosc kodu....
    Załączniki:
    • nixie.c (4.11 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • REKLAMA
  • Pomocny post
    #2 3125794
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    Drogi kolego , popełniłeś szkolny błąd :D
    W procedurze obsługi przerwania Timer0 masz ...
    
    SIGNAL(SIG_OVERFLOW0)				//obsługa multipleksowania wyswietlaczy
    {
    //extern unsigned char wyswietl[7];
    unsigned char licznik;//<-- ********** błąd !!!!!!!!!!!
    

    ... zmienną licznik , tyle że jest to zmienna lokalna , czyli istnieje w pamięci tylko w czasie wykonywania przez proca przerwania od TIMER0. Dopuki nie wywoływałeś z main żadnej procedury/funkcji , doputy wskaźnik stosu był niejako "nieruchomy" i przy przerwaniu od T0 alokowanie pamięci na zmienną licznik , trafiało zawsze na tę samo komórkę , ale jak tylko dodałeś skok do jakiejkolwiek funkcji , to wtedy procek odkłada na stos adres powrotu , jednocześnie zamazując niejako wartość w komórce gdzie była zmienna licznik.Jeśli przerwanie "trafiło" w czasie wykonywania tej funkcji , to ... już całkowity klops , bo zostanie użyta inna komórka pamięci na zmienną licznik.Trochę to zagmatwane , ale tyle na szybko mogłem wyjaśnić(?).
    Wyjścia są takie:
    
    SIGNAL(SIG_OVERFLOW0)            //obsługa multipleksowania wyswietlaczy
    {
    //extern unsigned char wyswietl[7];
    static unsigned char licznik=0; // <- ******* OK *****
    

    lub licznik jako zmienna globalna
    
    volatile unsigned char licznik=0;
    

    Mniemam , że to rozwiąze Twój problem ;)

    Piotrek
  • #3 3126470
    lukasb9
    Poziom 28  
    Posty: 1421
    Pomógł: 56
    Ocena: 69
    Witam wyjasniło sie conieco, dzieki wielkie bo juz wariowałem . moze sie porywam z motyka na słonce jak widac błedy sa jak sam napisałes "szkolne" troche wstyd.... problem pojawia sie jeszcze przy odczycie eeproma, odczyt ten jest przeprowadzany tylko raz po właczeniu zasilania, jak zauwazyłes nieaktywne sa linijki zapisywania do tablic wartosci eeproma, a to dlatego ze uaktywnienie którejkolwiek znów robi mi cyrk na wyswietlaczu, cztery pierwsze nie swieca, pewnie znów cos zadeklarowałem lokalnie, pomysle nad tym tymczasem pomagacz dla Ciebie, szkoda tylko ze sam nie wpadłem gdzie jest burak



    void odczyteeproma()
    {
    for (i=1;i<15;i++)
    {

    do //petla nieskonczona
    {} //czeka az dostane zezwolenie na odczyt
    while(bit_is_set(EECR,EEWE)); //eeproma


    EEAR = i;
    EECR |= 0b00000001;
    //if(i<5)
    //budzik_1[i]=EEDR;
    //if((i>5)&&(i<10))
    //budzik_2[i]=EEDR;
    //if(i>9)
    //budzik_3[i]=EEDR;
    }}


    z tym eepromem to juz nie wazne.... niewiem o czym ja mysle ale zapisywałem do tablicy 5elementowej 15 elementów... żałosny jestem wiem :)
REKLAMA