TPA81 an STM32F103 I2C Problem

OP (Firma: Insistro) #2850042
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
#2934803
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren