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..
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:
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_taccessConfig(void)
2
{
3
uint8_ttxData;// sending dataarray for access_config command
4
staticuint8_trxData;// 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
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"
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.
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_treadTemperature(TEMP_RESres)
2
{
3
uint8_ttxData=READ_TEMPERATURE;// sending dataarray for access_config command
4
uint8_trxData[2];
5
uint8_t*p_rxDataH;// pointer for MSB Byte
6
uint8_t*p_rxDataL;// pointer for MSB Byte
7
8
structArray
9
{
10
int8_tHByte;
11
uint8_tLByte;
12
};
13
14
structArrayByteArray;
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
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:
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:
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
* @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
doublereadTemperature(TEMP_RESres)
84
{
85
uint8_ttxData=READ_TEMPERATURE;// sending dataarray for access_config command
86
uint8_trxData[2];
87
staticdoubleDegrees;
88
89
struct
90
{
91
int8_tHByte;
92
uint8_tLByte;
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
* @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
doublereadTemperature(TEMP_RESres)
83
{
84
uint8_ttxData=READ_TEMPERATURE;// sending dataarray for access_config command
85
uint8_trxData[2];
86
staticdoubleDegrees;
87
88
struct
89
{
90
int8_tHByte;
91
uint8_tLByte;
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
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