Forum: Mikrocontroller und Digitale Elektronik CPAL I2C gleicher Code Fehler nach zweiter Ausführung


von Martin L. (martin_la)


Angehängte Dateien:

Lesenswert?

Hi Leute,
ich hoffe, mir kann irgendjemand bei meinem Problem helfen.

Ich versuche ein paar Sensordaten über I²C auszulesen. Ich arbeite mit 
dem stm32 DiscoveryVL, also mit dem stm32f100rb.
Ich nutze die CPAL Bib, welche auch grundsätzlich funktioniert. Ich habe 
mehrere Sensoren, bei denen ich problemlos Daten schreiben und lesen 
kann. Sobald ich aber den selben Code in einer Schleife ausführe, geht 
es nur das erste Mal. Danach geht es nur noch teilweise und beim dritten 
Mal wird die Adresse 0x00 gesendet. Im Bild hab ich diesen verlauf 
aufgezeichnet. Die vier Bilder sind eine Messung, wär nur zu klein 
geworden.

Ich kann mir absolut nicht erklären, wieso das passiert.
Egal welche Idee ihr habt, immer her damit. Ich bekomm sonst noch die 
Macke!!!!!!


Hier ist mein Code:
1
int main() {
2
  uint8_t databuffer[2];
3
  CPAL_TransferTypeDef transfer_test;
4
  
5
  
6
  display_init();
7
  i2c_init();
8
  //motor_init();
9
  
10
  position_sensor_init();
11
  //distance_sensors_init();
12
  //pressure_sensor_init();
13
  
14
  
15
  //set_i2c_device(&position_sensor);
16
  while(1){
17
    //CPAL_I2C_Read(&I2C2_DevStructure);
18
    
19
    CPAL_I2C_Read(set_i2c_device(&position_sensor));
20
    //while(I2C2_DevStructure.CPAL_State!=CPAL_STATE_READY);
21
    //pressure_sensor_init();
22
    /*
23
    to_array(((position_sensor.databuffer[1])<<8)|position_sensor.databuffer[0]);
24
    send_display(1, 1, display_buffer);
25
    to_array(((position_sensor.databuffer[3])<<8)|position_sensor.databuffer[2]);
26
    send_display(2, 1, display_buffer);
27
    to_array(((position_sensor.databuffer[5])<<8)|position_sensor.databuffer[4]);
28
    send_display(3, 1, display_buffer);
29
    */
30
    delay_ms(1);
31
  }
32
  
33
}
1
void position_sensor_init(void){
2
  i2c_device_typedef position_sensor_write;
3
  
4
  position_sensor.transfer_structure.pbBuffer = position_sensor.databuffer;
5
  position_sensor.transfer_structure.wAddr1 = POSITION_SENSOR_ADRESS << 1;
6
  position_sensor.options = 0x00000000;
7
  
8
  position_sensor_write.transfer_structure.pbBuffer = position_sensor_write.databuffer;
9
  position_sensor_write.transfer_structure.wAddr1 = POSITION_SENSOR_ADRESS << 1;
10
  
11
  // Transfer Struktur und Optionen setzen
12
  while(I2C2_DevStructure.CPAL_State!=CPAL_STATE_READY);
13
  I2C2_DevStructure.pCPAL_TransferRx = &position_sensor.transfer_structure;
14
  I2C2_DevStructure.pCPAL_TransferTx = &position_sensor_write.transfer_structure;
15
  I2C2_DevStructure.wCPAL_Options = position_sensor.options;
16
  
17
  
18
  position_sensor_write.transfer_structure.wAddr2 = 0x3D;
19
  position_sensor_write.transfer_structure.wNumData = 1;
20
  position_sensor_write.databuffer[0] = 0x0C;
21
  
22
  
23
  // Zuerst Registerwert auslesen, da sonst andere Werte überschrieben werden
24
  position_sensor.transfer_structure.wAddr2 = 0x3D;
25
  position_sensor.transfer_structure.wNumData = 1;
26
  CPAL_I2C_Read(&I2C2_DevStructure);
27
  
28
  // Operating Mode auf NDOF setzen
29
  position_sensor_write.transfer_structure.wAddr2 = 0x3D;
30
  position_sensor_write.transfer_structure.wNumData = 1;
31
  while(I2C2_DevStructure.CPAL_State!=CPAL_STATE_READY);
32
  position_sensor_write.databuffer[0] = position_sensor.databuffer[0] | 0x0C;
33
  CPAL_I2C_Write(&I2C2_DevStructure);
34
  
35
  // Struktur zum Messdaten auslesen initialisieren
36
  //position_sensor.transfer_structure.wAddr2 = 0x1A;
37
  position_sensor.transfer_structure.wAddr2 = 0x08;
38
  position_sensor.transfer_structure.wNumData = 6;
39
  
40
  // warten, bis NDOF Modus erreicht ist
41
  delay_ms(7);
42
  // warten, bis alle Daten übertagen sind. Struktrur zum schreiben nur lokal -> Gültigkeitsbereich
43
  while(I2C2_DevStructure.CPAL_State!=CPAL_STATE_READY);
44
}

position_sensor ist eine global angelegte Struktur:
1
typedef struct{
2
  CPAL_TransferTypeDef transfer_structure;
3
  uint8_t databuffer[DATABUFFER_SIZE];
4
  uint32_t options;
5
} i2c_device_typedef;


1
CPAL_InitTypeDef* set_i2c_device(i2c_device_typedef* device){
2
  I2C2_DevStructure.pCPAL_TransferRx = &device->transfer_structure;
3
  I2C2_DevStructure.wCPAL_Options = device->options;
4
  return &I2C2_DevStructure;
5
}

von Martin L. (martin_la)


Angehängte Dateien:

Lesenswert?

Ich hab grad festgestellt, wenn ich immer eine neue Struktur anlege 
funktioniert es einwandfrei. (siehe Bild)
Bleibt nur die Frage wieso?????????
Ich habe nämlich keine Lust, unnötig Rechenzeit zu verbraten, weil ich 
jedes Mal ne neue Struktur mit den gleichen Werten initialisieren muss.

Falls jemand ne Idee hat, wie ich das Problem umschiffen kann, immer her 
damit.

1
int main() {
2
  uint8_t databuffer[2];
3
  CPAL_TransferTypeDef transfer_test;
4
  
5
  
6
  display_init();
7
  i2c_init();
8
  //motor_init();
9
  
10
  position_sensor_init();
11
  //distance_sensors_init();
12
  //pressure_sensor_init();
13
  
14
  
15
  //set_i2c_device(&position_sensor);
16
  while(1){
17
    //CPAL_I2C_Read(&I2C2_DevStructure);
18
    i2c_device_typedef position_sensor_test;
19
    
20
    position_sensor_test.transfer_structure.pbBuffer = position_sensor_test.databuffer;
21
    position_sensor_test.transfer_structure.wAddr1 = POSITION_SENSOR_ADRESS << 1;
22
    position_sensor_test.options = 0x00000000;
23
    position_sensor_test.transfer_structure.wAddr2 = 0x08;
24
    position_sensor_test.transfer_structure.wNumData = 6;
25
    
26
    
27
    CPAL_I2C_Read(set_i2c_device(&position_sensor_test));
28
    //while(I2C2_DevStructure.CPAL_State!=CPAL_STATE_READY);
29
    //pressure_sensor_init();
30
    /*
31
    to_array(((position_sensor.databuffer[1])<<8)|position_sensor.databuffer[0]);
32
    send_display(1, 1, display_buffer);
33
    to_array(((position_sensor.databuffer[3])<<8)|position_sensor.databuffer[2]);
34
    send_display(2, 1, display_buffer);
35
    to_array(((position_sensor.databuffer[5])<<8)|position_sensor.databuffer[4]);
36
    send_display(3, 1, display_buffer);
37
    */
38
    //delay_ms(1);
39
    while(I2C2_DevStructure.CPAL_State!=CPAL_STATE_READY);
40
  }
41
  
42
}

von Martin (Gast)


Lesenswert?

Hi Leute.
Hab ganz vergessen, meine Lösung zu posten.

Der Trick ist einfach nur wNumData bei jedem Durchlauf wieder neu zu 
setzen. Diese Variable wird nämlich beim Senden/Empfangen runter gezählt 
bis 0.

Ich hoffe, ich kann dem ein oder anderen damit viel Arbeit ersparen.

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
Noch kein Account? Hier anmelden.