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.
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.
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)
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.
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...
???
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(inti=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
voidI2C2_Robust_Init(void)
2
{
3
GPIO_InitTypeDefGPIO_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) */
Bernd S. schrieb:> Kilo S. schrieb:>> Prüfe:
soweit geprüft!
anbei Auszug aus dem Quellcode. Seltsam ist, dass die eingebaute
Scannerfunktion tatsächlich die beiden angeschlossenen Slaves auch mit
den richtigen Adressen findet. Das Testprogramm eetest() läuft einmal
durch und bleibt dann beim nächsten Durchlauf in der single_write(0x20,
0x15)
hängen, wartet auf ein gesetztes TXE Bit, was nicht kommt.
Wie zu sehen, die I2C-Funktionen sind in einer Klasse enthalten.
Problem:
| statt ||
prüft das ganze Register statt Flags
ADDR wird nie gelöscht
Der Scanner funktioniert nur zufällig.
Dritter versteckter Bug
In readByte():
1
m_pI2C->DR=(address<<1)+0x00;
Das ist Write-Adresse, nicht Read.
Read müsste sein:
Kilo S. schrieb:> versuchs mal hiermit...
Hier mal die Resultate aus deinem Beispiel:
Er spricht wieder!!!
da ich auf dem Testboard ein EEPROM habe, dass eine 16bit Adresse
verlangt, (FM64LC64) habe ich die read/write funktionen noch
entsprechend ergänzt und siehe da, was man reinschreibt, kommt auch
wieder raus.
Jetzt muss ich nur noch ergründen, warum mein Code rum zickt
Schon mal Danke Kilo S.