Atmel AVR, operacje na portach, czy dobrze rozumuję?

Witam,

Poniżej zamieszczam fragment programu w assemblerze dla mikrokontrolera Atmel AVR ATmega32. Byłbym wdzięczny za zapoznanie się z nim i moim komentarzem i odpowiedź, czy dobrze rozumuję.

int main(void) { 8e: cf e5 ldi r28, 0x5F ; 95 90: d4 e0 ldi r29, 0x04 ; 4 92: de bf out 0x3e, r29 ; 62 94: cd bf out 0x3d, r28 ; 61

PORTB = _BV(PB1); 96: 82 e0 ldi r24, 0x02 ; 2 98: 88 bb out 0x18, r24 ; 24

PORTB |= _BV(PB1); 9a: c1 9a sbi 0x18, 1 ; 24

sbi(PORTB, PB1); 9c: c1 9a sbi 0x18, 1 ; 24

*** PORTB |= _BV(PB1) jest tożsame z sbi(PORTB,PB1);

PORTB |= _BV(PB1) | _BV(PB2); 9e: 88 b3 in r24, 0x18 ; 24 a0: 86 60 ori r24, 0x06 ; 6 a2: 88 bb out 0x18, r24 ; 24

*** Jeżeli za pomocą PORTB |= ... chcemy ustawić więcej niż jeden bit, to najpierw pobierana jest "wartość" występująca na tym porcie, następnie wykonywana jest na tej wartości operacja alternatywy z maską określającą bity, które mają zostać ustawione, a następnie uzyskany wynik zapisywany jest do portu. Załóżmy, że w głównej pętli programu ustawiamy/zerujemy wyjścia na jakimś porcie za pomocą PORTB |= _BV(PB1) | _BV(PB2). W programie działa funkcja obsługi przerwania, która także operuje na PORTB. Zatem może pojawić się sytuacja, w której w programie głównym zostanie odczytana "wartość" na porcie (in r24, 0x18), następnie zacznie być wykonywana funkcja obsługi przerwania, która zmieni wartość na PORTB, po czym nastąpi powrót do programu głównego i wykonanie ori r24,0x06 out 0x18,r24 -- z tym że ori r24,0x06 zostanie wykonana na wartości portu, która była uprzednio (przed wejściem do funkcji obsługi przerwania). Stąd, może pojawić się pewne zamieszanie i program może działać niepoprawnie. Czy dobrze myślę?

Z góry dziękuję za pomoc. Robbo

Reply to
Robbo
Loading thread data ...

Bardzo dobrze. Możesz się napić piwa.

Reply to
Bogdan G

Tak.

Jak nie chcesz mieć problemu to przed odczytem stanu portu i zapisem zmienionej wartosci zablokuj na chwile przerwania.

Reply to
Zibias

Zibias pisze:

Albo dokonuj wyłącznie zmian w jednym miejscu, regularnie albo np pod wpływem flagi "zostały wprowadzone zmiany, trzeba uaktualnić porty". Wtedy obojętnie czy to przerwanie zleci zmiane, czy też inne miejsce w programie - nie będzie konfliktu.

Reply to
BartekK

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.