Forum: Mikrocontroller und Digitale Elektronik I2C Kommunitkation funktioniert nicht


von Florian M. (lauch_henne)


Lesenswert?

Hallo liebe Community,

erstmal frohes neues Jahr!
Leider beginnt meines nicht ganz so toll.
Ich möchte einfach nur einen Temperatursensor (DS1621) auslesen. Dabei 
hapert es schon an der Initialisierung der I2C-Peripherie, was mich 
stutzig macht, da in der Headerdatei nur die I2C0-Schnittstelle 
behandelt werden. Aber was ist mit den anderen beiden? Bis hin zum Code, 
über den vielleicht ein Experte hier im Forum mal einen Blick 
drüberwerfen könnte?
An meinem LCD wird immer nur eine 0 angezeigt..
Ich habe zwei 4,7 kOhm Pullups angelötet.


Es geht mir anfangs nur mal darum, dass ich überhaupt Temperaturen 
angezeigt bekomme (keine Nachkommastellen).
Ich hoffe ihr könnt mir da weiterhelfen, wie ich die Peripherie korrekt 
einstelle, und sagen was ich an dem Code noch ändern müsste?!
Ich benutze als IDE: CooCox mit dem ARM-GCC Compiler..
Die Bibliotheken habe ich von keil.

Vielen Dank!!
main.c:
1
/*
2
#include "lpc17xx_timer.h"
3
#include "lpc17xx_clkpwr.h"
4
#include "lc798x.h"
5
#include "lpc17xx.h"  
6
#include "i2c.h"
7
8
//Definition der DS1621 Befehle bzw. Register
9
#define START_CONVERT_TEMP      0xEE   
10
#define READ_TEMPERATURE  0xAA    
11
#define DS1621_ADDR             0x90  //Schreibender Zugriff
12
#define DS1621_Read    0x91   //lesender Zugriff
13
#define PORT_USED 0
14
15
16
extern volatile uint8_t I2CMasterBuffer[I2C_PORT_NUM][BUFSIZE];
17
extern volatile uint8_t I2CSlaveBuffer[I2C_PORT_NUM][BUFSIZE];
18
extern volatile uint32_t I2CReadLength[I2C_PORT_NUM];
19
extern volatile uint32_t I2CWriteLength[I2C_PORT_NUM];
20
21
22
23
int main(void)
24
{
25
 
26
  int byte1;
27
  int byte2;
28
  
29
  int temp;  
30
31
32
33
  TimerInit(0, 1000);  
34
35
  I2C1Init();               //I2C initilisieren auf P0.0 und P0.1
36
  int portused = 1;                                                             
37
  init_lcd();
38
39
40
  
41
  I2CWriteLength[PORT_USED] = 2;      
42
  I2CReadLength[PORT_USED] = 0;      
43
  I2CMasterBuffer[PORT_USED][0] = DS1621_ADDR;  
44
  I2CMasterBuffer[PORT_USED][1] = START_CONVERT_TEMP;
45
  //I2CMasterBuffer[PORT_USED][2] = DS1621_ADDR | RD_BIT; //Nötig?
46
  I2CEngine(PORT_USED);
47
  delayMs(0,1000);
48
  
49
  while(1)  
50
 {
51
52
    delayMs(0,1000);
53
  I2CWriteLength[PORT_USED] = 1;
54
  I2CReadLength[PORT_USED]= 2;    //nämlich die zwei Slave Buffers?!
55
  I2CMasterBuffer[PORT_USED][0] = DS1621_ADDR;
56
  I2CMasterBuffer[PORT_USED][1] = READ_TEMPERATURE;
57
  I2CMasterBuffer[PORT_USED][2] = DS1621_Read;
58
  I2CEngine(PORT_USED);
59
60
  byte1 = I2CSlaveBuffer[0][0];      //MSB                        
61
  byte2 = I2CSlaveBuffer[1][1];      //LSB
62
63
      //var = ...; Hier sollen die Bytes konvertiert weden  
64
      temp = var...;
65
    
66
    printf("Grad in Celsius: %d",temp);
67
            delayMs(0,500);
68
69
  }
70
}

i2c.h:
1
#ifndef __I2C_H 
2
#define __I2C_H
3
4
/* If I2C SEEPROM is tested, make sure FAST_MODE_PLUS is 0.
5
For board to board test, this flag can be turned on. */
6
7
#define FAST_MODE_PLUS      0
8
9
#define I2C_PORT_NUM        3
10
#define BUFSIZE             64
11
#define MAX_TIMEOUT         0x00FFFFFF
12
13
static LPC_I2C_TypeDef (* const LPC_I2C[I2C_PORT_NUM]) = { LPC_I2C0, LPC_I2C1, LPC_I2C2 };
14
15
#define I2CMASTER           0x01
16
#define I2CSLAVE            0x02
17
18
#define PCF8594_ADDR        0x28
19
#define READ_WRITE          0x01
20
21
#define RD_BIT              0x01
22
23
#define I2C_IDLE              0
24
#define I2C_STARTED           1
25
#define I2C_RESTARTED         2
26
#define I2C_REPEATED_START    3
27
#define DATA_ACK              4
28
#define DATA_NACK             5
29
#define I2C_BUSY              6
30
#define I2C_NO_DATA           7
31
#define I2C_NACK_ON_ADDRESS   8
32
#define I2C_NACK_ON_DATA      9
33
#define I2C_ARBITRATION_LOST  10
34
#define I2C_TIME_OUT          11
35
#define I2C_OK                12
36
37
#define I2CONSET_I2EN       (0x1<<6)  /* I2C Control Set Register */
38
#define I2CONSET_AA         (0x1<<2)
39
#define I2CONSET_SI         (0x1<<3)
40
#define I2CONSET_STO        (0x1<<4)
41
#define I2CONSET_STA        (0x1<<5)
42
43
#define I2CONCLR_AAC        (0x1<<2)  /* I2C Control clear Register */
44
#define I2CONCLR_SIC        (0x1<<3)
45
#define I2CONCLR_STAC       (0x1<<5)
46
#define I2CONCLR_I2ENC      (0x1<<6)
47
48
#define I2DAT_I2C      0x00000000  /* I2C Data Reg */
49
#define I2ADR_I2C      0x00000000  /* I2C Slave Address Reg */
50
#define I2SCLH_SCLH      0x00000080  /* I2C SCL Duty Cycle High Reg */
51
#define I2SCLL_SCLL      0x00000080  /* I2C SCL Duty Cycle Low Reg */
52
#define I2SCLH_HS_SCLH    0x00000008  /* Fast Plus I2C SCL Duty Cycle High Reg */
53
#define I2SCLL_HS_SCLL    0x00000008  /* Fast Plus I2C SCL Duty Cycle Low Reg */
54
55
extern void I2C0_IRQHandler( void );
56
extern void I2C1_IRQHandler( void );
57
extern void I2C2_IRQHandler( void );
58
extern void I2C0Init( void );
59
extern void I2C1Init( uint32_t select );
60
extern void I2C2Init( void );
61
extern uint32_t I2CStart( uint32_t portNum );
62
extern uint32_t I2CStop( uint32_t portNum );
63
extern uint32_t I2CEngine( uint32_t portNum );
64
65
extern volatile uint8_t I2CMasterBuffer[I2C_PORT_NUM][BUFSIZE];
66
extern volatile uint8_t I2CSlaveBuffer[I2C_PORT_NUM][BUFSIZE];
67
extern volatile uint32_t I2CReadLength[I2C_PORT_NUM];
68
extern volatile uint32_t I2CWriteLength[I2C_PORT_NUM];
69
70
#endif /* end __I2C_H */


i2c.c
1
 #include "lpc17xx.h"
2
#include "lpc_types.h"
3
#include "i2c.h"
4
5
volatile uint32_t I2CMasterState[I2C_PORT_NUM] = {I2C_IDLE,I2C_IDLE,I2C_IDLE};
6
volatile uint32_t timeout[I2C_PORT_NUM] = {0, 0, 0};
7
8
volatile uint8_t I2CMasterBuffer[I2C_PORT_NUM][BUFSIZE];
9
volatile uint8_t I2CSlaveBuffer[I2C_PORT_NUM][BUFSIZE];
10
volatile uint32_t I2CCount[I2C_PORT_NUM] = {0, 0, 0};
11
volatile uint32_t I2CReadLength[I2C_PORT_NUM];
12
volatile uint32_t I2CWriteLength[I2C_PORT_NUM];
13
14
volatile uint32_t RdIndex0 = 0, RdIndex1 = 0, RdIndex2 = 0;
15
volatile uint32_t WrIndex0 = 0, WrIndex1 = 0, WrIndex2 = 0;
16
17
18
/* 
19
From device to device, the I2C communication protocol may vary, 
20
in the example below, the protocol uses repeated start to read data from or 
21
write to the device:
22
For master read: the sequence is: STA,Addr(W),offset,RE-STA,Addr(r),data...STO 
23
for master write: the sequence is: STA,Addr(W),offset,RE-STA,Addr(w),data...STO
24
Thus, in state 8, the address is always WRITE. in state 10, the address could 
25
be READ or WRITE depending on the I2C command.
26
*/   
27
28
/*****************************************************************************
29
** Function name:    I2C_IRQHandler
30
**
31
** Descriptions:    I2C interrupt handler, deal with master mode only.
32
**
33
** parameters:      None
34
** Returned value:    None
35
** 
36
*****************************************************************************/
37
void I2C0_IRQHandler(void) 
38
{
39
  uint8_t StatValue;
40
41
  timeout[0] = 0;
42
  /* this handler deals with master read and master write only */
43
  StatValue = LPC_I2C0->I2STAT;
44
  switch ( StatValue )
45
  {
46
  case 0x08:      /* A Start condition is issued. */
47
  WrIndex0 = 0;
48
  LPC_I2C0->I2DAT = I2CMasterBuffer[0][WrIndex0++];
49
  LPC_I2C0->I2CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
50
  break;
51
52
  case 0x10:      /* A repeated started is issued */
53
  RdIndex0 = 0;
54
  /* Send SLA with R bit set, */
55
  LPC_I2C0->I2DAT = I2CMasterBuffer[0][WrIndex0++];
56
  LPC_I2C0->I2CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
57
  break;
58
59
  case 0x18:      /* Regardless, it's a ACK */
60
  if ( I2CWriteLength[0] == 1 )
61
  {
62
    LPC_I2C0->I2CONSET = I2CONSET_STO;      /* Set Stop flag */
63
    I2CMasterState[0] = I2C_NO_DATA;
64
  }
65
  else
66
  {
67
    LPC_I2C0->I2DAT = I2CMasterBuffer[0][WrIndex0++];
68
  }
69
  LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
70
  break;
71
72
  case 0x28:  /* Data byte has been transmitted, regardless ACK or NACK */
73
  if ( WrIndex0 < I2CWriteLength[0] )
74
  {
75
    LPC_I2C0->I2DAT = I2CMasterBuffer[0][WrIndex0++]; /* this should be the last one */
76
  }
77
  else
78
  {
79
    if ( I2CReadLength[0] != 0 )
80
    {
81
    LPC_I2C0->I2CONSET = I2CONSET_STA;  /* Set Repeated-start flag */
82
    }
83
    else
84
    {
85
    LPC_I2C0->I2CONSET = I2CONSET_STO;      /* Set Stop flag */
86
    I2CMasterState[0] = I2C_OK;
87
    }
88
  }
89
  LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
90
  break;
91
92
  case 0x30:
93
  LPC_I2C0->I2CONSET = I2CONSET_STO;      /* Set Stop flag */
94
  I2CMasterState[0] = I2C_NACK_ON_DATA;
95
  LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
96
  break;
97
98
  case 0x40:  /* Master Receive, SLA_R has been sent */
99
  if ( (RdIndex0 + 1) < I2CReadLength[0] )
100
  {
101
    /* Will go to State 0x50 */
102
    LPC_I2C0->I2CONSET = I2CONSET_AA;  /* assert ACK after data is received */
103
  }
104
  else
105
  {
106
    /* Will go to State 0x58 */
107
    LPC_I2C0->I2CONCLR = I2CONCLR_AAC;  /* assert NACK after data is received */
108
  }
109
  LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
110
  break;
111
112
  case 0x50:  /* Data byte has been received, regardless following ACK or NACK */
113
  I2CSlaveBuffer[0][RdIndex0++] = LPC_I2C0->I2DAT;
114
  if ( (RdIndex0 + 1) < I2CReadLength[0] )
115
  {
116
    LPC_I2C0->I2CONSET = I2CONSET_AA;  /* assert ACK after data is received */
117
  }
118
  else
119
  {
120
    LPC_I2C0->I2CONCLR = I2CONCLR_AAC;  /* assert NACK on last byte */
121
  }
122
  LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
123
  break;
124
125
  case 0x58:
126
  I2CSlaveBuffer[0][RdIndex0++] = LPC_I2C0->I2DAT;
127
  I2CMasterState[0] = I2C_OK;
128
  LPC_I2C0->I2CONSET = I2CONSET_STO;  /* Set Stop flag */
129
  LPC_I2C0->I2CONCLR = I2CONCLR_SIC;  /* Clear SI flag */
130
  break;
131
132
  case 0x20:    /* regardless, it's a NACK */
133
  case 0x48:
134
  LPC_I2C0->I2CONSET = I2CONSET_STO;      /* Set Stop flag */
135
  I2CMasterState[0] = I2C_NACK_ON_ADDRESS;
136
  LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
137
  break;
138
139
  case 0x38:    /* Arbitration lost, in this example, we don't
140
          deal with multiple master situation */
141
  default:
142
  I2CMasterState[0] = I2C_ARBITRATION_LOST;
143
  LPC_I2C0->I2CONCLR = I2CONCLR_SIC;
144
  break;
145
  }
146
  return;
147
}
148
/*****************************************************************************
149
** Function name:    I2CStart
150
**
151
** Descriptions:    Create I2C start condition, a timeout
152
**        value is set if the I2C never gets started,
153
**        and timed out. It's a fatal error.
154
**
155
** parameters:      None
156
** Returned value:    true or false, return false if timed out
157
** 
158
*****************************************************************************/
159
uint32_t I2CStart( uint32_t portNum )
160
{
161
  uint32_t retVal = FALSE;
162
 
163
  timeout[portNum] = 0;
164
  /*--- Issue a start condition ---*/
165
  LPC_I2C[portNum]->I2CONSET = I2CONSET_STA;  /* Set Start flag */
166
    
167
  /*--- Wait until START transmitted ---*/
168
  while( 1 )
169
  {
170
  if ( I2CMasterState[portNum] == I2C_STARTED )
171
  {
172
    retVal = TRUE;
173
    break;
174
  }
175
  if ( timeout[portNum] >= MAX_TIMEOUT )
176
  {
177
    retVal = FALSE;
178
    break;
179
  }
180
  timeout[portNum]++;
181
  }
182
  return( retVal );
183
}
184
185
/*****************************************************************************
186
** Function name:    I2CStop
187
**
188
** Descriptions:    Set the I2C stop condition, if the routine
189
**        never exit, it's a fatal bus error.
190
**
191
** parameters:      None
192
** Returned value:    true or never return
193
** 
194
*****************************************************************************/
195
uint32_t I2CStop( uint32_t portNum )
196
{
197
  LPC_I2C[portNum]->I2CONSET = I2CONSET_STO;      /* Set Stop flag */
198
  LPC_I2C[portNum]->I2CONCLR = I2CONCLR_SIC;  /* Clear SI flag */
199
            
200
  /*--- Wait for STOP detected ---*/
201
  while( LPC_I2C[portNum]->I2CONSET & I2CONSET_STO );
202
  return TRUE;
203
}
204
205
/*****************************************************************************
206
** Function name:    I2CInit
207
**
208
** Descriptions:    Initialize I2C controller as a master
209
**
210
** parameters:      None
211
** Returned value:    None
212
** 
213
*****************************************************************************/
214
void I2C0Init( void ) 
215
{
216
  LPC_SC->PCONP |= (1 << 7);
217
218
  /* set PIO0.27 and PIO0.28 to I2C0 SDA and SCL */
219
  /* function to 01 on both SDA and SCL. */
220
  LPC_PINCON->PINSEL1 &= ~((0x03<<22)|(0x03<<24));
221
  LPC_PINCON->PINSEL1 |= ((0x01<<22)|(0x01<<24));
222
 
223
  /*--- Clear flags ---*/
224
  LPC_I2C0->I2CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;
225
226
  /*--- Reset registers ---*/
227
#if FAST_MODE_PLUS
228
  LPC_PINCON->I2CPADCFG |= ((0x1<<0)|(0x1<<2));
229
  LPC_I2C0->SCLL   = I2SCLL_HS_SCLL;
230
  LPC_I2C0->SCLH   = I2SCLH_HS_SCLH;
231
#else
232
  LPC_PINCON->I2CPADCFG &= ~((0x1<<0)|(0x1<<2));
233
  LPC_I2C0->I2SCLL   = I2SCLL_SCLL;
234
  LPC_I2C0->I2SCLH   = I2SCLH_SCLH;
235
#endif
236
237
  /* Install interrupt handler */
238
  NVIC_EnableIRQ(I2C0_IRQn);
239
240
  LPC_I2C0->I2CONSET = I2CONSET_I2EN;
241
  return;
242
}
243
/*****************************************************************************
244
** Function name:    I2CEngine
245
**
246
** Descriptions:    The routine to complete a I2C transaction
247
**            from start to stop. All the intermitten
248
**            steps are handled in the interrupt handler.
249
**            Before this routine is called, the read
250
**            length, write length, I2C master buffer,
251
**            and I2C command fields need to be filled.
252
**            see i2cmst.c for more details.
253
**
254
** parameters:      I2C port number
255
** Returned value:    master state of current I2C port.
256
** 
257
*****************************************************************************/
258
uint32_t I2CEngine( uint32_t portNum ) 
259
{
260
  /*--- Issue a start condition ---*/
261
  LPC_I2C[portNum]->I2CONSET = I2CONSET_STA;  /* Set Start flag */
262
263
  I2CMasterState[portNum] = I2C_BUSY;
264
265
  while ( I2CMasterState[portNum] == I2C_BUSY )
266
  {
267
  if ( timeout[portNum] >= MAX_TIMEOUT )
268
  {
269
    I2CMasterState[portNum] = I2C_TIME_OUT;
270
    break;
271
  }
272
  timeout[portNum]++;
273
  }
274
  LPC_I2C[portNum]->I2CONCLR = I2CONCLR_STAC;
275
276
  return ( I2CMasterState[portNum] );
277
}

von Florian M. (lauch_henne)


Lesenswert?

Ok, das Problem mit dem Konfigurieren der Peripherie habe ich jetzt 
lösen können.
Die Headerdatei war einfach nicht vollständig.

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.