Forum: Mikrocontroller und Digitale Elektronik I2C Problem bei DK LM3S9b96 TI Cortex M3


von Alex (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,


ich habe ein Problem bei einem ARM Projekt. Für eine Belegarbeit soll 
eine Wetterstation programmiert werden. Dazu kommt ein DK LM3S9B96 mit 
einem MPL3115A2 und einen resitiven Feuchtesensor zum Einsatz. 
Zusätzlich werden über ein LCD die aktuellen Werte ausgegeben und die 
Werte jeder Stunde sind über Webinterface abrufbar. Programmiert wird in 
c im CodeComposerStudio 5.1.

Unser Program basiert auf einem Beispiel der Stellaris Libs io_net. Aus 
diesem Grund sind da noch Funktionen drin, die wir nicht selber 
geschrieben haben.

Nun zum Problem:

Der MPL3115A2 wird über I²C konfiguriert und ausgelesen. Dies geschieht 
einmal pro Sekunde. Die Messung wird über ein Timerinterrupt ausgelöst.

In der Main-Funktion wird die I2C Masterbaugruppe und die Peripherie 
konfiguriert.
1
 
2
    // Enable the I²C-Master Block on the MCU
3
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
4
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
5
    GPIOPinConfigure(GPIO_PA6_I2C1SCL);
6
    GPIOPinConfigure(GPIO_PA7_I2C1SDA);
7
    GPIOPinTypeI2C(GPIO_PORTA_BASE,0xC0);
8
9
    // Initialize the I²C Master (I²C1m 50MHz, 100kbit);
10
    I2CMasterInitExpClk(I2C1_MASTER_BASE, SysCtlClockGet(), false);
11
    I2CMasterEnable(I2C1_MASTER_BASE);



Die Funktion, die nun die Messung im Sensor anstößt und die Daten abruft 
sieht wie folgendermaßen aus:

1
        struct SensorData ReadI2C(void){
2
  struct SensorData I2C_data;
3
  I2C_data.Temperature = 0.0;
4
  I2C_data.Pressure = 0.0;
5
  unsigned long ulTemp_MSB=0;
6
  int ulTemp_LSB=0;
7
  unsigned long ulPres_MSB=0;
8
9
  unsigned long ulPres_CSB=0;
10
11
  unsigned long ulPres_LSB=0;
12
13
        unsigned int iFracPres=0;
14
15
  int i=0;
16
17
  //init measurement
18
19
  while(I2CMasterBusy(I2C1_MASTER_BASE) ||  I2CMasterBusBusy(I2C1_MASTER_BASE)){
20
  };
21
  I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, 0x60, false);
22
  I2CMasterDataPut(I2C1_MASTER_BASE,0x26);
23
  I2CMasterControl(I2C1_MASTER_BASE,I2C_MASTER_CMD_BURST_SEND_START);
24
  while(I2CMasterBusy(I2C1_MASTER_BASE))
25
  {
26
  };
27
  I2CMasterDataPut(I2C1_MASTER_BASE,0x02);
28
  I2CMasterControl(I2C1_MASTER_BASE,I2C_MASTER_CMD_SINGLE_SEND);
29
30
31
  //configure data ready event
32
33
  while(I2CMasterBusy(I2C1_MASTER_BASE) || I2CMasterBusBusy(I2C1_MASTER_BASE)){
34
  };
35
  I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, 0x60, false);
36
  I2CMasterDataPut(I2C1_MASTER_BASE,0x13);
37
  I2CMasterControl(I2C1_MASTER_BASE,I2C_MASTER_CMD_BURST_SEND_START);
38
  while(I2CMasterBusy(I2C1_MASTER_BASE))
39
  {
40
  };
41
  I2CMasterDataPut(I2C1_MASTER_BASE,0x07);
42
  I2CMasterControl(I2C1_MASTER_BASE,I2C_MASTER_CMD_SINGLE_SEND);
43
44
45
  //set ship active
46
47
  while(I2CMasterBusy(I2C1_MASTER_BASE) || I2CMasterBusBusy(I2C1_MASTER_BASE)){
48
    };
49
  I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, 0x60, false);
50
  I2CMasterDataPut(I2C1_MASTER_BASE,0x26);
51
  I2CMasterControl(I2C1_MASTER_BASE,I2C_MASTER_CMD_BURST_SEND_START);
52
  while(I2CMasterBusy(I2C1_MASTER_BASE))
53
    {
54
    };
55
  I2CMasterDataPut(I2C1_MASTER_BASE,0x03);
56
  I2CMasterControl(I2C1_MASTER_BASE,I2C_MASTER_CMD_SINGLE_SEND);
57
58
  //poll data for temp
59
  while(I2CMasterBusy(I2C1_MASTER_BASE) || I2CMasterBusBusy(I2C1_MASTER_BASE))
60
  {
61
  };
62
63
    I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, 0x60, false);
64
    I2CMasterDataPut(I2C1_MASTER_BASE,0x04);
65
    I2CMasterControl(I2C1_MASTER_BASE,I2C_MASTER_CMD_BURST_SEND_START);
66
    while(I2CMasterBusy(I2C1_MASTER_BASE))
67
  {
68
  };
69
    I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, 0x60, true);
70
    I2CMasterControl(I2C1_MASTER_BASE,I2C_MASTER_CMD_SINGLE_RECEIVE);
71
    while(I2CMasterBusy(I2C1_MASTER_BASE))
72
  {
73
  };
74
    ulTemp_MSB=I2CMasterDataGet(I2C1_MASTER_BASE);
75
76
    while(I2CMasterBusy(I2C1_MASTER_BASE) || I2CMasterBusBusy(I2C1_MASTER_BASE))
77
    {
78
    };
79
80
    I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, 0x60, false);
81
    I2CMasterDataPut(I2C1_MASTER_BASE,0x05);
82
    I2CMasterControl(I2C1_MASTER_BASE,I2C_MASTER_CMD_BURST_SEND_START);
83
    while(I2CMasterBusy(I2C1_MASTER_BASE))
84
    {
85
    };
86
    I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, 0x60, true);
87
    I2CMasterControl(I2C1_MASTER_BASE,I2C_MASTER_CMD_SINGLE_RECEIVE);
88
    while(I2CMasterBusy(I2C1_MASTER_BASE))
89
    {
90
    };
91
    ulTemp_LSB=I2CMasterDataGet(I2C1_MASTER_BASE);
92
93
94
95
    I2C_data.Temperature =  ulTemp_MSB +  ((float)ulTemp_LSB)/1000;
96
97
98
    //poll data for pressure
99
    while(I2CMasterBusy(I2C1_MASTER_BASE) || I2CMasterBusBusy(I2C1_MASTER_BASE))
100
    {
101
    };
102
103
    I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, 0x60, false);
104
    I2CMasterDataPut(I2C1_MASTER_BASE,0x01);
105
    I2CMasterControl(I2C1_MASTER_BASE,I2C_MASTER_CMD_BURST_SEND_START);
106
    while(I2CMasterBusy(I2C1_MASTER_BASE))
107
    {
108
    };
109
    I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, 0x60, true);
110
    I2CMasterControl(I2C1_MASTER_BASE,I2C_MASTER_CMD_SINGLE_RECEIVE);
111
    while(I2CMasterBusy(I2C1_MASTER_BASE))
112
    {
113
    };
114
    ulPres_MSB=I2CMasterDataGet(I2C1_MASTER_BASE);
115
116
    ulPres_MSB <<=10;
117
118
    while(I2CMasterBusy(I2C1_MASTER_BASE) || I2CMasterBusBusy(I2C1_MASTER_BASE))
119
    {
120
    };
121
122
    I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, 0x60, false);
123
    I2CMasterDataPut(I2C1_MASTER_BASE,0x02);
124
    I2CMasterControl(I2C1_MASTER_BASE,I2C_MASTER_CMD_BURST_SEND_START);
125
    while(I2CMasterBusy(I2C1_MASTER_BASE))
126
    {
127
    };
128
    I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, 0x60, true);
129
    I2CMasterControl(I2C1_MASTER_BASE,I2C_MASTER_CMD_SINGLE_RECEIVE);
130
    while(I2CMasterBusy(I2C1_MASTER_BASE))
131
    {
132
    };
133
    ulPres_CSB=I2CMasterDataGet(I2C1_MASTER_BASE);
134
    ulPres_CSB<<=2;
135
136
    while(I2CMasterBusy(I2C1_MASTER_BASE) || I2CMasterBusBusy(I2C1_MASTER_BASE))
137
    {
138
    };
139
140
    I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, 0x60, false);
141
    I2CMasterDataPut(I2C1_MASTER_BASE,0x03);
142
    I2CMasterControl(I2C1_MASTER_BASE,I2C_MASTER_CMD_BURST_SEND_START);
143
    while(I2CMasterBusy(I2C1_MASTER_BASE))
144
    {
145
    };
146
    I2CMasterSlaveAddrSet(I2C1_MASTER_BASE, 0x60, true);
147
    I2CMasterControl(I2C1_MASTER_BASE,I2C_MASTER_CMD_SINGLE_RECEIVE);
148
    while(I2CMasterBusy(I2C1_MASTER_BASE))
149
    {
150
    };
151
    ulPres_LSB=I2CMasterDataGet(I2C1_MASTER_BASE);
152
153
154
    iFracPres = ulPres_LSB;
155
    ulPres_LSB>>=5;
156
157
    for(i=0;i<2;i++){
158
      if(i==0){
159
        iFracPres = iFracPres << 11;
160
      }else{
161
        iFracPres = iFracPres >> 15;
162
      }
163
    }
164
    I2C_data.Pressure =  (ulPres_MSB + ulPres_CSB + ulPres_LSB +(float)iFracPres/10.0)/100.0;
165
  return I2C_data;


sry für den langen Code, die Blöcke für Lesen/Schreiben werden noch in 2 
Funktionen zusammengefasst.

Beim Debuggen wird kein Fehler angezeigt, auch die FaultISR wird nicht 
ausgelöst. der µC arbeitet alle I2C-Funktionen ab, aber eine Messung 
findet nicht statt. Wenn wir direkt nach einem Schreibbefehl auf ein 
Register im Sensor dieses wieder auslesen, bekommen wir immer NULL 
zurück. Das lesen von Sensorregister 0x0C (Da steht eine Kennung des 
Sensors drin) bekommen wir C4, das auch richtig ist, also gehen wir 
davon aus, das zumindest das Lesen funktioniert. Schreiben aber nicht. 
Bei weiteren Nachforschungen, haben wir festgestellt, das dsa 
MasterDataRegister immer leer zu sein scheint. Komolinoten von uns haben 
die gleichen Funktionen und abläufe und dort funktioniert es.

Der Master scheint auch zu arbeiten, beim durchsteppen kann man sehen, 
das das Statusregister des I2C1 verändert wird. Bus wird Busy/Idle Slave 
Addresse wird gesetzt, Read/Write bit wird auf gesetzt.


Zur Info, das ganze hat schon funktioniert, am Mittwoch Morgen hab ich 
dann nur die Taktfrequenz des µC von 16MHz auf 50MHz erhöht, damit der 
Webserver keinen Timeout erzeugt. Donnerstag Nachmittag hat es dann 
nicht mehr Funktioniert. Wir haben das Programm auf mehreren Boards 
getestet, bei allen hat es nicht funktioniert.

Nach 8h suche haben wir immernoch keine Ahnung woran es liegen kann. 
Vllt. kann uns hier jemand behilflich sein.

Alex

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.