Forum: Mikrocontroller und Digitale Elektronik STM32 IIC Datenübertragung?


von Markus (Gast)


Lesenswert?

Ich habe einen STM32F103 und möchte über Interrupt die IIC Kommunikation 
herstellen.

Konkret geht es um einen Chip, der hat eine 7-Bit Chip-Adresse, 16 Bit 
Adresse und immer 16 Bit Daten. Der STM32 ist der Master.

Das Schreiben von diesen 5 Bytes geht ohne Probleme.

Mit dem Lesen hab ich noch Schwierigkeiten, da erhalte ich immer andere 
Interrupts.

Also das Lesen:
- Senden der Chip-Kennung, 7 Bit
- Senden der Adresse, 16 Bit
- Erneut Start-Bit
- Senden der Chip-Kennung, 7 Bit, Lese-Bit
- Dann möchte ich die 16 Bit Lesen

Dem Oszi nach kommen die auch an, aber der STM32 generiert 18 
Clock-Signale ohne dazwischen einen Interrupt zu generieren, somit kann 
ich dem beim letzten Lese-Byte nicht sagen, dass der ein Stop generieren 
soll.
Jetzt hängt der Chip endlos in IIC-Interrupts, CLK ist Hi, DAT ist LOW.

Die Demos von STM haben auch nur ein Schreiben vom serielen EEPROM, aber 
wie geht das mit dem Lesen richtig?

Vielen Dank für eure Unterstützung, anbei mein Code.

1
//**************************************************************************************************************************
2
// Definitionen von globalen Variablen
3
//**************************************************************************************************************************
4
5
u8  IIC_DevAddr; // IIC-Device Adresse
6
u16 IIC_Addr;    // Register-Adresse
7
u16 IIC_Data;    // Daten Wort
8
u8  IIC_Mode;    // Modus: 0=kein, 1=schreiben, 2=lesen
9
u8  IIC_Stat;    // Status: 0=in Arbeit, 1=Fertig
10
11
s16  IIC_Count;
12
13
// Initialiseren IIC Bus
14
void IICInit(char bRefresh)
15
{
16
  if (!bRefresh)
17
  {
18
    IIC_DevAddr = 0x58;
19
    IIC_Addr = 0;
20
    IIC_Data = 0;
21
    IIC_Mode = 0;
22
    IIC_Stat = 1;
23
    IIC_Count = 0;
24
    I2C_DeInit(I2C2);
25
  }
26
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
27
28
  /* Configure I2C2 pins: SCL and SDA ----------------------------------------*/
29
  GPIO_InitTypeDef GPIO_InitStructure;
30
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
31
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
32
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
33
  GPIO_Init(GPIOB, &GPIO_InitStructure);
34
35
  I2C_Cmd(I2C2, ENABLE);
36
37
  /* I2C2 configuration ------------------------------------------------------*/
38
  I2C_InitTypeDef  I2C_InitSt;
39
  I2C_InitSt.I2C_Mode = I2C_Mode_I2C;
40
  I2C_InitSt.I2C_DutyCycle = I2C_DutyCycle_2;
41
  I2C_InitSt.I2C_OwnAddress1 = IIC_DevAddr;
42
  I2C_InitSt.I2C_Ack = I2C_Ack_Enable;
43
  I2C_InitSt.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
44
  I2C_InitSt.I2C_ClockSpeed = 40000;
45
  I2C_Init(I2C2, &I2C_InitSt);
46
47
    /* Configure and enable I2C2 interrupt -------------------------------------*/
48
  NVIC_InitTypeDef NVIC_InitSt;
49
  NVIC_InitSt.NVIC_IRQChannel = I2C2_EV_IRQChannel;
50
  NVIC_InitSt.NVIC_IRQChannelPreemptionPriority = 0;
51
  NVIC_InitSt.NVIC_IRQChannelSubPriority = 0;
52
  NVIC_InitSt.NVIC_IRQChannelCmd = ENABLE;
53
  NVIC_Init(&NVIC_InitSt);
54
55
  I2C_ITConfig(I2C2, I2C_IT_EVT | I2C_IT_BUF, ENABLE);
56
}
57
58
// IIC Übertragung abgeschlossen
59
u8 IIC_Ready(void)
60
{
61
  return IIC_Stat;
62
}
63
64
// Schreibe Daten
65
void IIC_Write(u16 Addr, u16 Data)
66
{
67
  if (!IIC_Stat) return; // Doppelte Befehle gehen nicht!
68
  IIC_Addr = Addr;
69
  IIC_Data = Data;
70
  IIC_Mode = 1;
71
  IIC_Stat = 0;
72
  IIC_Count = 0;
73
  //I2C_GenerateSTOP(I2C2, DISABLE);
74
  I2C_GenerateSTART(I2C2, ENABLE);
75
}
76
77
// Leseanforderung Daten starten
78
void IIC_ReadStart(u16 Addr)
79
{
80
  IICInit(0); // *DEBUG für Test
81
  if (!IIC_Stat) return; // Doppelte Befehle gehen nicht!
82
  IIC_Addr = Addr;
83
  IIC_Data = 0;
84
  IIC_Mode = 2;
85
  IIC_Stat = 0;
86
  IIC_Count = 0;
87
  //I2C_GenerateSTOP(I2C2, DISABLE);
88
  I2C_GenerateSTART(I2C2, ENABLE);
89
}
90
91
// Daten der Leseanforderung
92
u16 IIC_ReadData(void)
93
{
94
  if (!IIC_Stat) return 0; // Nicht fertig
95
  return IIC_Data;
96
}
97
98
// Interrupt
99
void IIC_ISR(void)
100
{
101
  u32 i = I2C_GetLastEvent(I2C2);
102
  switch (i)
103
  {
104
      /* Test on I2C2 EV5 and clear it */
105
  case I2C_EVENT_MASTER_MODE_SELECT:
106
    /* Send I2C2 slave Address for write */
107
    if (IIC_Mode <= 2)
108
      I2C_Send7bitAddress(I2C2, IIC_DevAddr, I2C_Direction_Transmitter);
109
    else if (IIC_Mode == 3)
110
      I2C_AcknowledgeConfig(I2C2, ENABLE);
111
//      I2C_Send7bitAddress(I2C2, IIC_DevAddr, I2C_Direction_Receiver);
112
    break;
113
114
    /* Test on I2C2 EV6 and first EV8 and clear them */
115
  case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:
116
    /* I2C2 and I2C2 PEC Transmission Enable */
117
    I2C_CalculatePEC(I2C2, ENABLE);
118
    /* Send the first data */
119
    I2C_SendData(I2C2, (u8)((u16)(IIC_Addr >> 8) & 0xFF));  //EV8 just after EV6
120
    IIC_Count++;
121
    break;
122
123
  case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED:
124
    break;
125
126
  case I2C_EVENT_MASTER_BYTE_RECEIVED:
127
    switch (IIC_Count)
128
    {
129
    case 4:
130
      I2C_AcknowledgeConfig(I2C2, DISABLE);
131
      IIC_Data = ((u16)I2C_ReceiveData(I2C2)) << 8;
132
      break;
133
    case 5:
134
      I2C_GenerateSTOP(I2C2, ENABLE);
135
      IIC_Data |= ((u16)I2C_ReceiveData(I2C2));
136
      I2C_AcknowledgeConfig(I2C2, ENABLE);
137
      IIC_Stat = 1;
138
      break;
139
    }
140
    IIC_Count++;
141
    break;
142
  case 196611:
143
    I2C_AcknowledgeConfig(I2C2, DISABLE);
144
//    I2C_AcknowledgeConfig(I2C2, ENABLE);
145
    //IIC_Data = ((u16)I2C_ReceiveData(I2C2)) << 8;
146
    //IIC_Data |= ((u16)I2C_ReceiveData(I2C2));
147
    //IIC_Stat = 1;
148
    break;
149
  case 196677:
150
    I2C_GenerateSTOP(I2C2, ENABLE);
151
    //IIC_Data |= ((u16)I2C_ReceiveData(I2C2));
152
    break;
153
154
    /* Test on I2C2 EV8 and clear it */
155
  case I2C_EVENT_MASTER_BYTE_TRANSMITTED:
156
    if (I2C2->SR1 & 0x04000) // NACK Returned!
157
    {
158
      I2C_GenerateSTOP(I2C2, ENABLE);
159
      IIC_Stat = 1;
160
      return;
161
    }
162
    switch (IIC_Count)
163
    {
164
    case 1:
165
      I2C_SendData(I2C2, IIC_Addr & 0xFF);
166
      break;
167
    case 2:
168
      if (IIC_Mode == 2)
169
      {
170
        //I2C_GenerateSTOP(I2C2, ENABLE);
171
        I2C_GenerateSTART(I2C2, ENABLE); // Start-Bit für nächstes Lesen
172
        IIC_Mode = 3;
173
      } else I2C_SendData(I2C2, (u8)((u16)(IIC_Data >> 8) & 0xFF));
174
      break;
175
    case 3:
176
      if (IIC_Mode == 3)
177
      {
178
        //I2C_GenerateSTOP(I2C2, ENABLE);
179
        I2C_AcknowledgeConfig(I2C2, DISABLE);
180
        I2C_Send7bitAddress(I2C2, IIC_DevAddr, I2C_Direction_Receiver);
181
      } else {
182
        I2C_SendData(I2C2, IIC_Data & 0xFF);
183
        IIC_Stat = 1;
184
      }
185
      break;
186
    case 4:
187
      I2C_GenerateSTOP(I2C2, ENABLE);
188
      IIC_Stat = 1;
189
      break;
190
    default:
191
      I2C_TransmitPEC(I2C2, ENABLE);
192
      break;
193
    }
194
    IIC_Count++;
195
    break;
196
197
  case I2C_EVENT_SLAVE_ACK_FAILURE:
198
    I2C_GenerateSTOP(I2C2, ENABLE);
199
    IIC_Stat = 1;
200
    break;
201
202
    default:
203
      break;
204
  }
205
}

von Markus (Gast)


Lesenswert?

Hat keine eine Idee dazu?

von Reinhard B. (brainstorm)


Lesenswert?

Hallo,

Im Reference Manual von ST (RM0008) steht dazu was auf Seite 588. Unter 
den Punkten "Master receiver" und "Closing the Communication".

Und bei den Support Files von ST gibts auch noch die FWLib, in der alle 
Peripherieeinheiten implementiert sind. Die I2C Routinen von dort können 
mit Sicherheit auch Lesen.

mfg

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.