8Bit PIC 32 Bit inkrementieren
-
Hallo Leute,
ich hab einen 8Bit PIC, auf diesem habe ich einen Timer welcher einen 32 Bit wert hochzählt.
Nun habe ich folgenden Code im Timer-Interrupt:
if( counter == 0x7FFFFFFF) counter = 0; else ++counter;
welche in assembler (compiler XC8) so aussieht:
95: if( counter == 0x7FFFFFFF) 000D 0A2A INCF counter, W 000E 1D03 BTFSS STATUS, 0x2 000F 2822 GOTO 0x22 0010 0A2B INCF 0x2B, W 0011 1D03 BTFSS STATUS, 0x2 0012 2822 GOTO 0x22 0013 0A2C INCF 0x2C, W 0014 307F MOVLW 0x7F 0015 1903 BTFSC STATUS, 0x2 0016 062D XORWF 0x2D, W 0017 1D03 BTFSS STATUS, 0x2 0018 2822 GOTO 0x22 96: counter = 0; 0019 3000 MOVLW 0x0 001A 00AD MOVWF 0x2D 001B 3000 MOVLW 0x0 001C 00AC MOVWF 0x2C 001D 3000 MOVLW 0x0 001E 00AB MOVWF 0x2B 001F 3000 MOVLW 0x0 0020 00AA MOVWF counter 0021 282A GOTO 0x2A 97: else 98: ++counter; 0022 3001 MOVLW 0x1 0023 07AA ADDWF counter, F 0024 3000 MOVLW 0x0 0025 3DAB ADDWFC 0x2B, F 0026 3000 MOVLW 0x0 0027 3DAC ADDWFC 0x2C, F 0028 3000 MOVLW 0x0 0029 3DAD ADDWFC 0x2D, F
also rund 30 Zyklen im Timer interurpt
Dann dachte ich mir ich mache die Bedingung so dass er den couner auf 0 zurücksetzt sobald das 31 Bit ne 1 hat:
if((*(((BYTE*)&counter) + 3 ) & 0x40)) counter = 0; else ++counter;
wäre dann in ASM: 18 Zykle
101: if((*(((BYTE*)&counter) + 3 ) & 0x40)) 000D 1F2D BTFSS 0x2D, 0x6 000E 2818 GOTO 0x18 102: counter = 0; 000F 3000 MOVLW 0x0 0010 00AD MOVWF 0x2D 0011 3000 MOVLW 0x0 0012 00AC MOVWF 0x2C 0013 3000 MOVLW 0x0 0014 00AB MOVWF 0x2B 0015 3000 MOVLW 0x0 0016 00AA MOVWF counter 0017 2820 GOTO 0x20 103: else 104: ++counter; 0018 3001 MOVLW 0x1 0019 07AA ADDWF counter, F 001A 3000 MOVLW 0x0 001B 3DAB ADDWFC 0x2B, F 001C 3000 MOVLW 0x0 001D 3DAC ADDWFC 0x2C, F 001E 3000 MOVLW 0x0 001F 3DAD ADDWFC 0x2D, F
aber das inkrementieren dauert ewig, wowie as 0 ! setzen!
Was könnte ich da optimieren!
es würde mit auch ein 24Bit Wert reichen aber das gibts ja nich!?
-
Um was für ne Architektur gehts denn? Wenn dir der Compilercode zu langsam scheint, mach es doch gleich selbst.
-
NullBockException schrieb:
Hallo Leute,
if( counter == 0x7FFFFFFF) counter = 0; else ++counter;
Wenn Counter signed ist, d.h. als INT deklariert, hat vielleicht der optimierende Compiler eine gute Idee:
if ( counter < 0 ) counter = 0; else ++counter;
Dieser Schnippsel ist nach Standard UB (undefined behaviour), da er mit einem nicht vorgesehenen Überlauf bei INT arbeitet. Du musst genau prüfen, ob der Code das macht, was Du willst. Außerdem wird der Fall
counter == 0x7FFFFFFF
nicht mehr behandelt - vielleicht spielt der eine Tick aber keine Rolle.viele grüße
ralph
-
if( counter == 0x7FFFFFFF) counter = 0; else ++counter;
Was macht er denn aus
counter=((counter+1)&0x7FFFFFFF);
oder
++counter; *(BYTE*)&counter &= 0x7f;
-
Gute Idee Ralph , muss ich mal prüfen:)
was mit auch noch aufgefallen ist,
dass
counter = 0;
im Vergleich zu:
*(((BYTE*)&counter) + 0 ) = 0; *(((BYTE*)&counter) + 1 ) = 0; *(((BYTE*)&counter) + 2 ) = 0; *(((BYTE*)&counter) + 3 ) = 0;
doppelt soviel zyklen braucht!
Was allerdings noch schlimmer ist, ist die Subtraktion:
delta = counter - diff;
alles signed long (32Bit auf PIC 8Bit)
diese zeile erzeugt (39 Zyklen)! naja gut.. aber da komm ich wohl nich drum rum:(
0059 082A MOVF counter, W 005A 00F2 MOVWF 0x72 005B 082B MOVF 0x2B, W 005C 00F3 MOVWF 0x73 005D 082C MOVF 0x2C, W 005E 00F4 MOVWF 0x74 005F 082D MOVF 0x2D, W 0060 00F5 MOVWF 0x75 0061 093C COMF __pcstackBANK0, W 0062 00F6 MOVWF 0x76 0063 093D COMF 0x3D, W 0064 00F7 MOVWF 0x77 0065 093E COMF 0x3E, W 0066 00F8 MOVWF 0x78 0067 093F COMF 0x3F, W 0068 00F9 MOVWF 0x79 0069 0AF6 INCF 0x76, F 006A 1903 BTFSC STATUS, 0x2 006B 0AF7 INCF 0x77, F 006C 1903 BTFSC STATUS, 0x2 006D 0AF8 INCF 0x78, F 006E 1903 BTFSC STATUS, 0x2 006F 0AF9 INCF 0x79, F 0070 0876 MOVF 0x76, W 0071 07F2 ADDWF 0x72, F 0072 0877 MOVF 0x77, W 0073 3DF3 ADDWFC 0x73, F 0074 0878 MOVF 0x78, W 0075 3DF4 ADDWFC 0x74, F 0076 0879 MOVF 0x79, W 0077 3DF5 ADDWFC 0x75, F 0078 0875 MOVF 0x75, W 0079 00C3 MOVWF 0x43 007A 0874 MOVF 0x74, W 007B 00C2 MOVWF 0x42 007C 0873 MOVF 0x73, W 007D 00C1 MOVWF 0x41 007E 0872 MOVF 0x72, W 007F 00C0 MOVWF delta
-
A: (nicht so gut) 40 Zyklen
118: counter=((counter+1)&0x7FFFFFFF);
000D 30FF MOVLW 0xFF
000E 00F0 MOVWF __pcstackCOMMON
000F 30FF MOVLW 0xFF
0010 00F1 MOVWF 0x71
0011 30FF MOVLW 0xFF
0012 00F2 MOVWF 0x72
0013 307F MOVLW 0x7F
0014 00F3 MOVWF 0x73
0015 3001 MOVLW 0x1
0016 00F4 MOVWF 0x74
0017 3000 MOVLW 0x0
0018 00F5 MOVWF 0x75
0019 3000 MOVLW 0x0
001A 00F6 MOVWF 0x76
001B 3000 MOVLW 0x0
001C 00F7 MOVWF 0x77
001D 082A MOVF counter, W
001E 07F4 ADDWF 0x74, F
001F 082B MOVF 0x2B, W
0020 3DF5 ADDWFC 0x75, F
0021 082C MOVF 0x2C, W
0022 3DF6 ADDWFC 0x76, F
0023 082D MOVF 0x2D, W
0024 3DF7 ADDWFC 0x77, F
0025 0874 MOVF 0x74, W
0026 05F0 ANDWF __pcstackCOMMON, F
0027 0875 MOVF 0x75, W
0028 05F1 ANDWF 0x71, F
0029 0876 MOVF 0x76, W
002A 05F2 ANDWF 0x72, F
002B 0877 MOVF 0x77, W
002C 05F3 ANDWF 0x73, F
002D 0873 MOVF 0x73, W
002E 00AD MOVWF 0x2D
002F 0872 MOVF 0x72, W
0030 00AC MOVWF 0x2C
0031 0871 MOVF 0x71, W
0032 00AB MOVWF 0x2B
0033 0870 MOVF __pcstackCOMMON, W
0034 00AA MOVWF counterB: (ganz gut 12 Zylen) rekord:ü
119: ++counter; 000D 3001 MOVLW 0x1 000E 07AA ADDWF counter, F 000F 3000 MOVLW 0x0 0010 3DAB ADDWFC 0x2B, F 0011 3000 MOVLW 0x0 0012 3DAC ADDWFC 0x2C, F 0013 3000 MOVLW 0x0 0014 3DAD ADDWFC 0x2D, F 120: *((BYTE*)&counter+3) &= 0x7f; 0015 307F MOVLW 0x7F 0016 00F0 MOVWF __pcstackCOMMON 0017 0870 MOVF __pcstackCOMMON, W 0018 05AD ANDWF 0x2D, F
121: