avr-gcc i sbi, cbi

Loading thread data ...

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

Reply to
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.

Reply to
Adam Dybkowski

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

Reply to
Grzegorz Kurczyk

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

Reply to
Zbych

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

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

// Program główny int main(void) { PORTB&=(1<<7); PORTB&=(1<<6); PORTB&=(1<<5); PORTB&=(1<<4); PORTB&=(1<<3); PORTB&=(1<<2); PORTB&=(1<<1); PORTB&=(1<<0); cbi(PORTB,7); cbi(PORTB,6); cbi(PORTB,5); cbi(PORTB,4); cbi(PORTB,3); cbi(PORTB,2); cbi(PORTB,1); cbi(PORTB,0); PORTB|=(1<<7); PORTB|=(1<<6); PORTB|=(1<<5); PORTB|=(1<<4); PORTB|=(1<<3); PORTB|=(1<<2); PORTB|=(1<<1); PORTB|=(1<<0); sbi(PORTB,7); sbi(PORTB,6); sbi(PORTB,5); sbi(PORTB,4); sbi(PORTB,3); sbi(PORTB,2); sbi(PORTB,1); sbi(PORTB,0); return(0); } .. oto co otrzymałem ;-) .. int main(void) { 5c: cf e5 ldi r28, 0x5F ; 95 5e: d4 e0 ldi r29, 0x04 ; 4 60: de bf out 0x3e, r29 ; 62 62: cd bf out 0x3d, r28 ; 61 PORTB&=(1<<7); 64: 88 b3 in r24, 0x18 ; 24 66: 80 78 andi r24, 0x80 ; 128 68: 88 bb out 0x18, r24 ; 24 PORTB&=(1<<6); 6a: 88 b3 in r24, 0x18 ; 24 6c: 80 74 andi r24, 0x40 ; 64 6e: 88 bb out 0x18, r24 ; 24 PORTB&=(1<<5); 70: 88 b3 in r24, 0x18 ; 24 72: 80 72 andi r24, 0x20 ; 32 74: 88 bb out 0x18, r24 ; 24 PORTB&=(1<<4); 76: 88 b3 in r24, 0x18 ; 24 78: 80 71 andi r24, 0x10 ; 16 7a: 88 bb out 0x18, r24 ; 24 PORTB&=(1<<3); 7c: 88 b3 in r24, 0x18 ; 24 7e: 88 70 andi r24, 0x08 ; 8 80: 88 bb out 0x18, r24 ; 24 PORTB&=(1<<2); 82: 88 b3 in r24, 0x18 ; 24 84: 84 70 andi r24, 0x04 ; 4 86: 88 bb out 0x18, r24 ; 24 PORTB&=(1<<1); 88: 88 b3 in r24, 0x18 ; 24 8a: 82 70 andi r24, 0x02 ; 2 8c: 88 bb out 0x18, r24 ; 24 PORTB&=(1<<0); 8e: 88 b3 in r24, 0x18 ; 24 90: 81 70 andi r24, 0x01 ; 1 92: 88 bb out 0x18, r24 ; 24 cbi(PORTB,7); 94: c7 98 cbi 0x18, 7 ; 24 cbi(PORTB,6); 96: c6 98 cbi 0x18, 6 ; 24 cbi(PORTB,5); 98: c5 98 cbi 0x18, 5 ; 24 cbi(PORTB,4); 9a: c4 98 cbi 0x18, 4 ; 24 cbi(PORTB,3); 9c: c3 98 cbi 0x18, 3 ; 24 cbi(PORTB,2); 9e: c2 98 cbi 0x18, 2 ; 24 cbi(PORTB,1); a0: c1 98 cbi 0x18, 1 ; 24 cbi(PORTB,0); a2: c0 98 cbi 0x18, 0 ; 24 PORTB|=(1<<7); a4: c7 9a sbi 0x18, 7 ; 24 PORTB|=(1<<6); a6: c6 9a sbi 0x18, 6 ; 24 PORTB|=(1<<5); a8: c5 9a sbi 0x18, 5 ; 24 PORTB|=(1<<4); aa: c4 9a sbi 0x18, 4 ; 24 PORTB|=(1<<3); ac: c3 9a sbi 0x18, 3 ; 24 PORTB|=(1<<2); ae: c2 9a sbi 0x18, 2 ; 24 PORTB|=(1<<1); b0: c1 9a sbi 0x18, 1 ; 24 PORTB|=(1<<0); b2: c0 9a sbi 0x18, 0 ; 24 sbi(PORTB,7); b4: c7 9a sbi 0x18, 7 ; 24 sbi(PORTB,6); b6: c6 9a sbi 0x18, 6 ; 24 sbi(PORTB,5); b8: c5 9a sbi 0x18, 5 ; 24 sbi(PORTB,4); ba: c4 9a sbi 0x18, 4 ; 24 sbi(PORTB,3); bc: c3 9a sbi 0x18, 3 ; 24 sbi(PORTB,2); be: c2 9a sbi 0x18, 2 ; 24 sbi(PORTB,1); c0: c1 9a sbi 0x18, 1 ; 24 sbi(PORTB,0); c2: c0 9a sbi 0x18, 0 ; 24 return(0); } c4: 80 e0 ldi r24, 0x00 ; 0 c6: 90 e0 ldi r25, 0x00 ; 0 c8: 00 c0 rjmp .+0 ; 0xca

000000ca <_exit>: ca: ff cf rjmp .-2 ; 0xca ... Tylko bez optymalizacji było "LDS..ORI/ANDI...STS"

Piotrek

Reply to
Piotrek Sz.

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

Reply to
Zbych

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

Reply to
Piotrek Sz.

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

Reply to
Adam Dybkowski

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.

Reply to
Zbych

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

Reply to
Piotrek Sz.

Hm, wersja 3.4.3 tak nie robi - wstawia cbi

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

J.

Reply to
J.F.

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.