Funktion nicht nutzbar
-
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
-
DirkB schrieb:
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
Ihr seid so schlaue Typen ey, Wahnsinn.
weiter gehts
-
Hallo
Ich habe eine weitere Frage dazu, wie ich es am Besten machen kann.
Ich sehe den "Vorteil", dass mein struct und all die anderen Variablen für das Auslesen der Temp. nur in der Fkt. existiert und nachher den Speicherplatz wieder freigibt.Jetzt habe ich mir gedacht, dass ich aber trotzdem den Teil ab counter und slope vor dem switch-case in eine Fkt. calculateTemp packe, mit der Angabe der Resolution.
am Besten hätte ich es jetzt so gemacht, dass mir die ReadTemperature Funktion einen struct zurückgibt und ich diesen dann der Funktion calculate übergebe. Aber dafür müsste ich den struct wieder global machen oder ausserhalb der Funktion definieren.
Wenn ich das aber tue, dann kann ich ja gleich auf die Elemente des structs zugreifen.. und die Temperatur direkt berechnen.Wie könnte ich das denn jetzt am Besten machen?
double readTemperature(TEMP_RES resolution) { txDataBuf[0] = READ_TEMPERATURE; struct { int8_t HByte; uint8_t LByte; }ByteArray; HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, txDataBuf, 2, 10); // Shift is necessary because of i2C function description HAL_I2C_Master_Receive(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, (uint8_t*)&ByteArray, 2, 10); // Shift is necessary because of i2C function description double slope = ReadCommand(READ_SLOPE); double counter = ReadCommand(READ_COUNTER); switch(resolution) { case 0: // HALFDEGREE mode if((ByteArray.LByte != 0) & (ByteArray.HByte < 0) ) { Degrees = ByteArray.HByte - 0.5; }else if((ByteArray.LByte != 0) & (ByteArray.HByte > 0) ) { Degrees = ByteArray.HByte + 0.5; }else { Degrees = ByteArray.HByte + 0.0; } break; case 1: // FULLDEGREE mode Degrees = ByteArray.HByte; break; case 2: // HIGHRESOLUTION mode Degrees = ByteArray.HByte-0.25+((slope-counter)/slope); break; } return Degrees; }
-
maximus111111 schrieb:
am Besten hätte ich es jetzt so gemacht, dass mir die ReadTemperature Funktion einen struct zurückgibt und ich diesen dann der Funktion calculate übergebe. Aber dafür müsste ich den struct wieder global machen oder ausserhalb der Funktion definieren.
Du musst zwischen der Variablendefiniton und der Definiton der
struct
unterscheiden.Die struct-Definition sagt dem Compiler nur, wie die struct aufegebaut ist. Das frisst keinen Programmspeicher.
Bei der Variablendefiniton wird die Variable angelegt und verbraucht auch Speicher.Du hast jetzt beides gleichzeitig gemacht. Das ist macht eher selten.
In die .h oder nach den #include:
struct DS1621_Temp { int8_t HByte; uint8_t LByte; };
Bei der Nutzung:
struct Ds1621_Temp ByteArray; // Blöder Variablenname für eine struct
So eine struct kannst du dann auch als Rückgabewert einer Funktion machen.
-
achsoo ok, ich mach das mal, danke
-
Jetzt war ich zu voreilig, sorry.
Frage: wenn ich jetzt den struct im headerfile habe, macht ja ein Rückgabewert von einem ByteArray ja keinen Sinn mehr ... oder?
-
max111111 schrieb:
Jetzt war ich zu voreilig, sorry.
Frage: wenn ich jetzt den struct im headerfile habe, macht ja ein Rückgabewert von einem ByteArray ja keinen Sinn mehr ... oder?
Was hast du im Headerfile stehen?
Was verstehst du unter Bytearray?
-
also ich habe es jetzt so gelöst, ist aber natürlich nicht das was ich mit meiner Frage zuvor bezwecken wollte..
oder geht das was ich wollte doch irgendwie anderst?#ifndef TEMPSENSORDRIVER_H_ #define TEMPSENSORDRIVER_H_ #include "stm32l4xx_hal.h" #include "stdbool.h" /****************************************************************************** ** Constants, macros and type definitions ** ******************************************************************************/ /* Commands to the TempSensor - Read or Write*/ #define TEMP_SENSOR_ADRESS_7_BIT 0x48 #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 of Commands to the TempSensor - Read or Write*/ #define SHIFT 0x01 // enum definitions enum Temperature_conversion { CONTINUOUS_MODE, ONE_SHOT_MODE }; enum OutputPolarity { ACTIVE_LOW, ACTIVE_HIGH, }; enum ConfigRegister { ONE_SHOT, POL, NVB = 4U, TLF, THF, DONE }; enum TempResolution { HALF_DEGREE, FULL_DEGREE, HIGH_RESOLUTION }; // typedefs typedef enum Temperature_conversion TEMP_CONV; typedef enum OutputPolarity OUT_POL; typedef enum ConfigRegister CONV_REG; typedef enum TempResolution TEMP_RES; struct Temperature { int8_t HByte; uint8_t LByte; }; /****************************************************************************** ** Variables ** ******************************************************************************/ /****************************************************************************** ** Functions ** ******************************************************************************/ uint8_t ReadCommand(uint8_t command); void WriteCommand(uint8_t command); void init_TempSensor(TEMP_CONV mode, OUT_POL pol); void calbulateTemperature(TEMP_RES resolution); // helping functions used in other functions void readTemperature(void); // used in calculateTemperature // general proofing flag function bool ConfigRegisterFlag(CONV_REG configBit); #endif // TEMPSENSORDRIVER_H_
#include "TempSensorDriver.h" /****************************************************************************** ** Constants, macros and type definitions ** ******************************************************************************/ /****************************************************************************** ** Variables ** ******************************************************************************/ extern I2C_HandleTypeDef hi2c1; uint8_t txDataBuf[10]; // txData Buffer uint8_t rxDataBuf[10]; // rxData Buffer struct Temperature ByteArray; double degrees; /****************************************************************************** ** Functions ** ******************************************************************************/ /** * @brief ReadCommand(uint8_t command) gets all desired values of the TempSensor which should be read (only 1Byte values) * @param It uses the parameter command command could be ACCESS_TH, ACCESS_TL, ACCESS_CONFIG READ_COUNTER or READ_SLOPE */ uint8_t ReadCommand(uint8_t command) { txDataBuf[0] = command; // load data to Buffer[0] HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, txDataBuf, 1, 10); // Shift is necessary because of i2C function description HAL_I2C_Master_Receive(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, rxDataBuf, 1, 10); // Shift is necessary because of i2C function description return rxDataBuf[0]; } /** * @brief WriteCommand(uint8_t command) writes all desired values of the TempSensor which should be read (only 1Byte values) * @param It uses the parameter command command could be ACCESS_TH, ACCESS_TL, ACCESS_CONFIG, START_CONVERT_T or STOP_CONVERT_T */ void WriteCommand(uint8_t command) { txDataBuf[0] = command; // load data to Buffer[0] HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, txDataBuf, 1, 10); // Shift is necessary because of i2C function description } /** * @brief init_TempSensor(TEMP_CONV mode, POLARITY pol) intializes the TempSensor * @param takes the Conversion Mode mode out of the enum Temperature_conversion * and the polartiy out of enum OutputPolarity POLARITY * mode could be CONTINUOUS_MODE or ONE_SHOT_MODE * pol could be ACTIVE_LOW, ACTIVE_HIGH or if pol is not used select one of both */ void init_TempSensor(TEMP_CONV mode, OUT_POL pol) { txDataBuf[0] = ReadCommand(ACCESS_CONFIG); txDataBuf[0] &= ~( 1<<ONE_SHOT | 1<<POL); // delete bits generally txDataBuf[0] |= (mode<<ONE_SHOT | pol<<POL); // set Bits according to mode and pol while(!ConfigRegisterFlag(NVB)); // wait until EEPROM is written HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, txDataBuf, 1, 10); } double calculateTemperature(TEMP_RES resolution) { readTemperature(); // calculation according to the desired temperature resolution double slope = ReadCommand(READ_SLOPE); double counter = ReadCommand(READ_COUNTER); switch(resolution) { case 0: // HALFDEGREE mode if((ByteArray.LByte != 0) & (ByteArray.HByte < 0) ) { degrees = ByteArray.HByte - 0.5; }else if((ByteArray.LByte != 0) & (ByteArray.HByte > 0) ) { degrees = ByteArray.HByte + 0.5; }else { degrees = (double) ByteArray.HByte; } break; case 1: // FULLDEGREE mode degrees = ByteArray.HByte; break; case 2: // HIGHRESOLUTION mode degrees = ByteArray.HByte-0.25+((slope-counter)/slope); break; } return degrees; } /** * @brief readTemperature(TEMP_RES res) reads the converted temperature of the sensor * @param takes temperature resolution out of enum TempResolution TEMP_RES * resolution could be HALF_DEGREE, FULL_DEGREE, HIGH_RESOLUTION */ void readTemperature() { txDataBuf[0] = READ_TEMPERATURE; HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, txDataBuf, 1, 10); // Shift is necessary because of i2C function description HAL_I2C_Master_Receive(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, (uint8_t*)&ByteArray, 2, 10); // Shift is necessary because of i2C function description } /** * @brief checks the bits in the config Register of the TempSensor * @param takes the configBit out of the config Register CONV_REG * configBit could be NVB, TLF, THF or DONE */ bool ConfigRegisterFlag(CONV_REG configBit) { return ((ReadCommand(ACCESS_CONFIG) & (1 << configBit)) != 0); }
-
Standardheader bindet man immer mit spitzen Klammern <> ein.
#include <stdint.h> fehlt.
Nur Deppen benutzen globale Variablen.
Das Verwenden von int und double-Werten in einem Ausdruck ist fehleranfällig (insbesondere für Nichtprofis, die die C-internen Konvertierunsgregeln nicht kennen und verinnerlicht haben wie Profis es haben).
-
Wutz schrieb:
Standardheader bindet man immer mit spitzen Klammern <> ein.
hab ich erledigt.
Wutz schrieb:
#include <stdint.h> fehlt.
Ich glaube nicht, denn ich bekomme so keine Fehlermeldung. Also muss diese irgendwo in der #include "stm32l4xx_hal.h" definiert sein.
Wutz schrieb:
Nur Deppen benutzen globale Variablen.
und das heisst was?
Wutz schrieb:
Das Verwenden von int und double-Werten in einem Ausdruck ist fehleranfällig (insbesondere für Nichtprofis
Was heisst das?
dass ich das HByte bevor ich dieses mit dem double verrechne casten muss?