Hallo zusammen,
ich versuche gerade eine atomare Berechnung "ordentlich", also mit
zwischenspeichern des SREG zu programmieren.
Mein c-Code sieht so aus:
1 | uint8_t lclSREG = SREG;
|
2 | cli();
|
3 | LN_UART_FR &= ~(0x1C << ShiftValue);
|
4 | LN_UART_FR ^= 0x02;
|
5 | SREG = lclSREG;
|
Im Disassembly sieht dann so aus:
1 | uint8_t lclSREG = SREG;
|
2 | 0000009F IN R20,0x3F In from I/O location
|
3 | cli();
|
4 | 000000A0 CLI Global Interrupt Disable
|
5 | LN_UART_FR &= ~(0x1C << ShiftValue);
|
6 | 000000A1 LDS R21,0x0205 Load direct from data space
|
7 | 000000A3 LDI R18,0x1C Load immediate
|
8 | 000000A4 LDI R19,0x00 Load immediate
|
9 | 000000A5 MOVW R22,R18 Copy register pair
|
10 | 000000A6 RJMP PC+0x0003 Relative jump
|
11 | 000000A7 LSL R22 Logical Shift Left
|
12 | 000000A8 ROL R23 Rotate Left Through Carry
|
13 | 000000A9 DEC R25 Decrement
|
14 | 000000AA BRPL PC-0x03 Branch if plus
|
15 | 000000AB MOVW R24,R22 Copy register pair
|
16 | 000000AC COM R24 One's complement
|
17 | 000000AD AND R24,R21 Logical AND
|
18 | 000000AE STS 0x0205,R24 Store direct to data space
|
19 | LN_UART_FR ^= 0x02;
|
20 | 000000B0 LDS R25,0x0205 Load direct from data space
|
21 | 000000B2 LDI R24,0x02 Load immediate
|
22 | 000000B3 EOR R24,R25 Exclusive OR
|
23 | 000000B4 STS 0x0205,R24 Store direct to data space
|
24 | SREG = lclSREG;
|
25 | 000000B6 OUT 0x3F,R20 Out to I/O location
|
Wenn ich (im AVR Studio 6 Simulator) bei 0x9F einen Breakpoint setze,
kann ich im "Processor"-Fenster auch sehen, dass das I-Flag und H-Flag
im SREG gesetzt sind. Einen Einzelschritt weiter ist dann R20 aber nur
0x20. Das I-Flag wird also nicht übernommen und demnach auch bei 0xB6
nicht wieder eingeschaltet.
Ein schneller Blick ins Datenblatt vermittel mir das Gefühl, dass das
komplette SREG leß- und schreibbar ist, weshalb ich nicht verstehe,
warum sich das I-Bit nicht auslesen läßt.
Kann mir da jemand auf die Sprünge helfen?
Dank und Gruß
Lars