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.

attiny2313, problem z timerem 16

helios 21 Wrz 2006 00:54 1094 9
  • #1 21 Wrz 2006 00:54
    helios
    Poziom 12  

    Od samego początku mam problem z tym timerem. Napisałem program w C, który jest specjalnie prymitywny, ale jest w tym przypadku pewien sens, żeby to wyglądało tak jak tutaj:


    #include <inttypes.h>
    #include <avr/io.h>

    int main()
    {
    TCCR1A=0;
    TCCR1B=_BV(CS12) | _BV(CS10); //przez 1024
    TCCR1C=0;
    DDRB=1;

    while(1)
    {

    TCNT1 = 0;
    while(TCNT1L < 110); // ***********
    PORTB = 1 - PORTB;
    }

    return 0;
    }


    Program powoduje że dioda sobie miga, (leży na PB0).
    Problem jest w linii oznaczonej: // ***********
    Kiedy ta linia jest taka jak tutaj to dioda miga, częstotliwość kilka Hz czyli w miarę szybko ale widać to wyraźnie [dokładnie można obliczyć, ale to nie ma większego znaczenia]. Czyli teoretycznie wpisanie
    while(TCNT1H < 10);
    powinno spowodować że dioda będzie migać wolniej? tak?
    No i tu moje pytanie, skoro "tak" to dlaczego jest NIE :P W symulatorze wychodzi że powinna migać a w praktyce cichosza, nic się nie dzieje.
    Żeby było śmieszniej to wpisanie
    while(TCNT1 < 10*256);
    powoduje że dioda miga wolniej, czyli jest ok.

    W takim razie dlaczego nie działa kiedy porównuje TCNT1H? Już kilka razy tak podchodziłem do tematu żeby to sprawdzić, ale się spieszyłem i sobie odpuszczałem, jednak tym razem w końcu muszę ustalić o co chodzi bo okazuje się że odczyt TCNT1H jest niemożliwy, bo w innych działaniach też go nie można wykorzystać, podczas gdy operacje na TCNT1 i TCNT1L działają normalnie. TCNT1H działa jedynie na symulacji, a praktyce nie.

    Co o tym sądzicie? Robie coś źle?

    PS. procek ATTINY2313, AVR Studio 4
    PS2. próbowałe też w ASM i ten sam efekt, TCNT1L chodzi a TCNT1H nie. W takim razie o co biega?
    Sprawdziłem nawet czy stałe są prawidłowe i wychodzi że tak, bo
    TCNT1L = 0x2c
    TCNT1H = 0x2d


    Pozdrawiam i pomóżcie :!::!::!: :)

    0 9
  • #2 21 Wrz 2006 07:51
    Ch.M.
    Poziom 27  

    hmm napisz w jakim trybie chodzic ma timer1

    0
  • #3 21 Wrz 2006 14:57
    helios
    Poziom 12  

    Całkowity standard, czyli kopiując z noty:

    1.Normal port operation, OC1A/OC1B
    disconnected.

    2. Timer/Counter Mode of Operation: Normal

    3. clkI/O/1024 (From prescaler)

    To chyba wszystko, on ma po prostu liczyć sobie w górę a w pęli jest porownywanie [najprymitywniejsze rozwiązanie z pominięcem rozwiązań gotowych w timer1 i o takie rozwiązanie mi chodzi, bo nie mogę inaczej, bo TCNT1H normalnie chciałbym użyć do obliczeń itp, a tak nie mogę bo już kilka razy próbowałem i nie chodziło za każdym razem. Na TCNT1L mogę wykonywać operację i działa, a na TCNT1H nic nie działa i operacje też nie].

    Sam timer musiałem dobrze skonfigurować bo opcja
    while(TCNT1<5000);

    działa zupelnie normalnie, normalnie też działa
    while(TCNT1L<100);

    ale NIE DZIAŁA
    while(TCNT1H<30);

    Królestwo dla kogoś kto mi napisze kod, który będzie używał TCNT1H i będzie działał, a efekt będzie widoczny i kod będzie najprostrzy.

    0
  • #4 21 Wrz 2006 18:49
    GienekS
    Poziom 32  

    Przyczyna jest banalna. To nie moze dzialac bo takie jest zalozenie producenta. A wystarczy napisac

    Code:
    while(TCNT1<100); 
    Nie nie to nie pomyjka ten rejest jest z zalozenia 16 bitowy i porownuje caly licznik T1 a nie tylko jeden bajt.

    0
  • #5 21 Wrz 2006 21:19
    helios
    Poziom 12  

    przyczyna nie jest jednak taka banalna. Skoro tylko TCNT1 to dlaczego działa while(TCNT1L<100)? Wydaje mi się że to trochę dziwne, nieprawdaż? i jednocześnie przeczy w 99% tej teorii :). Poza tym w assemblerze do wyzerowania w nocie katalogowej jest program gdzie najpierw załadowane zostaje zero do TCNT1L a potem TCNT1H (lub odwrotnie)... więc coś tu musi być nie tak, że nie ma dostępu do TCNT1H...
    GienekS, gdzie znalazłeś informacje na ten temat? czy to tylko wniosek który wyciągnąłeś sam?

    Dodano po 1 [minuty]:

    a kod w asemblerze też nie działa dla TCNT1H i działa dla TCNT1L... no i w dodatku symulacja przechodzi dla obu, a praktyka tylko dla jednego [zarówno w C i assemblerze jest tak samo... w C przechodzi dodatkowo TCNT1]

    0
  • #6 21 Wrz 2006 22:35
    GienekS
    Poziom 32  

    helios napisał:
    GienekS, gdzie znalazłeś informacje na ten temat? czy to tylko wniosek który wyciągnąłeś sam?
    oczywiście że w nocie katalogowej producenta. Z resztą w to nie ma znaczenia w jakim języku programujesz, ta zależność obowiązuje zawsze. Jest to specjalnie pomyślane aby można przeczytać stan licznika 16 bitowego w "locie" bez jego zatrzymywania.

    0
  • #7 21 Wrz 2006 23:00
    helios
    Poziom 12  

    Dobra, weź mi to wyjaśnij :), bo mi jakoś nic do głowy nie przychodzi. Jak to się odbywa, jakaś prosta teoria w j. polskim :)

    0
  • Pomocny post
    #8 21 Wrz 2006 23:44
    GienekS
    Poziom 32  

    Generalnie we wszystkich nowych procesorach Atmela, do nich tez nalezy ten procesor, rejestry 16 bitowe maja buforowanie rejestru H To znaczy, aby przeczytac rejestr TCNTnH nalezy najpierw przeczytac rejestr TCNTnL co powoduje jednoczesne zapisaniem rejestru TCNTnH w niewidocznym rejestrze TEMP dla programisty. Dopiero kolejna operacja odczytu rejestru TCNTnH powoduje podenie tej wartosci z rejestru TEMP. Co jak wczesniej pisalem pozwala odczytanie wszystkich 16-tu bitow przeczytania w "locie". Ot i cala filozofia Atmela.
    Czy jest to zrozumiale :?:

    0
  • #9 22 Wrz 2006 13:54
    Ch.M.
    Poziom 27  

    Tak jak kolega Gieniek napisał: najpierw musisz odczytac "dolną" część rejestru po to by uzyskać dostęp do górnej. Instrukcje bascomowe potrafia odczytać cały rejestr lub dolną połowe, ale tylko górnej nie. Dla porównania jeśli wykonujesz jakiekolwiek operacje na liczbie większej niz 8bitowa, zawsze zaczynasz od najmniej znaczących bitów. Takie są uroki 8bitówców, osobiście omijam liczniki 16bitowe jeśli to możliwe :)

    0
  • #10 22 Wrz 2006 16:54
    helios
    Poziom 12  

    No to teraz dopiero jasne. Gienek nie mogleś od razu tak napisać tylko taką atmosferę tajemniczości wprowadziłeś :P

    Pozdrawiam. Dzięki.

    0