hallo Ich mache hier mal einen neuen Thread auf, da ich denke, dass dies nicht mehr viel mit dem anderen Thema von mir zu tun hat. Ich lese bei meinem Sensor DS1621 die Temperatur aus. Laut Datenblatt bekomme ich 2Byte zurück geliefert. MSB first Nun habe ich die Transmit- und die Receivefunktion vom I2C die folgend aufgebaut ist: HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); Beim Transmit gebe ich den Command, dass ich die Temperatur auswerten möchte heraus, das wäre dann die Angabe pData. Da ich nur den Command Read_Temp möchte, ist auch die Länge/Size 1Byte, also 1 Beim Receive dann aber --> muss ich die Adresse angeben, wo er mir die Daten uint8_t Daten hinspeichern soll. zB &rxData die Grösse muss dann aber 2 Byte angegeben werden, also Size= 2 Jetzt kommt ja das MSB zuerst an, diese Werte können nun positiv aber auch negativ sein. Wie erkenne ich das aber wenn in der Receive Funktion der pointer auf einen uint8_t zeigt??? Ausserdem was ich wissen möchte ist, wenn ich zB einen Pointer definiert habe ist ja, weil das MSB zuerst geschickt wird, der Wert vom pointer *p = MSB-Byte (irgend ein uint8_t Wert) wenn ja, wie komme ich dann an das LSB-Byte? ich habe das noch nicht so ganz verstanden... wie die Fkt. tickt.. Ich hätte jetzt einfach 2 Pointer gemacht uint8_t* p_rxDataH, p_rxDataL; Aber ich habe keine Ahnung wie ich durch die einmalig aufzurufende Fkt Receive an 2 Werte komme, vor allem wie ich durch uint8_t auch negative Werte erhalte?? Ich hoffe es kann mir jemand weiterhelfen..
Solltest du dringend mal lesen! http://cs.indstate.edu/~cbasavaraj/cs559/the_c_programming_language_2.pdf
Es gibt in C die Möglichkeit Mehrere Element desselben Datentyps zusammenhängend im Speicher zu halten. Das wird Array genannt. Du kannst auch eine struct dafür anlegen. Die Empfangenen Daten musst du dann entsprechen auswerten und passend zusammenbauen. Wenn dein Rechner auch im Zweierkomplement rechnet geht das z.B so:
1 | uint8_t ds_data[2]; |
2 | ... // Temperaturdaten empfangen |
3 | short Temp = ds_data[0] << 8 | ds_data[1]; |
pData ist ein array, und du übergibst der funktion einen Pointer auf das erste Arrayelemnt. uint8_t pData[20]; -> funtionsaufruf MSB steht dann in pData[0], LSB in pData[1]. Danach kannst du MSB auf int8 casten, wenn dich das Vorzeichen interessiert. int8_t temp_msb = (int8_t)pData[0];
Joe F. schrieb: > pData ist ein array, und du übergibst der funktion einen Pointer > auf das > erste Arrayelemnt. > > uint8_t pData[20]; > -> funtionsaufruf > > MSB steht dann in pData[0], LSB in pData[1]. > > Danach kannst du MSB auf int8 casten, wenn dich das Vorzeichen > interessiert. > > int8_t temp_msb = (int8_t)pData[0]; achsooo, danke :) ja ich frage deshalb so deppert, weil ich den Fehler schon mal gemacht habe und mich mit pointern vertan habe. Ich habe diese Funktion hier geschrieben und verwende hier normale variablen statt pointern. Wenn doch pData ein Array ist, wieso kann ich das dann direkt einer Variable übergeben?? zB an uint8_t var; var = accessConfig(); ?? Weil es nehme ich an, ein 1Byte Array ist, also Size=1 nehme ich an. Wenn ja, dann habe ich das jetzt nicht nur zu 99.9 % verstanden, sondern 100.
1 | uint8_t accessConfig(void) |
2 | {
|
3 | uint8_t txData; // sending dataarray for access_config command |
4 | static uint8_t rxData; // receiving dataarray for access_config command |
5 | // static because of variable rxData validity only within the function
|
6 | txData = ACCESS_CONFIG; |
7 | |
8 | |
9 | HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, &txData, sizeof(txData), 10); // Shift is necessary because of i2C function description |
10 | HAL_I2C_Master_Receive(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, &rxData, sizeof(rxData), 10); // Shift is necessary because of i2C function description |
11 | return rxData; |
12 | }
|
Harry L. schrieb: > Solltest du dringend mal lesen! > http://cs.indstate.edu/~cbasavaraj/cs559/the_c_pro... Ich klicke unbekannte Links an (Virengefahr). :P Was ist das?
mark schrieb: > Harry L. schrieb: >> Solltest du dringend mal lesen! >> http://cs.indstate.edu/~cbasavaraj/cs559/the_c_pro... > > Ich klicke unbekannte Links an (Virengefahr). :P > Was ist das? Der Link zu einem PDF Das WWW basiert auf Links, und, wenn du hinter jedem Link etwas bösartiges vermutest, solltest du lieber nur lokal und ohne jede Verbindung zur Aussenwelt leben. Wenn dir "gefühlte Sicherheit" so ungeheuer wichtig ist, nutz doch Linux! Merke: der effektivste aller Viren-Scanner, der bei jeden "gratis" und "kostenlos" Alarm schlagen sollte, sitzt zwischen deine 2 Ohren ;) Ohne den gesunden Menschenverstand, bist du jedoch mit jedem OS nur ein "Opfer"
:
Bearbeitet durch User
Harry L. schrieb: > mark schrieb: >> Harry L. schrieb: >>> Solltest du dringend mal lesen! >>> http://cs.indstate.edu/~cbasavaraj/cs559/the_c_pro... >> >> Ich klicke unbekannte Links an (Virengefahr). :P >> Was ist das? > > Der Link zu einem PDF > > ....und wenn du so große Angst vor Viren hast (die dich blockiert) > solltest du dringend einen Wechsel von Windows zu Linux überdenken. > > Merke: der effektivste aller Viren-Scanner, der bei jeden "gratis" und > "kostenlos" Alarm schlagen sollte, sitzt zwischen deine 2 Ohren ;) Scheiss auf Linux ;P wegen so ner Frage schickst du mir sowas? Das Ding hat ja 500 000 Seiten.. und trockenes English
Wenn du nicht in der Lage bist, sowas zu verstehen, empfehle ich dir, dir nen anderes Hobby zu suchen. Für Digitaltechnik und Mikrocontroller scheint es dir an den erforderlichen Voraussetzungen zu mangeln.
:
Bearbeitet durch User
Harry L. schrieb: > Wenn du nicht in der Lage bist, sowas zu verstehen, empfehle ich > dir, > dir nen anderes Hobby zu suchen. > > Für Digitaltechnik und Mikrocontroller scheint es dir an den > erforderlichen Voraussetzungen zu mangeln. ok, weil du es sagst, höre ich gleich morgen damit auf. Aber davor mache ich noch meine Uebung fertig ;)
Harry L. schrieb: > Wenn du nicht in der Lage bist, sowas zu verstehen, empfehle ich > dir, > dir nen anderes Hobby zu suchen. > > Für Digitaltechnik und Mikrocontroller scheint es dir an den > erforderlichen Voraussetzungen zu mangeln. Ein letztes Wort: Einen Tipp habe ich für dich auch noch. Wenn du kein Spass verstehst, dann bleib lieber zu Hause. Und ja manchmal frage ich mich selbst, ob ich zu kompliziert denke und sehe es sogar ein. Aber zum Glück gibt es so Leute, wie Joe F. oder DirkB, die Dinge, die ich zB und womöglich viele andere irgendwie tief im Inneren zwar wissen, zumindest annähernd, es aber doch noch nicht so ganz begriffen oder vielleicht Teile davon vergessen haben, trotzdem sehr gut erklären, ohne die Leute versuchen klein zu reden. Wie es aber aussieht, scheint es dir aber wiederum dafür an den erforderlichen Voraussetzungen zu mangeln zu erkennen, dass man für gewisse Fragen nicht ein ganzes 258 seitiges Buch lesen muss, um die Lösung für das Problem zu finden und voran zu kommen und nicht jeder ein kompletter Idiot ist, wenn er vllt. auch mal etwas "blödere" Fragen stellt. Aber ja, da bist du sicher anderer Meinung. Gute Nacht..
Joe F. schrieb: > pData ist ein array, und du übergibst der funktion einen Pointer > auf das > erste Arrayelemnt. > > uint8_t pData[20]; > -> funtionsaufruf > > MSB steht dann in pData[0], LSB in pData[1]. > > Danach kannst du MSB auf int8 casten, wenn dich das Vorzeichen > interessiert. > > int8_t temp_msb = (int8_t)pData[0]; So, die Fkt. ist zwar noch nicht ganz fertig, aber ich denke, so müsste es klappen.
1 | uint8_t readTemperature(TEMP_RES res) |
2 | {
|
3 | uint8_t txData = READ_TEMPERATURE; // sending dataarray for access_config command |
4 | uint8_t rxData[2]; |
5 | uint8_t *p_rxDataH; // pointer for MSB Byte |
6 | uint8_t *p_rxDataL; // pointer for MSB Byte |
7 | |
8 | struct Array |
9 | {
|
10 | int8_t HByte; |
11 | uint8_t LByte; |
12 | };
|
13 | |
14 | struct Array ByteArray; |
15 | |
16 | HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, &txData, sizeof(txData), 10); // Shift is necessary because of i2C function description |
17 | HAL_I2C_Master_Receive(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, rxData, sizeof(rxData), 10); // Shift is necessary because of i2C function description |
18 | |
19 | p_rxDataH = rxData; |
20 | p_rxDataL = p_rxDataH++; |
21 | |
22 | ByteArray.HByte = (int8_t) *p_rxDataH; // must be casted from uint8_t to int8_t |
23 | ByteArray.LByte = *p_rxDataH; // must not be casted, because always positive |
24 | }
|
mark schrieb: > aber ich denke, so müsste > es klappen. Könnte so klappen, ist aber unnötig kompliziert. Es spricht nichts dagegen die Größe der Buffer für den I2C Transfer größer zu machen, als sie für eine individuelle Transaktion benötigt wird. Evtl. gibt es noch andere I2C Slaves, und dann kann man die Buffer wiederverwenden. Vorschlag:
1 | uint8_t txDataBuf[10]; |
2 | uint8_t rxDataBuf[10]; |
3 | |
4 | uint8_t readTemperature(TEMP_RES res) |
5 | {
|
6 | struct
|
7 | {
|
8 | int8_t HByte; |
9 | uint8_t LByte; |
10 | } ByteArray; |
11 | |
12 | txDataBuf[0] = READ_TEMPERATURE; |
13 | |
14 | HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, txDataBuf, 1, 10); |
15 | HAL_I2C_Master_Receive (&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, rxDataBuf, 2, 10); |
16 | |
17 | ByteArray.HByte = (int8_t)rxDataBuf[0]; // der explizite cast auf int8_t ist hier eigentlich überflüssig, da ByteArray.HByte schon als int8_t definiert ist, aber schaden kann es nicht |
18 | ByteArray.LByte = rxDataBuf[1]; |
19 | |
20 | // ...
|
21 | }
|
Wofür ist eigentlich das Argument "TEMP_RES res" in dieser Funktion? Als Minimalist oder wenn einem das umkopieren der 3 Bytes zu zeitkritisch ist, kann man es auch so machen:
1 | uint8_t readTemperature(TEMP_RES res) |
2 | {
|
3 | uint8_t cmd = READ_TEMPERATURE; |
4 | struct
|
5 | {
|
6 | int8_t HByte; |
7 | uint8_t LByte; |
8 | } ByteArray; |
9 | |
10 | HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, &cmd, 1, 10); |
11 | HAL_I2C_Master_Receive (&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, (uint8_t *)&ByteArray, 2, 10); |
12 | |
13 | // ...
|
14 | }
|
Ich finde den ersten Code aber lesbarer.
:
Bearbeitet durch User
Joe F. schrieb: > mark schrieb: >> aber ich denke, so müsste >> es klappen. > > Könnte so klappen, ist aber unnötig kompliziert. > Es spricht nichts dagegen die Größe der Buffer für den I2C Transfer > größer zu machen, als sie für eine individuelle Transaktion benötigt > wird. > Evtl. gibt es noch andere I2C Slaves, und dann kann man die Buffer > wiederverwenden. > > Vorschlag:uint8_t txDataBuf[10]; > uint8_t rxDataBuf[10]; > > uint8_t readTemperature(TEMP_RES res) > { > struct > { > int8_t HByte; > uint8_t LByte; > } ByteArray; > > txDataBuf[0] = READ_TEMPERATURE; > > HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, > txDataBuf, 1, 10); > HAL_I2C_Master_Receive (&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, > rxDataBuf, 2, 10); > > ByteArray.HByte = (int8_t)rxDataBuf[0]; // der explizite cast auf > int8_t ist hier eigentlich überflüssig, da ByteArray.HByte schon als > int8_t definiert ist, aber schaden kann es nicht > ByteArray.LByte = rxDataBuf[1]; > > // ... > } > > Wofür ist eigentlich das Argument "TEMP_RES res" in dieser Funktion? > > Als Minimalist oder wenn einem das umkopieren der 3 Bytes zu > zeitkritisch ist, kann man es auch so machen:uint8_t > readTemperature(TEMP_RES res) > { > uint8_t cmd = READ_TEMPERATURE; > struct > { > int8_t HByte; > uint8_t LByte; > } ByteArray; > > HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, > &cmd, 1, 10); > HAL_I2C_Master_Receive (&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, > (uint8_t *)&ByteArray, 2, 10); > > // ... > } > > Ich finde den ersten Code aber lesbarer. Ok, vielen Dank. Ich habe jetzt noch nicht alle Optimierungen von dir drinnen, aber soweit sieht es mal so wie unten aus. Jedoch habe ich ein paar Fragen, wenn auch manche wieder einmal c-technisch sind. Also, so wie ich das verstehe ist, dass der Wert rxDataBuf bei deiner ersten Version in der Receive-Fkt ein vom Typ uint8_t. Von daher muss der Cast meiner Meinung nach schon stattfinden, weil ja im struct HByte vom Typ int8_t ist. Oder?? Warum muss ich eigentlich, wenn ich anstatt dem struct-Namen oben, unten die Listenbezeichnung angebe, kein Speicher alloziieren indem ich struct Name Variable; schreibe? Was ist der Vorteil so wie du es gemacht hast. Dass ich eben nicht extra eine Variable definieren muss? Du castest ja den struct ByteArray, wenn du diesen direkt der Receive-Fkt. übergibst, zu einem Pointer. Kann man einen struct eigentlich nicht als pointer definieren? Oder geht das nur für dessen einzelnen Elemente? TEMP_RES res ist die wählbare resolution der Temperatur. Hier der Code: (Er ist soweit fertig, nach der Optimierung werde ich ihn öffentlich zugänglich machen). Dann gibt es für den DS1621 auch etwas in der STM32 Variante und nicht nur AVR. Ich habe mal versucht so viele Funktionen zusammenzufassen wie nur geht und den Code klein zu halten. Wäre gut, wenn Profis noch drüber schauen könnten, bevor ihn alle anderen kopieren. c-file
1 | #include "TempSensorDriver.h" |
2 | |
3 | |
4 | /******************************************************************************
|
5 | ** Constants, macros and type definitions **
|
6 | ******************************************************************************/
|
7 | |
8 | /******************************************************************************
|
9 | ** Variables **
|
10 | ******************************************************************************/
|
11 | |
12 | extern I2C_HandleTypeDef hi2c1; |
13 | |
14 | /******************************************************************************
|
15 | ** Functions **
|
16 | ******************************************************************************/
|
17 | |
18 | /**
|
19 | * @brief ReadCommand(uint8_t command) gets all desired values of the
|
20 | TempSensor which should be read (only 1Byte values)
|
21 | * @param It uses the parameter command
|
22 | command could be ACCESS_TH, ACCESS_TL, ACCESS_CONFIG
|
23 | READ_COUNTER or READ_SLOPE
|
24 | */
|
25 | |
26 | uint8_t ReadCommand(uint8_t command) |
27 | {
|
28 | uint8_t txData; // sending dataarray for access_config command |
29 | static uint8_t rxData; // receiving dataarray for access_config command |
30 | // static because of variable rxData validity only within the function
|
31 | txData = command; |
32 | |
33 | HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, &txData, sizeof(txData), 10); // Shift is necessary because of i2C function description |
34 | HAL_I2C_Master_Receive(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, &rxData, sizeof(rxData), 10); // Shift is necessary because of i2C function description |
35 | return rxData; |
36 | }
|
37 | |
38 | /**
|
39 | * @brief WriteCommand(uint8_t command) gets all desired values of the
|
40 | TempSensor which should be read (only 1Byte values)
|
41 | * @param It uses the parameter command
|
42 | command could be ACCESS_TH, ACCESS_TL, ACCESS_CONFIG, START_CONVERT_T
|
43 | or STOP_CONVERT_T
|
44 | */
|
45 | |
46 | void WriteCommand(uint8_t command) |
47 | {
|
48 | uint8_t txData = command; // sending dataarray for access_config command |
49 | |
50 | HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, &txData, sizeof(txData), 10); // Shift is necessary because of i2C function description |
51 | }
|
52 | |
53 | /**
|
54 | * @brief init_TempSensor(TEMP_CONV mode, POLARITY pol) intializes the TempSensor
|
55 | * @param takes the Conversion Mode mode out of the enum Temperature_conversion
|
56 | * and the polartiy out of enum OutputPolarity POLARITY
|
57 | * mode could be CONTINUOUS_MODE or ONE_SHOT_MODE
|
58 | * pol could be ACTIVE_LOW, ACTIVE_HIGH or NONE if not used
|
59 | */
|
60 | |
61 | void init_TempSensor(TEMP_CONV mode, OUT_POL pol) |
62 | {
|
63 | // variables
|
64 | uint8_t txData; |
65 | |
66 | txData = ReadCommand(ACCESS_CONFIG); |
67 | |
68 | txData &= ~( 1<<ONE_SHOT | 1<<POL); // delete bits generally |
69 | txData |= (mode<<ONE_SHOT | pol<<POL); // set Bits according to mode and pol |
70 | |
71 | //_delay_ms(12); // wait for at least 10ms - better 12ms for config process
|
72 | |
73 | HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, &txData, sizeof(txData), 10); |
74 | }
|
75 | |
76 | /**
|
77 | * @brief readTemperature(TEMP_RES res) reads the converted temperature of the sensor
|
78 | * @param takes temperature resolution res out of TempResolution TEMP_RES
|
79 | * resolution res could be HALF_DEGREE, FULL_DEGREE, HIGH_RESOLUTION
|
80 | * pol could be ACTIVE_LOW, ACTIVE_HIGH or NONE if not used
|
81 | */
|
82 | |
83 | double readTemperature(TEMP_RES res) |
84 | {
|
85 | uint8_t txData = READ_TEMPERATURE; // sending dataarray for access_config command |
86 | uint8_t rxData[2]; |
87 | static double Degrees; |
88 | |
89 | struct
|
90 | {
|
91 | int8_t HByte; |
92 | uint8_t LByte; |
93 | }ByteArray; |
94 | |
95 | HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, &txData, sizeof(txData), 10); // Shift is necessary because of i2C function description |
96 | HAL_I2C_Master_Receive(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, (uint8_t*)&ByteArray, sizeof(rxData), 10); // Shift is necessary because of i2C function description |
97 | |
98 | uint8_t slope = ReadCommand(READ_SLOPE); |
99 | uint8_t counter = ReadCommand(READ_COUNTER); |
100 | |
101 | switch(res) |
102 | {
|
103 | case 0: // HALFDEGREE mode |
104 | if((ByteArray.LByte != 0) & (ByteArray.HByte < 0) ) |
105 | {
|
106 | Degrees = ByteArray.HByte - 0.5; |
107 | }else if((ByteArray.LByte != 0) & (ByteArray.HByte > 0) ) |
108 | {
|
109 | Degrees = ByteArray.HByte + 0.5; |
110 | }else |
111 | {
|
112 | Degrees = ByteArray.HByte + 0.0; |
113 | }
|
114 | break; |
115 | |
116 | case 1: // ONEDEGREE mode |
117 | Degrees = ByteArray.HByte; |
118 | break; |
119 | |
120 | case 2: // HIGHRESOLUTION mode |
121 | Degrees = ByteArray.HByte-0.25+((slope-counter)/slope); |
122 | break; |
123 | }
|
124 | |
125 | return Degrees; |
126 | }
|
127 | |
128 | /**
|
129 | * @brief checks the bits in the config Register of the TempSensor
|
130 | * @param takes the configBit out of the config Register CONV_REG
|
131 | * configBit could be ONE_SHOT, POL, NVB, TLF, THF or DONE
|
132 | */
|
133 | |
134 | bool checkConfigRegisterFlag(CONV_REG configBit) |
135 | {
|
136 | return ((ReadCommand(ACCESS_CONFIG) & (1 << configBit)) != 0); |
137 | }
|
h-file
1 | #ifndef TEMPSENSORDRIVER_H_
|
2 | #define TEMPSENSORDRIVER_H_
|
3 | |
4 | #include "stm32l4xx_hal.h" |
5 | #include "stdbool.h" |
6 | |
7 | /******************************************************************************
|
8 | ** Constants, macros and type definitions **
|
9 | ******************************************************************************/
|
10 | |
11 | /* Commands to the TempSensor - Read or Write*/
|
12 | #define TEMP_SENSOR_ADRESS_7_BIT 0x48
|
13 | |
14 | #define READ_TEMPERATURE 0xAA
|
15 | #define ACCESS_TH 0xA1
|
16 | #define ACCESS_TL 0xA2
|
17 | #define ACCESS_CONFIG 0xAC
|
18 | #define READ_COUNTER 0xA8
|
19 | #define READ_SLOPE 0xA9
|
20 | #define START_CONVERT_T 0xEE
|
21 | #define STOP_CONVERT_T 0x22
|
22 | /* End of Commands to the TempSensor - Read or Write*/
|
23 | |
24 | #define SHIFT 0x01
|
25 | |
26 | |
27 | // enum definitions
|
28 | enum Temperature_conversion |
29 | {
|
30 | CONTINUOUS_MODE, |
31 | ONE_SHOT_MODE
|
32 | };
|
33 | |
34 | enum OutputPolarity |
35 | {
|
36 | ACTIVE_LOW, |
37 | ACTIVE_HIGH, |
38 | NONE
|
39 | };
|
40 | |
41 | enum ConfigRegister |
42 | {
|
43 | ONE_SHOT, |
44 | POL, |
45 | NVB = 4U, |
46 | TLF, |
47 | THF, |
48 | DONE
|
49 | };
|
50 | |
51 | enum TempResolution |
52 | {
|
53 | HALF_DEGREE, |
54 | FULL_DEGREE, |
55 | HIGH_RESOLUTION
|
56 | };
|
57 | |
58 | |
59 | // typedefs
|
60 | typedef enum Temperature_conversion TEMP_CONV; |
61 | typedef enum OutputPolarity OUT_POL; |
62 | typedef enum ConfigRegister CONV_REG; |
63 | typedef enum TempResolution TEMP_RES; |
64 | |
65 | /******************************************************************************
|
66 | ** Variables **
|
67 | ******************************************************************************/
|
68 | |
69 | /******************************************************************************
|
70 | ** Functions **
|
71 | ******************************************************************************/
|
72 | |
73 | uint8_t ReadCommand(uint8_t command); |
74 | void WriteCommand(uint8_t command); |
75 | void init_TempSensor(TEMP_CONV mode, OUT_POL pol); |
76 | double readTemperature(TEMP_RES res); |
77 | |
78 | // proofing flag functions
|
79 | bool checkConfigRegisterFlag(CONV_REG configBit); |
80 | |
81 | |
82 | |
83 | #endif // TEMPSENSORDRIVER_H_
|
die Fkt. von readTemperature ist noch ein wenig lang. Die restlichen Optimierungen nehme ich morgen noch vor. Dann sollte es soweit passen.
1 | #include "TempSensorDriver.h" |
2 | |
3 | |
4 | /******************************************************************************
|
5 | ** Constants, macros and type definitions **
|
6 | ******************************************************************************/
|
7 | |
8 | /******************************************************************************
|
9 | ** Variables **
|
10 | ******************************************************************************/
|
11 | |
12 | extern I2C_HandleTypeDef hi2c1; |
13 | |
14 | /******************************************************************************
|
15 | ** Functions **
|
16 | ******************************************************************************/
|
17 | |
18 | /**
|
19 | * @brief ReadCommand(uint8_t command) gets all desired values of the
|
20 | TempSensor which should be read (only 1Byte values)
|
21 | * @param It uses the parameter command
|
22 | command could be ACCESS_TH, ACCESS_TL, ACCESS_CONFIG
|
23 | READ_COUNTER or READ_SLOPE
|
24 | */
|
25 | |
26 | uint8_t ReadCommand(uint8_t command) |
27 | {
|
28 | uint8_t txData; // sending dataarray for access_config command |
29 | static uint8_t rxData; // receiving dataarray for access_config command |
30 | // static because of variable rxData validity only within the function
|
31 | txData = command; |
32 | |
33 | HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, &txData, sizeof(txData), 10); // Shift is necessary because of i2C function description |
34 | HAL_I2C_Master_Receive(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, &rxData, sizeof(rxData), 10); // Shift is necessary because of i2C function description |
35 | return rxData; |
36 | }
|
37 | |
38 | /**
|
39 | * @brief WriteCommand(uint8_t command) writes all desired values of the
|
40 | TempSensor which should be read (only 1Byte values)
|
41 | * @param It uses the parameter command
|
42 | command could be ACCESS_TH, ACCESS_TL, ACCESS_CONFIG, START_CONVERT_T
|
43 | or STOP_CONVERT_T
|
44 | */
|
45 | |
46 | void WriteCommand(uint8_t command) |
47 | {
|
48 | uint8_t txData = command; // sending dataarray for access_config command |
49 | |
50 | HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, &txData, sizeof(txData), 10); // Shift is necessary because of i2C function description |
51 | }
|
52 | |
53 | /**
|
54 | * @brief init_TempSensor(TEMP_CONV mode, POLARITY pol) intializes the TempSensor
|
55 | * @param takes the Conversion Mode mode out of the enum Temperature_conversion
|
56 | * and the polartiy out of enum OutputPolarity POLARITY
|
57 | * mode could be CONTINUOUS_MODE or ONE_SHOT_MODE
|
58 | * pol could be ACTIVE_LOW, ACTIVE_HIGH or NONE if not used
|
59 | */
|
60 | |
61 | void init_TempSensor(TEMP_CONV mode, OUT_POL pol) |
62 | {
|
63 | // variables
|
64 | uint8_t txData; |
65 | |
66 | txData = ReadCommand(ACCESS_CONFIG); |
67 | |
68 | txData &= ~( 1<<ONE_SHOT | 1<<POL); // delete bits generally |
69 | txData |= (mode<<ONE_SHOT | pol<<POL); // set Bits according to mode and pol |
70 | |
71 | while(!checkConfigRegisterFlag(NVB)); // wait until EEPROM is written |
72 | |
73 | HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, &txData, sizeof(txData), 10); |
74 | }
|
75 | |
76 | /**
|
77 | * @brief readTemperature(TEMP_RES res) reads the converted temperature of the sensor
|
78 | * @param takes temperature resolution res out of TempResolution TEMP_RES
|
79 | * resolution res could be HALF_DEGREE, FULL_DEGREE, HIGH_RESOLUTION
|
80 | */
|
81 | |
82 | double readTemperature(TEMP_RES res) |
83 | {
|
84 | uint8_t txData = READ_TEMPERATURE; // sending dataarray for access_config command |
85 | uint8_t rxData[2]; |
86 | static double Degrees; |
87 | |
88 | struct
|
89 | {
|
90 | int8_t HByte; |
91 | uint8_t LByte; |
92 | }ByteArray; |
93 | |
94 | HAL_I2C_Master_Transmit(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, &txData, sizeof(txData), 10); // Shift is necessary because of i2C function description |
95 | HAL_I2C_Master_Receive(&hi2c1, TEMP_SENSOR_ADRESS_7_BIT << SHIFT, (uint8_t*)&ByteArray, sizeof(rxData), 10); // Shift is necessary because of i2C function description |
96 | |
97 | uint8_t slope = ReadCommand(READ_SLOPE); |
98 | uint8_t counter = ReadCommand(READ_COUNTER); |
99 | |
100 | switch(res) |
101 | {
|
102 | case 0: // HALFDEGREE mode |
103 | if((ByteArray.LByte != 0) & (ByteArray.HByte < 0) ) |
104 | {
|
105 | Degrees = ByteArray.HByte - 0.5; |
106 | }else if((ByteArray.LByte != 0) & (ByteArray.HByte > 0) ) |
107 | {
|
108 | Degrees = ByteArray.HByte + 0.5; |
109 | }else |
110 | {
|
111 | Degrees = ByteArray.HByte + 0.0; |
112 | }
|
113 | break; |
114 | |
115 | case 1: // ONEDEGREE mode |
116 | Degrees = ByteArray.HByte; |
117 | break; |
118 | |
119 | case 2: // HIGHRESOLUTION mode |
120 | Degrees = ByteArray.HByte-0.25+((slope-counter)/slope); |
121 | break; |
122 | }
|
123 | |
124 | return Degrees; |
125 | }
|
126 | |
127 | /**
|
128 | * @brief checks the bits in the config Register of the TempSensor
|
129 | * @param takes the configBit out of the config Register CONV_REG
|
130 | * configBit could be ONE_SHOT, POL, NVB, TLF, THF or DONE
|
131 | */
|
132 | |
133 | bool checkConfigRegisterFlag(CONV_REG configBit) |
134 | {
|
135 | return ((ReadCommand(ACCESS_CONFIG) & (1 << configBit)) != 0); |
136 | }
|
ohh mann ist schon später sorry, war zu schnell ich habe noch die zeile mit dem delay von 12ms in der fkt. init_TempSensor ersetzt durch das Prüfen des NVB flags.. so nun gute Nacht
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.