Funktion nicht nutzbar



  • Der Rückgabetyp bei der Definition, Deklaration und beim return sollten schon übereinstimmen.

    Beim löschen von convMode fehlt noch etwas.



  • DirkB-offline schrieb:

    Der Rückgabetyp bei der Definition, Deklaration und beim return sollten schon übereinstimmen.

    Beim löschen von convMode fehlt noch etwas.

    Ok, ich habe den rückgabewert auf uint8_t geändert, weil es die i2C fkt. auch so benötigt und es im h-file geändert.

    aber das mit dem Löschen, was da noch fehlt sehe ich nicht..



  • Die bitweise Negation:

    txData &= ~convMode;
    


  • Th69 schrieb:

    Die bitweise Negation:

    txData &= ~convMode;
    

    danke vielmals, omg, ich habe das tausend mal angeschaut und einfach nicht gesehen. 😋 👍
    danke

    Ich habe mal meinen Code erweitert und wollte bevor ich eine Temperatur auslese das Conversion Done bit, MSB, prüfen.

    Nun bekomme ich eine Fehlermeldung, die ich nicht verstehe. (Siehe nachfolgend)
    Ich möchte also mit der neuen Funktion im main zB while(!conversion_Done()); nutzen und warten, bis das Done-bit 1 ist.
    Das müsste doch so funktionieren.

    *** Using Compiler 'V5.06 update 4 (build 422)', folder: 'C:\Keil_v5\ARM\ARMCC\Bin'
    Build target 'quadrocopter_bldc'
    compiling TempSensorDriver.c...
    ../Inc/TempSensorDriver.h(67): warning: #1295-D: Deprecated declaration conversion_Done_Flag - give arg types
    bool conversion_Done_Flag();
    ..\Src\TempSensorDriver.c: 1 warning, 0 errors
    linking...
    Program Size: Code=6904 RO-data=488 RW-data=8 ZI-data=1104
    "quadrocopter_bldc\quadrocopter_bldc.axf" - 0 Error(s), 1 Warning(s).
    Build Time Elapsed: 00:00:03

    #include "TempSensorDriver.h" 
    
    /****************************************************************************** 
     ** Constants, macros and type definitions                                   ** 
     ******************************************************************************/ 
    
    /****************************************************************************** 
     ** Variables                                                                ** 
     ******************************************************************************/ 
    
    extern I2C_HandleTypeDef hi2c1; 
    
    /****************************************************************************** 
     ** Functions                                                                ** 
     ******************************************************************************/ 
    
    uint8_t getConfig(void) 
    { 
        uint8_t txData;                                                // sending dataarray for access_config command 
        static uint8_t rxData;                                         // receiving dataarray for access_config command 
    	                                                                 // static because of variable rxData validity only within the function
    
        txData = ACCESS_CONFIG; 
    
        HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, &txData, sizeof(txData), 10);    // Shift is necessary because of i2C function description 
        HAL_I2C_Master_Receive(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, &rxData, sizeof(rxData), 10);     // Shift is necessary because of i2C function description 
        return rxData;
    } 
    
    void init_TempSensor(TEMP_CONV mode) 
    { 
        // variables
        uint8_t convMode = mode; 
        uint8_t txData; 
    
        txData = getConfig(); 
    
        // choosing 1Shot-Mode or continuous mode 
        if(convMode == 1)                                            // if 1SHOT-Mode 
        { 
          txData |= convMode;                                        // set LSB-Bit 1SHOT
        } else 
          { 
            txData &= ~convMode;                                     // delete LSB-Bit 1SHOT  
          }
    
        //_delay_ms(12);                                             // wait for at least 10ms - better 12ms for config process
    
        HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, &txData, sizeof(txData), 10); 
    }
    
    bool conversion_Done() 
    { 
        // variables
    	  done = FALSE;
    	  CONV_REG DONE;
        uint8_t config; 
    
    	  while(!done)
    		{
    			config = getConfig(); 
    			if((config & DONE) == 1)                               // if 1SHOT-Mode 
    			{ 
    				done = TRUE;
    			} else 
    				{ 
    					done = FALSE;
    				}		
    		}
    
    		return done;
    
    }
    
    #ifndef TEMPSENSORDRIVER_H_ 
    #define TEMPSENSORDRIVER_H_ 
    
    #include "stm32l4xx_hal.h" 
    
    /****************************************************************************** 
     ** Constants, macros and type definitions                                   ** 
     ******************************************************************************/ 
    
     /* Commands to the TempSensor - Read or Write*/ 
     #define TEMP_SENSOR_ADRESS_7_BIT                                          0x48 
    
     /* DS1621 Command set*/ 
     #define READ_TEMPERATURE                                                  0xAA 
     #define ACCESS_TH                                                         0xA1 
     #define ACCESS_TL                                                         0xA2 
     #define ACCESS_CONFIG                                                     0xAC 
     #define READ_COUNTER                                                      0xA8 
     #define READ_SLOPE                                                        0xA9 
     #define START_CONVERT_T                                                   0xEE 
     #define STOP_CONVERT_T                                                    0x22 
     /**End DS1621 Command Set*/ 
    
     #define SHIFT                                                             0x01 
     enum Temperature_conversion 
     { 
         CONTINUOUS_MODE, 
         ONE_SHOT_MODE 
     }; 
    
     enum boolean 
     { 
         FALSE, 
         TRUE 
     };
    
      enum ConfigRegister 
     { 
         ONE_SHOT, 
         POL,
         NVB = 4U,
         TLF,
         THF,
         DONE	 
     }; 
    
     typedef enum Temperature_conversion TEMP_CONV;
     typedef enum boolean bool;
     typedef enum ConfigRegister CONV_REG; 
    
    /****************************************************************************** 
     ** Variables                                                                ** 
     ******************************************************************************/ 
    
     bool pol; 
     bool nvb;
     bool tlf;
     bool thf; 
     bool done; 
    /****************************************************************************** 
     ** Functions                                                                ** 
     ******************************************************************************/ 
    
    uint8_t getConfig(void); 
    void init_TempSensor(TEMP_CONV mode); 
    bool conversion_Done();
    #endif // TEMPSENSORDRIVER_H_
    


  • Du sollst explizit "void" als Funktionsparameter angeben (ohne Angabe wird es als Funktion mit beliebig vielen Parametern interpretiert - daher die Warnung).



  • max111111 schrieb:

    Ich möchte also mit der neuen Funktion im main zB while(!conversion_Done());

    Warum dann noch die while-Schleife in conversion_Done?

    max111111 schrieb:

    bis das Done-bit 1 ist.
    Das müsste doch so funktionieren.

    Verstehst du die Zeilen 57 und 58 in deinem C Programm?

    Das if((config & DONE) == 1) funktioniert nur, wenn DONE auch den Wert 1 hat.

    max111111 schrieb:

    das Conversion Done bit, MSB,

    deutet aber eher nicht darauf hin (MSB würde 128 sein)

    Darum
    if((config & DONE) == DONE)
    oder
    if((config & DONE) != 0)
    oder
    if(config & DONE)

    Oder kurz (aber nicht schmerzlos)

    bool conversion_Done()
    { 
       int done;
       while(!(done = !!(getConfig() & DONE)))
       return done;
    }
    

    Achja, bool ist kein Datentyp, den der Compiler einfach so kennt ( wie int oder char ).
    Wenn du bool benutzt, dann musst du den passenden Header einfügen.



  • DirkB: Das hatte mich auch erst verwundert, aber er hat es selber definiert (in Zeile 49 der Header-Datei):

    typedef enum boolean bool;
    


  • ach da ist ja auch das DONE definiert.
    Da hat das aber den Wert 7. Demnach wird auch nicht mit DONE direkt verglich sondern mit (1<<DONE)



  • [quote="DirkB"]

    max111111 schrieb:

    Achja, bool ist kein Datentyp, den der Compiler einfach so kennt ( wie int oder char ).
    Wenn du bool benutzt, dann musst du den passenden Header einfügen.

    Was für ein header, wenn ich es nicht selbst definiert hätte.
    Ich weiss nicht, warum es kein bool gibt, ich finde es noch nützlich..
    Ich bin für sprechende Namen und möchte nicht mit 1 und 0 hantieren müssen, wenn es geht.

    Ich habe eigentlich (1<<DONE) schreiben wollen, habe es dann jedoch vergessen zu ändern.

    Ich habe die Funktion folgend abgeändert.
    So müsste es nämlich auch gehen, wenn ich im main das conversion_Done_flag prüfe mit while(!conversion_Done);
    Richtig? Ich sehe keinen Fehler mehr in meiner Funktion:

    bool conversion_Done() 
    { 
    		if((getConfig() & (1 << DONE)) == 1)                                   // if DONE-bit = 1
    		{ 
    			done = TRUE;
    		} else 
    			{ 
    				done = FALSE;
    			}		
    
    		return done;
    }
    


  • max111111 schrieb:

    Was für ein header, wenn ich es nicht selbst definiert hätte.
    Ich weiss nicht, warum es kein bool gibt, ich finde es noch nützlich..

    Bool gibt es in C seit fast 20 Jahren. Wo, sollte in deinen Lehrunterlagen stehen.

    max111111 schrieb:

    Ich sehe keinen Fehler mehr in meiner Funktion:

    DirkB schrieb:

    Das if((config & DONE) == 1) funktioniert nur, wenn DONE auch den Wert 1 hat.

    Welchen Wert hat denn (1 << DONE)? 1 ist es wohl nicht.



  • DirkB schrieb:

    max111111 schrieb:

    Was für ein header, wenn ich es nicht selbst definiert hätte.
    Ich weiss nicht, warum es kein bool gibt, ich finde es noch nützlich..

    Bool gibt es in C seit fast 20 Jahren. Wo, sollte in deinen Lehrunterlagen stehen.

    wir haben das so leider nie angeschaut, auch nicht welche einzelnen Funktionen .h-files alle auch enthalten.
    aber hat sich erledigt, ich habe das bzgl. des bool google gefragt 😛

    [quote="DirkB"]

    max111111 schrieb:

    DirkB schrieb:

    Das if((config & DONE) == 1) funktioniert nur, wenn DONE auch den Wert 1 hat.

    Welchen Wert hat denn (1 << DONE)? 1 ist es wohl nicht.

    Ja DONE hat den WErt 7. Das ist so beabsichtigt, denn ich schiebe so die 1 solange bis ich das entsprechende Register erreicht habe, ohne zu wissen, wie dieses aufgebaut ist.
    Sollte ja so richtig sein oder?

    bool checkconfigRegFlag(CONV_REG configBit) 
    { 
    		if((getConfig() & (1 << configBit)) == 1)                         // if DONE-bit = 1
    		{ 
    			flag = true;
    		} else 
    			{ 
    				flag = false;
    			}		
    
    		return flag;
    }
    




  • max111111 schrieb:

    Ja DONE hat den WErt 7.

    Und welchen Wert hat 1<<Done?

    max111111 via Picload schrieb:

    1000000

    Welcher Wert ist das?
    Aber wenn du schon das schöne Bitmuster hast, was kommt denn nach dem & raus?

    1111000
    & 1000000 
    ---------
    = ???????
    

    kommt da 1 raus?

    max111111 schrieb:

    Sollte ja so richtig sein oder?

    Nö, immer noch nicht.



  • Habe ich ein brett vor den Augen?

    Ich weiss irgendwie nicht worauf du hinaus willst.

    Ich will ja nur das MSB lesen. Mich interessiert da doch nicht, dass der Wert 128 raus kommt?! oder doch? 😕

    oder meinst du, dass ich das Ganze noch zurück schieben muss um DONE, weil ich das ja mit 1 nicht vergleichen kann 😕

    128 ist nämlich ned 1



  • warte mal, das ist doch einfacher als die ganze rumschieberei oder?

    if(getConfig() & configBit) != 0)



  • max111111 schrieb:

    warte mal, das ist doch einfacher als die ganze rumschieberei oder?

    if(getConfig() & configBit) != 0)

    Ob das richtig ist, hängt vom Wert von configBit ab.
    Wenn das eine Zweierpotenz ist, ist das in Ordnung. Wenn es Z.B 7 ist, dann nicht.



  • und da gibts nichts kürzeres für

    if(((accessConfig() & (1 << configBit)) >> configBit) == 1)

    😕



  • max111111 schrieb:

    und da gibts nichts kürzeres für

    if(((accessConfig() & (1 << configBit)) >> configBit) == 1)

    😕

    Klar.

    Das Ergebnis von (accessConfig() & (1 << configBit)) ist entweder 0 oder (1 << configBit)

    Also 0 oder nicht 0, keinesfalls aber 1

    Das != 0 von 20:47:30 war schon in Ordnung (das & configBit aber nicht)

    Um 16:41:42 DirkB schrieb:

    Darum
    if((config & DONE) == DONE)
    oder
    if((config & DONE) != 0)
    oder
    if(config & DONE)

    Da bin ich aber davon ausgegangen, das DONE schon der richtige Wert ist (eben das (1 << configBit) )

    Deine ganze Funktion reduziert sich auf

    return (accessConfig() & (1 << configBit) != 0
    

    ohne flag, if-else



  • Ich habe meine Init Fkt. nochmals angepasst und habe nun die Polaritätseinstellung noch als Parameter mitgegeben.

    Nun habe ich 2 ifs drin.
    Ich habe versucht diese beiden ifs zusammen zu fassen, habe aber festgestellt, dass ich dann mehrere Bedingungen prüfen muss.
    Getrennt, ist es dann doch einfacher so wie unten.

    Bin ich da im Recht oder gibt es da auch eine bessere Variante wie man das effizienter machen könnte?

    void init_TempSensor(TEMP_CONV mode, POLARITY pol) 
    { 
        // variables
        uint8_t convMode = mode;
    	  uint8_t polarity = pol;
        uint8_t txData; 
    
        txData = accessConfig(); 
    
    	  // choosing 1Shot-Mode or continuous mode 
        if(convMode == 1)                                            // if 1SHOT-Mode 
        { 
          txData |= convMode;                                        // set LSB-Bit 1SHOT
        } else 
          { 
            txData &= ~convMode;                                     // delete LSB-Bit 1SHOT  
          }
    
    		// choosing Polarity functionality
    	  if(polarity == 1)                                            // if polarity is activeHigh = 1
    		{
    			txData |= (1 << POL);
    		}else
    		 {
    			 txData &= ~(1 << POL);
    		 }
    
        //_delay_ms(12);                                             // wait for at least 10ms - better 12ms for config process
    
        HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, &txData, sizeof(txData), 10); 
    }
    


  • Du kannst auch die Bits generell löschen und bei Bedarf setzen.
    Bzw, wenn pol und mode wirklich nur 0 oder 1 sind, kannst du auch diese Werte verschieben.

    txData &= ~(   1<<ONE_SHOT |   1<<POL); // Bits löschen
    txData |=  (mode<<ONE_SHOT | pol<<POL); // Bits entsprechen setzen
    

Anmelden zum Antworten