Hallo auch, ich brüte schon seit ein paar Tagen an der I2C Kommunikation (mit EEPROM, Display) an einem STM32F103RFT6. Die Pins PB10/11 führen die Signale SCL/SDA des 2. I2C Interfaces (I2C2). Pullups 3.6k sind dran. Selbst in einem minimalsten Testprogramm regt sich an den Leitungen nichts, dauerhafter Highpegel. Im Debugger sind alle notwendigen Register der RCC, GPIOB und I2C2 korrekt gesetzt. Gleiches Testprogramm für I2C1 konfiguriert, läuft ohne Probleme. Ich habe schon sämtliche Errata's und "googles" durch, nichts gefunden. Meine Hoffnung liegt nun hier. Hat jemand eine evtl Lösung?
Moinsen, wurde auch beim richtigen Package für die physischen Pins geguckt? Laut Datenblatt liegen I2C2 SCL/SDA an Pin 29/30 für LQFP-64. Nicht, das versehentlich bei LQFP-100 geguckt wurde und 47/48 vewendet wird. Grüße, derEine
Patrick schrieb: > Laut Datenblatt liegen I2C2 SCL/SDA an Pin 29/30 für LQFP-64. > Nicht, das versehentlich bei LQFP-100 geguckt wurde und 47/48 vewendet > wird. Einwand berechtigt, ist aber korrekt angeschlossen (SCL: pin 29, PB10 und SDA: pin 30, PB11) Getestet wurde auf 2 verschiedenen Boards mit dem gleichen negativen Ergebnis. Kilo S. schrieb: > Sollen wir Hellsehen? > > Zeig deinen CODE! Der Code für die Initialisierung, Nutzung der I2C-Schnittstellen dürfte den Wissenden bekannt sein. Es wurde mit verschiedenen Tests geprüft: Bare-Metal, HAL, StdPeripherie, auch mit STMCube erzeugter Code, alles mit gleichem Ergebnis. Das Ding rührt sich nicht.
Gibt es sonst eventuell ein Konflikt mit einer aktivierten USART3 Schnittstelle?
Bernd S. schrieb: > Patrick schrieb: >> Laut Datenblatt liegen I2C2 SCL/SDA an Pin 29/30 für LQFP-64. >> Nicht, das versehentlich bei LQFP-100 geguckt wurde und 47/48 vewendet >> wird. > > Einwand berechtigt, ist aber korrekt angeschlossen (SCL: pin 29, PB10 > und SDA: pin 30, PB11) > Getestet wurde auf 2 verschiedenen Boards mit dem gleichen negativen > Ergebnis. Gut, an der Hardware liegt es nicht. Bernd S. schrieb: > Kilo S. schrieb: >> Sollen wir Hellsehen? >> >> Zeig deinen CODE! > > Der Code für die Initialisierung, Nutzung der I2C-Schnittstellen dürfte > den Wissenden bekannt sein. Es wurde mit verschiedenen Tests geprüft: > Bare-Metal, HAL, StdPeripherie, auch mit STMCube erzeugter Code, alles > mit gleichem Ergebnis. Das Ding rührt sich nicht. Gut, die Software ist auch ausgeschlossen. Also muss der Bug im Silizium des Chips sitzen - denn an dir bzw. deiner Schaltung (die du geheim hältst) und deinem Code (den du ebenfalls geheim hältst) kann es schließlich nicht liegen. Beides ist schließlich garantiert fehlerfrei - es stammt ja schließlich von dir. Ergo können wir dir hier nicht weiterhelfen.
:
Bearbeitet durch User
Ah, der fehlerfreie perfekte Mensch erbarmt sich zu uns ins niedere Forum auf der Suche nach Hilfe die ja unmöglich auf einen seiner Fehler zurückzuführen sind! Langsam aber sicher sind doch 90% der Menschheit noch zu doof einen Schuh vol pisse auszuleeren, bei dem die Anleitung dazu auf der Sohle steht! Goodbye, TROLL!
Stefan S. schrieb: > Gut, die Software ist auch ausgeschlossen. > > Also muss der Bug im Silizium des Chips sitzen - denn an dir bzw. > deiner Schaltung (die du geheim hältst) und deinem Code (den du > ebenfalls geheim hältst) kann es schließlich nicht liegen. Beides ist > schließlich garantiert fehlerfrei - es stammt ja schließlich von dir. > Ergo können wir dir hier nicht weiterhelfen. Dabei ist der Code garnicht von mir (CubeMX)
Beitrag #8010552 wurde vom Autor gelöscht.
Kilo S. schrieb: > Ah, der fehlerfreie perfekte Mensch erbarmt sich zu uns ins niedere > Forum auf der Suche nach Hilfe die ja unmöglich auf einen seiner Fehler > zurückzuführen sind! Schwachsinn, habe ich nie behauptet. Warscheinlich ist mein Ersuchen doch nur für Leute mit entsprechendem Wissen geeignet! hier noch ein weiterer Test , nutzt die StdPeriph lib.
Kein clock keine Pin Definitionen! Geräteadresse?...
:
Bearbeitet durch User
Du sprichst von Pin 10/11, ich sehe aber nur Pin 6/7 konfiguriert.
:
Bearbeitet durch User
1 | void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c) |
2 | {
|
3 | GPIO_InitTypeDef GPIO_InitStruct = {0}; |
4 | |
5 | if(hi2c->Instance == I2C2) |
6 | {
|
7 | /* Clocks */
|
8 | __HAL_RCC_GPIOB_CLK_ENABLE(); |
9 | __HAL_RCC_I2C2_CLK_ENABLE(); |
10 | __HAL_RCC_AFIO_CLK_ENABLE(); |
11 | |
12 | /* I2C2 GPIO Configuration: PB10=SCL, PB11=SDA */
|
13 | GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_11; |
14 | GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; |
15 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; |
16 | HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); |
17 | }
|
18 | }
|
falsch initialisiert! F1 benutzt keine Alternate-Function Nummern (GPIO_AF4_I2C2 existiert hier nicht)
Alex R. schrieb: > Du sprichst von Pin 10/11, ich sehe aber nur Pin 7/8 konfiguriert. Mist, falsches File. Du hast Recht, ändert aber nix.
Beitrag #8010567 wurde vom Autor gelöscht.
Thomas W. schrieb im Beitrag #8010567: > Eigentlich haette der Compiler auch eine Warnung schicken sollen (16-bit > vs. 8-Bit). Daher meine Frage bezüglich der Adresse...
Bernd S. schrieb: > Warscheinlich ist mein Ersuchen doch nur für Leute mit entsprechendem > Wissen geeignet! Vorsicht, so hochtrabenden können tief Fallen!
Kilo S. schrieb: > __HAL_RCC_AFIO_CLK_ENABLE(); ist auch richtig, kann weggelassen werden, ändert aber ebenfalls nix. Damit auch die letzten Zweifel ausgeräumt werden: Testumgebung: Visual Studio mit Extension VisualDGB (Compiler GCC) Wie schon gesagt: in der Hardware-Registeransicht sind alle Register von I2C2, GPIOB, RCC korrekt gesetzt, aber es passiert nichts. Ich kan sehen, dass beim Sendeversuch, d.h. I2C2->DR das zu sendende Datum erhält, es bleibt jedoch beim nächsten Singlestep stehen (im Gegenzug zum Test mit I2C1)
Kilo S. schrieb: > Thomas W. schrieb im Beitrag #8010567: >> Eigentlich haette der Compiler auch eine Warnung schicken sollen (16-bit >> vs. 8-Bit). > > Daher meine Frage bezüglich der Adresse... ???
CubeMX setzt CR2 oft nur für I2C1 korrekt.
1 | RCC->APB1ENR |= RCC_APB1ENR_I2C2EN; |
2 | |
3 | I2C2->CR2 = 36; // APB1 Clock in MHz |
I2C2 kann mit JTAG/SWD Pins kollidieren, wenn AFIO falsch konfiguriert ist.
1 | __HAL_RCC_AFIO_CLK_ENABLE(); |
2 | |
3 | //und ob irgendwo remapped wurde
|
4 | AFIO->MAPR |
teste mal:
1 | printf("CR2=%lu\n", I2C2->CR2); |
2 | printf("APB1=%lu\n", HAL_RCC_GetPCLK1Freq()); |
Wenn du mir diese drei Werte gibst, sag ich dir sofort den Fehler: RCC->CFGR I2C2->CR2 GPIOB->CRH
:
Bearbeitet durch User
Kilo S. schrieb: > RCC->CFGR > I2C2->CR2 > GPIOB->CRH RCC->CFGR: 0x001d040a I2C2->CR2: 0x00000024 GPIOB->CRH: 0x2848ff42 (CNF/MODE 10,11 = 0x11)
Prüfe:
1 | uint32_t busy = I2C2->SR2 & I2C_SR2_BUSY; |
Wenn ≠0 → Ursache gefunden. Typische Gründe: Slave hält SDA Pull-ups fehlen / zu schwach vorheriger Reset mitten im Transfer Debugger Stop während I2C aktiv. Fix (offizieller ST Workaround)
1 | I2C2->CR1 |= I2C_CR1_SWRST; |
2 | I2C2->CR1 &= ~I2C_CR1_SWRST; |
Vor Init Bus freitakten:
1 | // SCL manuell toggeln wenn SDA LOW
|
2 | for(int i=0;i<9;i++) |
3 | {
|
4 | SCL_HIGH(); |
5 | delay(); |
6 | SCL_LOW(); |
7 | delay(); |
8 | }
|
Direkt nach Init:
1 | printf("SR2 = %04X\n", I2C2->SR2); |
Ausgabe:
1 | SR2 = 0002 |
BUSY Flag gesetzt, Ursache bestätigt. Füge direkt nach Init ein:(Schnelllösung)
1 | if(I2C2->SR2 & I2C_SR2_BUSY) |
2 | {
|
3 | I2C2->CR1 |= I2C_CR1_SWRST; |
4 | I2C2->CR1 &= ~I2C_CR1_SWRST; |
5 | }
|
das sollte selbst mit kaputten slaves laufen:
1 | void I2C2_Robust_Init(void) |
2 | {
|
3 | GPIO_InitTypeDef GPIO_InitStruct = {0}; |
4 | |
5 | /* 1. Clocks aktivieren */
|
6 | __HAL_RCC_GPIOB_CLK_ENABLE(); |
7 | __HAL_RCC_I2C2_CLK_ENABLE(); |
8 | __HAL_RCC_AFIO_CLK_ENABLE(); |
9 | |
10 | /* 2. Pins erstmal als GPIO OpenDrain (manuelle Bus Recovery) */
|
11 | GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_11; |
12 | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; |
13 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; |
14 | HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); |
15 | |
16 | HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10|GPIO_PIN_11, GPIO_PIN_SET); |
17 | HAL_Delay(1); |
18 | |
19 | /* 3. Bus freitakten falls Slave hängt */
|
20 | if(!HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_11)) // SDA LOW? |
21 | {
|
22 | for(int i=0;i<9;i++) |
23 | {
|
24 | HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET); |
25 | HAL_Delay(1); |
26 | HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET); |
27 | HAL_Delay(1); |
28 | }
|
29 | }
|
30 | |
31 | /* STOP Condition erzwingen */
|
32 | HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_RESET); |
33 | HAL_Delay(1); |
34 | HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET); |
35 | HAL_Delay(1); |
36 | HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_SET); |
37 | HAL_Delay(1); |
38 | |
39 | /* 4. I2C Hardware Reset */
|
40 | I2C2->CR1 |= I2C_CR1_SWRST; |
41 | HAL_Delay(1); |
42 | I2C2->CR1 &= ~I2C_CR1_SWRST; |
43 | |
44 | /* 5. Pins auf I2C Alternate Function */
|
45 | GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; |
46 | HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); |
47 | |
48 | /* 6. Peripheral Disable */
|
49 | I2C2->CR1 &= ~I2C_CR1_PE; |
50 | |
51 | /* 7. Timing konfigurieren */
|
52 | I2C2->CR2 = 36; // APB1 MHz |
53 | I2C2->CCR = 180; // 100kHz @36MHz |
54 | I2C2->TRISE = 37; // laut Datenblatt |
55 | |
56 | /* 8. Peripheral Enable */
|
57 | I2C2->CR1 |= I2C_CR1_PE; |
58 | |
59 | /* 9. Dummy Read SR2 → Flags reset */
|
60 | (void)I2C2->SR2; |
61 | |
62 | /* 10. BUSY prüfen */
|
63 | if(I2C2->SR2 & I2C_SR2_BUSY) |
64 | {
|
65 | /* letzter Rettungsversuch */
|
66 | I2C2->CR1 &= ~I2C_CR1_PE; |
67 | HAL_Delay(1); |
68 | I2C2->CR1 |= I2C_CR1_PE; |
69 | }
|
70 | }
|
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.