avr-gcc i sbi, cbi

Aug 02, 2005 11 Replies

Witam.



Co siê sta³o z funkcjami sbi i cbi w najnowszym avr-gcc? Czy jedyn± mo¿liwo¶ci± zmiany jakiego¶ bitu jest u¿ycie tego typu zapisów? : PORTA &= ~(1 << numerbitu); //wyzerowanie bitu PORTA |= 1 << numerbitu; //ustawienie bitu



Dziêki za pomoc Pozdrawiam Pawe³r



Użytkownik Pawełr napisał:

Wystarczy zrobić sobie makrodefinicje:

#define cbi(sfr, b) (sfr &= ~(1<<b)) #define sbi(sfr, b) (sfr |= (1<<b))

i już masz po staremu :-)

Pozdrawiam Grzegorz Kurczyk

Znikły, bo to nie były funkcje tylko makra, do tego już od dawna przeznaczone do usunięcia z biblioteki.

To jest działanie ze wszech miar zalecane i skuteczne nawet gdy w przyszłości przesiądziesz się na inny procesor i inny kompilator. Lepiej nabrać takich przyzwyczajeń niż używać w nowych programach makr cbi, sbi, które już tu proponował Grzegorz.

Uuuuupsss... Właśnie zauważyłem, że WinAVR-20050214 ma drobną gafę. Oto co przetłumaczył:

PORTB &= ~(1<<7); 784: 88 b3 in r24, 0x18 ; 24 786: 81 23 and r24, r17 788: 88 bb out 0x18, r24 ; 24

i jest trochę śmiesznie bo linijkę dalej jest dobrze:

PORTB &= ~(1<<6); 78a: c6 98 cbi 0x18, 6 ; 24

W takim razie zrezygnowałem z "dobrych" przyzwyczajeń i naskrobałem makra asm:

#define sbi(port, bit) \ __asm__ __volatile__ ( \ "sbi %0, %1" "\n\t" \ : \ : "I" (_SFR_IO_ADDR(port)), \ "I" (bit) \ )

#define cbi(port, bit) \ __asm__ __volatile__ ( \ "cbi %0, %1" "\n\t" \ : \ : "I" (_SFR_IO_ADDR(port)), \ "I" (bit) \ )

i to działa bez pudła :-)

Pozdrawiam Grzegorz Kurczyk

A jaki poziom optymalizacji masz ustawiony ? Możesz wkleić jakiś kawałek kodu, w którym ten efekt występuje ?

Ja przeprowadziłem mały eksperyment i ...

#define sbi(a,b) a|=(1<: ca: ff cf rjmp .-2 ; 0xca ... Tylko bez optymalizacji było "LDS..ORI/ANDI...STS"

Piotrek

Pozjadałeś tyldy mistrzu, więc nic dziwnego.

Zbych snipped-for-privacy@onet.pl napisał(a): ..

Fakt :( Po "ugotowaniu" nowych tyld , kompilator "nie potrafi" wykonać CBI na bitach nr.7 Ciekawe ;-)

Pozdrawiam Piotrek

Podaj dokładnie linijkę źródła i komunikat kompilatora. U mnie instrukcja typu PORTB &= ~(1<<7); działa bez problemu.

Problem jest związany z ustawieniami kompilatora, a dokładniej z promocją do inta (16b). Dodanie opcji -mint8 likwiduje problem. Nie zauważyłem wpływu opcji -funsigned-char i -funsigned-bitfields no to zachowanie. Dokumentacja wspomina coś o możliwych problemach z biblioteką libc przy stosowaniu -mint8, ale ja nic takiego nie zauważyłem.

Adam Dybkowski snipped-for-privacy@amwaw.edu.pl> napisał(a):

Źle się wyraziłem.Nie chodzi o błąd , a efekt kompilacji różny dla bitu nr.7 i pozostałych 6 - 0 ...

PORTB&=~(1<<7); 96: 8f e7 ldi r24, 0x7F ; 127 98: 98 b3 in r25, 0x18 ; 24 9a: 98 23 and r25, r24 9c: 98 bb out 0x18, r25 ; 24 PORTB&=~(1<<6); 9e: c6 98 cbi 0x18, 6 ; 24 PORTB&=~(1<<5); a0: c5 98 cbi 0x18, 5 ; 24 .. jak to opisał wcześniej Grzegorz.

Piotrek

Hm, wersja 3.4.3 tak nie robi - wstawia cbi

Moze opcje masz jakos specyficznie ustawione - np domyslny jest "signed char" ?

J.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required