Forum: Mikrocontroller und Digitale Elektronik E2PROM Atmel AT24C512 - Was ist da anders?


von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich schreib grad die Routinen für ein E2PROM bzw 2 Stück als Bank aber 
mein ACK Polling funzt nicht, was ich mühsam aufgetüfelt habe und was 
bei anderen funktionierte.

Das sind Atmel E2PROMS und normalerweise polle ich nach einem 
Schreibzyklus solange mit Write Zugriffen, bis der Stein mit "ACK" 
antwortet. Dann ist der Zyklus beendet. Es heisst ja auch "Acknowledge 
Polling".

Nur bei dem Teil läuft die Routine in den Timeout :-( Wie ist denn das 
gemeint, was da steht? Auf dem Bus tut sich nichts wenn ich das Polling 
laufen lasse.

Ich polle auf das Event 6 beim STM32F103.

Ersetze ich das Polling durch DelayMs(5) ist alles ok, der Wert steht 
drin, wird auch ausgelesen aber das ist es ja nicht, Ziel ist ja 
maximaler Durchsatz.


Gruss,
Christian

von Jim M. (turboj)


Lesenswert?

Christian J. schrieb:
> Auf dem Bus tut sich nichts wenn ich das Polling
> laufen lasse.

Dann ist da was kaputt: Da sollte immer die Adresse mit NACK kommen.

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

So etwa? Bei einem PROM von Microchip 24Lc1025 ist da nämlich anders 
beschrieben in dem Manual. Allerdings haben die auch "Bank Bits", nur 2 
Adressleitungen usw.

Hier mal meine Polling Routine, die bei denen von MC funktionierte. Die 
Schleife rödelt solange bis das E2PROM sich bequemt mit einem ACK zu 
antworten, d.h. der interne Zyklus ist beendet. So war es bisher immer.

Nur was meinen die mit "EEPROM will respond with a 0". Das Teil kann ja 
nur eine Null senden, wenn der Master weiter clocked. Und das ist bei 
einer Statemachine wie im Cortex nicht ganz trivial, die hält sich stur 
an den I2C Stndard.

Zum Vergleich mal das Datenblatt eines Microchip Steins gleicher Größe, 
512 kBit.
1
// ---------------------------------------------------------------
2
// Warte bis Schreibzyklus beendet ist (ACK Polling)
3
// ---------------------------------------------------------------
4
static uint8_t e2p_WaitForWriteReady() {
5
6
    // Warte bis Byte weggeschrieben wurde (Slave sendet solange kein ACK)
7
    uint32_t timeout = I2C_TIMEOUT_MAX;
8
    do{
9
        if (--timeout == 0)
10
            return ERROR;
11
        /* Erzeuge Schreibzugriff */
12
        I2C_GenerateSTART(I2C1, ENABLE);
13
        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
14
        /* Sende die Write Adresse */
15
        I2C_Send7bitAddress(I2C1, E1_WR_ADR, I2C_Direction_Transmitter);
16
    } while(I2C_WaitForEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCESS);
17
18
    // Sequenz abschliessen
19
    I2C_GenerateSTOP(I2C1, ENABLE);
20
21
    return SUCCESS;
22
}

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Ok,  es klappt .... zumindest die Hardware. Aber meine Auswertung nicht. 
Bin aber zu müde das heute noch zu ergründen. Die I2C Hardware des STM32 
ist ein Brief mit vielen Siegeln bzw ein tiefes Tal der Tränen :-(

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Ich verstehe es nicht !

Was kann daran noch falsch sein? Auf dem LA sehe ich eindeutig, dass das 
EEPROM nach einer Weile von NAK auf ACK wechselt aber die letzte 
Schleife wird einfach nicht verlassen, obwohl sie das müsste.  Es ist 
nicht möglich die Busy Abfrage vor einem Schreibzugriff zu machen, da 
die I2C Statemachine des STM32F103 klare Vorgaben erwartet, was sie 
senden soll und was darauf zurück kommt. Die Events werden nur 
ausgelöst, wenn die erwartete Antwort kommt. Wenn ein ACK erwartet wurde 
aber ein NAK kommt wird das Event einfach nicht ausgelöst.

Ist da schonmal jemand in die Tiefen dieses I2C Interfaces eingestiegen?

Menno...
1
/* Schreibt ein Byte in eine einzelne Adresse */
2
uint8_t EE_WriteByte(uint16_t adr, uint8_t data)
3
{
4
    uint8_t lower_addr, upper_addr;
5
6
    lower_addr = (uint8_t)((0x00FF) & adr);
7
    adr = adr>>8;
8
    upper_addr = (uint8_t)((0x00FF) & adr);
9
10
    // Wait until I2C1 is not busy anymore
11
    //while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
12
13
    // ACK ein
14
    I2C_AcknowledgeConfig(I2C1, ENABLE);
15
16
    /* Erzeuge START Bedingung */
17
    I2C_GenerateSTART(I2C1, ENABLE);
18
    if (I2C_WaitForEvent(I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS)
19
        return ERROR;
20
21
    // Adressiere das E2PROM
22
    I2C_Send7bitAddress(I2C1, E1_WR_ADR, I2C_Direction_Transmitter);
23
    if (I2C_WaitForEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCESS)
24
        return ERROR;
25
26
    // Adresse als 2 x 8 Bit senden
27
    I2C_SendData(I2C1,upper_addr);
28
    if (I2C_WaitForEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS)
29
        return ERROR;
30
31
    I2C_SendData(I2C1, lower_addr);
32
    if (I2C_WaitForEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS)
33
        return ERROR;
34
35
    // Sende Datum
36
    I2C_SendData(I2C1, data);
37
    while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)!= SUCCESS);
38
39
    // Sende I2C3 STOP Condition
40
    I2C_GenerateSTOP(I2C1, ENABLE);
41
    while (I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF));
42
43
    /* Warte bis Schreibzyklus beendet wurde */
44
    do{
45
        /* Erzeuge Schreibzugriff */
46
        I2C_GenerateSTART(I2C1, ENABLE);
47
        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
48
        /* Sende die Write Adresse */
49
        I2C_Send7bitAddress(I2C1, E1_WR_ADR, I2C_Direction_Transmitter);
50
    } while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCESS);
51
52
    // Sequenz abschliessen
53
    I2C_GenerateSTOP(I2C1, ENABLE);
54
55
56
    return SUCCESS;
57
58
}

von Peter D. (peda)


Lesenswert?


von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Ich habs am Laufen!

Es stellt sich aber die Frage, ob man bei EEPROM Funktionen den 
Riesenaufwand treiben sollte allen möglichen Fehler ab zu fangen? Gerade 
bei dem STM32Fxxxx Controllern gibt es unzählige Fehlerflags  usw. Wenn 
das EEPROM nicht reagiert wie gewünscht bleibt die CPU komplett hängen 
in den Schleifen und wird erst durch den WDT wieder rausgerissen.

Ich glaube das ist für Hobbyanwendungen etwas zu viel da jede Form von 
Diagnose zu nutzen, da das den Programmcode ganz schön aufbläht.

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.