Hallo ich suche die Vereinfachung für folgende 2 Befehlzeilen zu einem Befehl: ... PORTA &= ~(1 << PINA1); PORTA |= MP.mp.MPTA & (1 << PIN1); ... Ich möchte also in Abhängigkeit von bit1 in der uint8_t MP.mp.MPTA Struktur den PIN1 in PORTA auf LOW oder HIGH setzen. Danke!
1 | PORTA = (PORTA & ~(1 << PIN1)) | (MP.mp.MPTA & (1 << PIN1)); |
Stefan Ernst schrieb: > PORTA = (PORTA & ~(1 << PIN1)) | (MP.mp.MPTA & (1 << PIN1)); Ist sogar noch ein Takt schneller als der Zweizeiler des TO.
Luk4s K. schrieb: > Stefan Ernst schrieb: >> PORTA = (PORTA & ~(1 << PIN1)) | (MP.mp.MPTA & (1 << PIN1)); > Ist sogar noch ein Takt schneller als der Zweizeiler des TO. Danke. Verstehe, weil der PORT erst nach der Ermittlung des Endergebnisses gesetzt wird, während er vorher immer erst einmal auf LOW gesetzt wird - oder ?
Hendrik L. schrieb: > Luk4s K. schrieb: >> Stefan Ernst schrieb: >>> PORTA = (PORTA & ~(1 << PIN1)) | (MP.mp.MPTA & (1 << PIN1)); >> Ist sogar noch ein Takt schneller als der Zweizeiler des TO. > > Danke. > > Verstehe, weil der PORT erst nach der Ermittlung des Endergebnisses > gesetzt wird, während er vorher immer erst einmal auf LOW gesetzt wird - > oder ? Ich hab's durch den Complier geschoben:
1 | PORTA &=~(1<<PIN1); |
2 | 50: d9 98 cbi 0x1b, 1 ; 27 |
3 | PORTA |= s&(1<<PIN1); |
4 | 52: 9b b3 in r25, 0x1b ; 27 |
5 | 54: 82 70 andi r24, 0x02 ; 2 |
6 | 56: 89 2b or r24, r25 |
7 | 58: 8b bb out 0x1b, r24 ; 27 |
1 | PORTA = (PORTA&~(1<<PINA1)) | (s & (1 << PIN1)); |
2 | 50: 9b b3 in r25, 0x1b ; 27 |
3 | 52: 82 70 andi r24, 0x02 ; 2 |
4 | 54: 9d 7f andi r25, 0xFD ; 253 |
5 | 56: 89 2b or r24, r25 |
6 | 58: 8b bb out 0x1b, r24 ; 27 |
Beides sind 5 Instruktionen, aber das cbi braucht 2 Takte; in, andi, or, out nur je einen.
Hendrik L. schrieb: > Verstehe, weil der PORT erst nach der Ermittlung des Endergebnisses > gesetzt wird, während er vorher immer erst einmal auf LOW gesetzt wird - > oder ? PORTA ist als IO-Register volatile, das heißt, der Compiler muss genauso viele Lese- und Schreibzugriffe in der selben Reihenfolge durchführen, wie es im Programm steht. Im Beispiel mit zwei Zeilen wird PORTA zweimal modifiziert, was zweimal lesen-modifizieren-schreiben heißt. In diesem Spezialfall konnte eine der Operationen in einem einzigen cbi Befehl abgehandelt werden. Die Version in einer Zeile liest PORTA einmal und schreibt einmal. Den selben Effekt könnte man auch mit einer temporären Variable erzeugen:
1 | uint8_t tmp; |
2 | |
3 | tmp = PORTA; |
4 | tmp &= ~(1 << PINA1); |
5 | tmp |= MP.mp.MPTA & (1 << PIN1); |
6 | PORTA = tmp; |
Das sollte dasselbe Ergebnis wie der Einzeiler ergeben.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.