Funktion nicht nutzbar



  • Hallo

    Ich habe eine Funktion getConfig, aber leider kann ich diese einem Pointer nicht zuweisen.
    Was ist hier falsch?

    uint8_t *p;
    p= getConfig();
    
    #include "tempSensorDriver.h"
    #include "stm32f3xx_hal.h"
    
    /******************************************************************************
     ** Constants, macros and type definitions                                   **
     ******************************************************************************/
    
    /******************************************************************************
     ** Variables                                                                **
     ******************************************************************************/
    
    extern I2C_HandleTypeDef hi2c1;
    
    /******************************************************************************
     ** Functions                                                                **
     ******************************************************************************/
    
    uint8_t* getConfig(void)
    {
    	uint8_t txDataBuffer[1];                            																									            // sendig dataarray for access_config command
    	static uint8_t rxDataBuffer[1];                            													  								            // receiving dataarray for access_config command
    	txDataBuffer[0] = ACCESS_CONFIG;
    
    	HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_bit << SHIFT, txDataBuffer, sizeof(txDataBuffer), 10);        // Shift is necessary because of i2C function description
    	HAL_I2C_Master_Receive(&hi2c1, TEMP_SENSOR_ADRESS_7_bit << SHIFT, &rxDataBuffer[0], sizeof(rxDataBuffer), 10);     // Shift is necessary because of i2C function description
    	return rxDataBuffer;
    }
    
    void Init_TempSensor(TEMP_CONV mode)
    {
    	// variables and pointer definitions
    	uint8_t convMode = mode;
    	uint8_t *config;
      uint8_t txDataBuffer[1];
    	uint8_t *p_txDataBuffer;
    	p_txDataBuffer = txDataBuffer;
    
    	config = getConfig();
    
    	// choosing 1Shot-Mode or continuous mode
    	if(convMode == 1)																																																	// if 1SHOT-Mode
    	{
    		config[0] |= convMode;   
    	}	else
    	  {
    			config[0] &= convMode;  
    	  }
    
      p_txDataBuffer = config;																																													// committing value of config to pointer after changing Lsb
    
    	//_delay_ms(12);																																										// wait for at least 10ms - better 12ms
    
    	HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_bit << SHIFT, p_txDataBuffer, sizeof(txDataBuffer), 10);
    }
    
    #ifndef TEMPSENSORDRIVER_H_
    #define TEMPSENSORDRIVER_H_
    
    //#include "types.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
     };
    
     typedef enum Temperature_conversion TEMP_CONV;
    
    /******************************************************************************
     ** Variables                                                                **
     ******************************************************************************/
    
    /******************************************************************************
     ** Functions                                                                **
     ******************************************************************************/
    
    void getConfig(void);
    void Init_TempSensor(enum Temperature_conversion mode);
    
    #endif // TEMPSENSORDRIVER_H_
    


  • Meine c-Kentnisse sind ein bisschen eingerostet, aber ich fürchte du schmeißt Pointer und Arrays durcheinander.

    In getConfig definierst du rxDataBuffer als Array (mt der Größe 1??).
    Der Returnwert soll ein Pointer auf uint8_t sein, aber versucht das Array zurück zu geben.



  • Du hast 2 Fehler:
    1. In der Headerdatei stimmt der Rückgabewert der Funktion nicht
    2. Du darfst keinen Zeiger auf ein lokales Array zurückgeben (da das Array nach Verlassen der Funktion nicht mehr existiert)

    Edit: Ich habe das statische Array nicht gesehen, sondern nur das lokale Array (weil die Variablennamen fast gleich sind).



  • Bin mir nicht sicher ob es in dem Fall funktionieren könnte da das Array ja static ist. Sieht jedenfalls komisch aus.



  • Ich weiß nicht, ob das mit dem statischen Array komisch aussieht. Es ist jedenfalls richtig so. Der einzige Fehler ist, dass der Rückgabetyp im Header als void statt uint8_t* angegeben ist. (Jedenfalls der einzige offensichtliche ... einige Sachen sind komisch formuliert, aber die die ich gecheckt hab stimmen.)

    Ich kann die Kommentare übrigens gerade noch auf meinem zweiten Monitor erkennen, vielleicht lässt es sich einrichten, die noch weiter nach rechts zu schieben? Wer will Kommentare sehen? 😉



  • "aber leider kann ich diese einem Pointer nicht zuweisen" implizierst eher, dass er einen Funktionszeiger will und nicht den Rückgabewert.
    Falls das der Fall ist, ist das:

    uint8_t *p;
    p= getConfig();
    

    natürlich die falsche Schreibweise.



  • ok, warum ist das alles komisch?
    Anders fällt mir sonst keine Möglichkeit ein, einen Register auszulesen und diesen zu bearbeiten.
    Es geht um einen Tempsensor. (Ds1621)
    Ich schicke dem einen command AccessConfig 0xAC und bekomme einen Konfigurationsregisterwert (8 bit= 1Byte).
    Der wird nehme ich mal an irgend ein Dezimalwert sein, was halt in binär umzurechnen ist.
    Dieses Byte muss ich in ein Array packen, da die i2C Funktion einen pointer will (3. Parameter = *data). Deshalb muss ich es so kompliziert machen und daher die Grösse 1 des Arrays selbst.
    Nachdem getConfig ein Array zurückgibt kann ich dieses Array ja nicht einfach einer Variable zuweisen, sondern ein Pointer drauf zeigen lassen. deshalb p = getConfig();
    Wenn ich den Wert p übergeben habe, wollte ich diesen im Anschluss so manipulieren, dass das LSB bit auf 1 gesetzt wird, falls es nicht ist und dann wieder per i2C schreiben.

    Das im main mit p= getConfig(); war nur ein Test.
    Eigentlich sollte mir das Init_TempSensor das was ich oben erklärt habe alles erledigen, wenn ich die Fkt aufrufe.

    Ich bitte um Tipps und Anregungen.

    Ich würde gerne wissen, warum das was ich mache komisch ist und wie es denn besser geht. Wäre euch da dankbar. Ich wollte einfach mal nach ein wenig Theorie einen Sensor auslesen bzw. zuerst zu initialisieren.



  • max111111 schrieb:

    Der wird nehme ich mal an irgend ein Dezimalwert sein, was halt in binär umzurechnen ist.

    Es ist ein Wert.
    Wie immer du ihn betrachtest (dezimal, binär, Hex), es bleibt derselbe Wert.

    max111111 schrieb:

    Dieses Byte muss ich in ein Array packen, da die i2C Funktion einen pointer will (3. Parameter = *data). Deshalb muss ich es so kompliziert machen und daher die Grösse 1 des Arrays selbst.

    Den Adressoperator & kennst du aber?

    max111111 schrieb:

    Nachdem getConfig ein Array zurückgibt kann ich dieses Array ja nicht einfach einer Variable zuweisen, sondern ein Pointer drauf zeigen lassen. deshalb p = getConfig();

    Verzichte auf das Array

    Bei getchar bekommst du doch auch einen Wert geliefert und kannst ihn bearbeiten und wieder ausgeben.

    uint8_t getConfig(void)
    {
        uint8_t txDataBuffer;                                                                                                                                            // sendig dataarray for access_config command
        uint8_t rxDataBuffer;                                                                                                                         // receiving dataarray for access_config command
        txDataBuffer = ACCESS_CONFIG;
    
        HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_bit << SHIFT, &txDataBuffer, sizeof(txDataBuffer), 10);        // Shift is necessary because of i2C function description
        HAL_I2C_Master_Receive (&hi2c1, TEMP_SENSOR_ADRESS_7_bit << SHIFT, &rxDataBuffer, sizeof(rxDataBuffer), 10);        // Shift is necessary because of i2C function description
        return rxDataBuffer;
    }
    


  • [quote="DirkB"]

    max111111 schrieb:

    Den Adressoperator & kennst du aber?

    ja aber die Adresse des Arrays ist der Name des Arrays selbst

    [quote="DirkB"]

    max111111 schrieb:

    max111111 schrieb:

    Nachdem getConfig ein Array zurückgibt kann ich dieses Array ja nicht einfach einer Variable zuweisen, sondern ein Pointer drauf zeigen lassen. deshalb p = getConfig();

    Verzichte auf das Array

    Bei getchar bekommst du doch auch einen Wert geliefert und kannst ihn bearbeiten und wieder ausgeben.

    Ich versuche es morgen einmal zu implementieren. 👍

    Ich danke euch allen



  • Mal ne grundlegende Frage, mit welchem Controller kommuniziert dein Sensor?



  • max111111 schrieb:

    ja aber die Adresse des Arrays ist der Name des Arrays selbst

    Das ist richtig.

    Das ist aber trotzdem kein Grund, hier ein Array zu benutzen.



  • vfbhrtfg schrieb:

    Mal ne grundlegende Frage, mit welchem Controller kommuniziert dein Sensor?

    Hallo

    steht im c-file (Einbindung headerfiles) 1. Seite

    ich arbeite jetzt gerade aber mit dem Nucleo stm32L4



  • DirkB schrieb:

    max111111 schrieb:

    ja aber die Adresse des Arrays ist der Name des Arrays selbst

    Das ist richtig.

    Das ist aber trotzdem kein Grund, hier ein Array zu benutzen.

    Sieht es jetzt besser aus?
    Ich habe das mal gemacht, was du mir geraten hast.

    #include "TempSensorDriver.h" 
    #include "stm32l4xx_hal.h" 
    
    /****************************************************************************** 
     ** Constants, macros and type definitions                                   ** 
     ******************************************************************************/ 
    
    /****************************************************************************** 
     ** Variables                                                                ** 
     ******************************************************************************/ 
    
    extern I2C_HandleTypeDef hi2c1; 
    
    /****************************************************************************** 
     ** Functions                                                                ** 
     ******************************************************************************/ 
    
    char 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 
    
        HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, &txData, sizeof(txData), 10); 
    }
    
    #ifndef TEMPSENSORDRIVER_H_ 
    #define TEMPSENSORDRIVER_H_ 
    
    //#include "types.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 
     }; 
    
     typedef enum Temperature_conversion TEMP_CONV; 
    
    /****************************************************************************** 
     ** Variables                                                                ** 
     ******************************************************************************/ 
    
    /****************************************************************************** 
     ** Functions                                                                ** 
     ******************************************************************************/ 
    
    char getConfig(void); 
    void Init_TempSensor(enum Temperature_conversion mode); 
    
    #endif // TEMPSENSORDRIVER_H_
    


  • 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;
    

Log in to reply