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

Jak ustawić/wyzerować bity CS00 i CS01 w TCCR0B mikrokontrolera ATtiny2313?

Sparrowhawk 04 Lis 2015 11:18 774 7
  • #1 15121563
    Sparrowhawk
    Poziom 22  
    W jednym z niedawnych wątków przy okazji takiego zapisu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    padło następujące stwierdzenie:
    Cytat:
    A w ogóle operacje |= na rejestrach sterujących są bez sensu
    W takim razie chciałem się dowiedzieć jak poprawnie ustawić/wyzerować bity CS00 & CS01 w rejestrze TCCR0B mikrokontrolera ATtiny2313?
  • #2 15121613
    yokoon
    Poziom 29  
    Sparrowhawk napisał:
    W jednym z niedawnych wątków przy okazji takiego zapisu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    padło następujące stwierdzenie:
    Cytat:
    A w ogóle operacje |= na rejestrach sterujących są bez sensu
    W takim razie chciałem się dowiedzieć jak poprawnie ustawić/wyzerować bity CS00 & CS01 w rejestrze TCCR0B mikrokontrolera ATtiny2313?


    Witam.
    Są to bity preskalera uważam, że są poprawnie ustawione w/w przykładzie.
    Ustawione w ten sposób bity to podział przez 64.
  • Pomocny post
    #3 15121633
    szczywronek
    Poziom 28  
    Chodzi o to, że operacja |= generuje (najczęściej) sekwencję R-M-W (read - modify - write). Czyli rejestr konfiguracyjny jest odczytywany do rejestru ogólnego procesora, na tym rejestrze jest dokonywana operacja arytmetyczno/logiczna (OR) a na koniec wynik jest zapisywany nazad w rejestrze konfiguracyjnym.

    Przykład:
    Kod: AVR assembler
    Zaloguj się, aby zobaczyć kod

    Operacja PORTB |= 1<<PB1 | 1<<PB6; generuje trzy rozkazy procesora:
    - odczyt zawartości rejestru PORTB (adres 0x18) do r24
    - sumę bitową wartości r24 i stałej 0x42 (1<<PB1 | 1<<PB6)
    - zapisanie wartości z r24 do rejestru PORTB (adres 0x18)

    Wersja bez sumy bitowej:
    Kod: AVR assembler
    Zaloguj się, aby zobaczyć kod


    Do rejestrów konfiguracyjnych wykonuje się najczęściej jeden zapis - przy konfiguracji danego peryferiala. W związku z tym nie ma potrzeby wykonywania operacji sumy bitowej i można wykorzystać zwykłe przypisanie. Kod jest wtedy krótszy i szybszy (... i kolega BlueDraco się nie czepia :D). Suma bitowa pozwala zachować niezmienianą zawartość rejestru, ale jeśli konfigurujemy jakiś układ to najczęściej rejestr konfiguracyjny ma (przed konfiguracją) wartość 0 - stosowanie na nim sumy bitowej jest bez sensu. A nawet jeśli nie ma wartości zerowej, to zazwyczaj wiemy jaką wartość rejestr ma mieć po konfiguracji układu - czyli możemy wykorzystać zwykłe przypisanie zamiast sumy bitowej.
  • #4 15121803
    tmf
    VIP Zasłużony dla elektroda
    Do tego co napisał kol. @szczywronek dodam tylko, że suma bitowa może być niebezpieczna jeśli maskowane pole nie ma wartości zero. Dla pewności trzebaby więc przedtem wykonać dodatkową operację zerowania bitów. Inaczej czasami uzyskamy sieczkę. No i analiza efektu końcowego takiego zapisu jest utrudniona.
  • Pomocny post
    #6 15121835
    szczywronek
    Poziom 28  
    Dodam jeszcze jedną cegiełkę: AVRy mają specjalne rozkazy do atomowych operacji na bitach rejestrów układów peryferyjnych. Umożliwiają one ustawienie i skasowanie pojedynczego bitu:
    - sbi - set bit
    - cbi - clear bit

    Jeśli więc kompilator jest na tyle zdolny, że potrafi z nich korzystać to operacje ustawiające (lub kasujące) pojedyncze bity rejestrów wykonywane są właśnie za ich pomocą. GCC (z tego co wiem) kiedyś taki mądry nie był i trzeba było jawnie stosować wspomniane rozkazy (poprzez makra SBI i CBI). Od którejś tam wersji działa to "automatycznie". Przykład podsumowujący (trzy razy ustawiane są bity PB0 i PB1):
    Kod: AVR assembler
    Zaloguj się, aby zobaczyć kod

    Opcja 1 - suma bitowa: to już było w poprzednim poście (odczyt, modyfikacja, zapis)
    Opcja 2 - przypisanie: tylko dwie operacje (wczytanie stałej do r24, zapisanie w PORTB). Przy czym jeśli program będzie większy to może się okazać że pierwsza operacja nie będzie potrzebna, bo potrzebna wartość (tu akurat 3) już będzie w którymś z rejestrów procesora i kompilator to wykorzysta.
    Opcja 3 - operacje sbi: dwie operacje (każda ustawia jeden bit)

    @ASMnauka_ - out zadziała ze stałą?
  • #7 15121838
    tadzik85
    Poziom 38  
    Sparrowhawk napisał:
    W jednym z niedawnych wątków przy okazji takiego zapisu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    padło następujące stwierdzenie:
    Cytat:
    A w ogóle operacje |= na rejestrach sterujących są bez sensu
    W takim razie chciałem się dowiedzieć jak poprawnie ustawić/wyzerować bity CS00 & CS01 w rejestrze TCCR0B mikrokontrolera ATtiny2313?



    Pola bitowe które chcesz edytować wcześniej należy wyzerować.
    W przypadku 1-ej konfiguracji rejestru warto zrezygnować z ORa na rzecz zwykłego przypisania.

    AVR jest specyficzny w przypadku edycji 1 bitu w rejestru SFR (tylko to pewnego adresu) taki or zostanie zastąpiony instrukcją SBI (CBI);
REKLAMA