Forum: Mikrocontroller und Digitale Elektronik TPA81 an STM32F103 I2C Problem


von Andre B. (Firma: Insistro) (qusoften)


Lesenswert?

Hallo liebe Forum-Gemeinde,

ich hab mich nun nach langem Lesen dazu entschlossen, selbst Mitglied zu 
werden=)

Und da starte ich mein Mikrocontroller.net-Leben gleich mit einer Bitte 
zur Hilfestellung.

Folgendes Szenario:

Ich möchte den TPA81 (http://www.roboter-teile.de/datasheets/tpa81.pdf) 
via I2C an mein STM32F103VE Board klemmen und auslesen.
Das klappt auch soweit ganz gut, zumindest 1 mal, danach zieht SDA auf 
LOW und mein STM-Board interpretiert dies als BUSY.

I2C habe ich wie folg initialisiert:
1
GPIO_InitTypeDef GPIO_InitStructure;
2
NVIC_InitTypeDef NVIC_InitStructure;
3
I2C_InitTypeDef I2C_InitStructure;
4
5
RCC_Configuration();  
6
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
7
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
8
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
9
GPIO_Init(GPIOB, &GPIO_InitStructure);
10
GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);
11
12
I2C_DeInit(I2C1);
13
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
14
I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
15
I2C_InitStructure.I2C_ClockSpeed = 100000;
16
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
17
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
18
I2C_InitStructure.I2C_OwnAddress1 = 0xD0;  
19
20
I2C_Init(I2C1, &I2C_InitStructure);
21
I2C_Cmd(I2C1, ENABLE);

Um nun den TPA81 zu sagen was ich von ihm möchte nutze ich folgenden 
Code:
Als Info: TFT_ShowString und TFT_ShowNum habe ich zum "debuggen" 
eingesetzt damit ich seh wo er grad steht ;-)
1
while (1)
2
{
3
  TFT_CLEAR(0,0,240,320);
4
  while(I2C_CheckEvent(I2C1, I2C_FLAG_BUSY))
5
  {
6
    TFT_ShowString(10,10,"I2C_Bus: FAIL");
7
  } 
8
  TFT_ShowString(10,10,"I2C_Bus: OKAY");
9
  I2C_GenerateSTART(I2C1, ENABLE);
10
  while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
11
  {
12
    TFT_ShowString(10,30,"I2C_EventCheck: FAIL");
13
  }
14
  TFT_ShowString(10,30,"I2C_EventCheck: OKAY");
15
  I2C_Send7bitAddress(I2C1,0xD0,0);                 
16
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
17
  {
18
    TFT_ShowString(10,50,"I2C_Master: FAIL");
19
  }
20
  TFT_ShowString(10,50,"I2C_Master: OKAY");
21
  I2C_Cmd(I2C1,ENABLE);
22
  while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED))    
23
  {                
24
    TFT_ShowString(10,70,"I2C_M_Trans1: FAIL");                 
25
  }                     
26
  TFT_ShowString(10,70,"I2C_M_Trans1: OKAY");
27
  for (j=3;j<10;j++)
28
  {
29
    I2C_Cmd(I2C1, ENABLE);                         
30
    I2C_SendData(I2C1, j);                        
31
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
32
    {
33
      TFT_ShowString(10,90,"I2C_M_Trans2: FAIL");
34
    }
35
    TFT_ShowString(10,90,"I2C_M_Trans2: OKAY");
36
    while (I2C_CheckEvent(I2C1, I2C_FLAG_BUSY))                 
37
    {                    
38
      TFT_ShowString(10,110,"I2C_Bus: FAIL");                 
39
    }                    
40
    TFT_ShowString(10,110,"I2C_Bus: OKAY");                     
41
    I2C_GenerateSTART(I2C1, ENABLE);
42
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
43
    {
44
      TFT_ShowString(10,130,"I2C_EventCheck2: FAIL");
45
    }
46
    TFT_ShowString(10,130,"I2C_EventCheck2: OKAY");
47
    I2C_Send7bitAddress(I2C1,0xD1,1);
48
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
49
    {
50
      TFT_ShowString(10,150,"I2C_M_Trans3: FAIL");
51
    }
52
    TFT_ShowString(10,150,"I2C_M_Trans3: OKAY");
53
    I2C_Cmd(I2C1, ENABLE);
54
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
55
    {
56
      TFT_ShowString(10,170,"I2C_Master_RX: FAIL");
57
    }
58
    TFT_ShowString(10,170,"I2C_Master_RX: OKAY");
59
    TFT_ShowNum(140,10+(j*20),I2C_ReceiveData(I2C1));
60
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
61
    {
62
      TFT_ShowString(10,190,"I2C_Master_RX1: FAIL");
63
    }
64
    TFT_ShowString(10,190,"I2C_Master_RX1: OKAY");
65
    delay_ms(100);
66
    I2C_AcknowledgeConfig(I2C1,DISABLE);
67
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
68
    {
69
      TFT_ShowString(10,210,"I2C_Master_RX2: FAIL");
70
    }
71
    TFT_ShowString(10,210,"I2C_Master_RX2: OKAY");
72
    TFT_ShowNum(180,10+(j*20),I2C_ReceiveData(I2C1));
73
    I2C_GenerateSTOP(I2C1, ENABLE);
74
    while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF))
75
    {
76
      TFT_ShowString(10,230,"I2C_Stop: FAIL");
77
    }
78
    TFT_ShowString(10,230,"I2C_Stop: OKAY");
79
    I2C_AcknowledgeConfig(I2C1,ENABLE);
80
    delay_ms(100);
81
  }
82
  TFT_ShowNum(10,280,i);
83
  i++;
84
  delay_ms(100);
85
}

Die Routine läuft genau 1 mal durch, danach ist schluss. SDA wird immer 
auf LOW gezogen.
Ich habe zu diesem Problem etliche Foren durchforstet, Manuals gelesen 
und mich auch ausgiebig mit dem I2C bzw. TWI Bus beschäftigt und stoße 
solangsam an meine Grenzen :-(

Leider habe ich kein Oszi daheim stehen.

Ich bedanke mich schon mal vorab für Tips / Kritik und weitere Infos zu 
dem Thema I2C, STM32 sowie TPA81

von Michael A. (mukululul)


Lesenswert?

Hallo,
ich empfehle dir folgende Infos anzuschauen:

http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/CD00209826.pdf

https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Attachments/19516/i2croutines.c
Hier siehst du das es gar nicht so einfach ist mir der STM32 i2c HW zu 
arbeiten. 1,2, und mehr bytes sind jeweils spezielle Sequenzen.

Ich vermute mal das du das lesen des letzten bytes anderst machen must. 
Also vor dem lesen des letzten bytes ein STOP schicken.

Dein Device will vermutlich ein weiteres byte schicken und deshalb kann 
der Master nichts schicken. Theoretisch könnte man auch einfach an der 
SCL takten bis SDA auf high geht. Dann ist der Bus wieder frei.
Siehe z.B hier... http://www.microchip.com/forums/m175368-print.aspx
Aber das sollte man eigentlich nur als letzte möglichkeit verwenden.

Gruss
Michael

von Klaus (Gast)


Lesenswert?

Michael Andres schrieb:
> Also vor dem lesen des letzten bytes ein STOP schicken.

Das geht bei I2C nicht, Nach einem Stop wartet der Slave auf das nächste 
Start mit folgender Adresse.

Der Fehler klingt nach "lesen mit ACK", statt beim letzten Byte "lesen 
mit NACK" zu machen.

MfG Klaus

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.