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
    


  • @Volkard:

    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 counter

    B: (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:


Log in to reply