- posted
18 years ago
avr-gcc i sbi, cbi
- Vote on answer
- posted
18 years ago
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
- Vote on answer
- posted
18 years ago
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.
- Vote on answer
- posted
18 years ago
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
- Vote on answer
- posted
18 years ago
A jaki poziom optymalizacji masz ustawiony ? Możesz wkleić jakiś kawałek kodu, w którym ten efekt występuje ?
- Vote on answer
- posted
18 years ago
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
- Vote on answer
- posted
18 years ago
Pozjadałeś tyldy mistrzu, więc nic dziwnego.
- Vote on answer
- posted
18 years ago
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
- Vote on answer
- posted
18 years ago
Podaj dokładnie linijkę źródła i komunikat kompilatora. U mnie instrukcja typu PORTB &= ~(1<<7); działa bez problemu.
- Vote on answer
- posted
18 years ago
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.
- Vote on answer
- posted
18 years ago
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
- Vote on answer
- posted
18 years ago
Hm, wersja 3.4.3 tak nie robi - wstawia cbi
Moze opcje masz jakos specyficznie ustawione - np domyslny jest "signed char" ?
J.