Atmega328p I²C

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Atmega328p I²C

Beitrag von Timm Thaler »

siro hat geschrieben:Ja ich meinte die Konstanten..
const
ads1115wr = %10010001;
ads1115rd = %10010000;


Ähm, ja, die sind vertauscht. Write ist 0 und Read ist 1. Man sollte doch in den Code schauen und nicht einfach aus dem Gedächtnis.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Atmega328p I²C

Beitrag von Mathias »

Zieht jetzt irgendwas den SCL dauerhaft auf low, z.B. ein Kurzschluss, dann bleibt der Controller in der Read-Routine hängen.

Das war auch der Grund meine Blockierung, da ich von einer falschen Adresse lesen wollte.
Wen ich den ADS entferne, dann bleibt er wieder hängen.
Schuld wir diese Schleife sein:

Code: Alles auswählen

while (TWCR and (1 shl TWINT)) = 0 do begin
    end;

Du solltest da ein Timeout einbauen, sowas wie: Wenn die while-Schleife nach xx Durchläufen nicht beendet ist, dann beende sie mit einem ungültigen Wert.
Diese Gedanke hatte ich auch mal kurz, als es gestern noch hängte. Wen der Wert ungültig ist, könnte man zB eine LED aufleuchten lassen. Dann wüsste der Benutzer das etwas mit der Hardware nicht stimmt.
Beim Arduino-Header muss so etwas schon eingebaut sein, der läuft einfach mit einem ungültigen Wert durch.

So eine Abfrage habe ich auch noch gefunden, nur nützt diese nichts, wen er hängt. :roll:

Code: Alles auswählen

uint8_t TWIGetStatus(void) {
    uint8_t status;
    //mask status
    status = TWSR & 0xF8;
    return status;
}


Ist dies richtig, wen der Prescale 4 ist, dann läuft das Ganze mit 400KHz ?

Code: Alles auswählen

  procedure TWIInit;
  const
    Prescaler = 4;
    TWBR_val = ((((CPU_Clock div F_SCL) div Prescaler) - 16) div 2);
  begin
    TWSR := 0;
    TWBR := byte(TWBR_val);
    TWCR := (1 shl TWEN);
  end;

Ich habe gerade gesehen, F_SCL ist die Frequenz, für was ist dann der Prescaler ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Atmega328p I²C

Beitrag von Timm Thaler »

Das mit dem Prescaler ist wie der Prescaler für die Timer: Ausgangswert ist Dein Systemtakt, bei Dir der 16MHz Quarz, und daraus wird über den Prescaler ein verringerter Takt gemacht, mit dem läuft der Baudratenzähler des TWI, und wenn der überläuft gibt es eine Taktflanke, das div 2 am Ende bedeutet, dass der Takt zweimal pro SCL benötigt wird, einmal für steigende, einmal für fallende Flanke.

Also bei 16MHz und Prescaler 4 hast Du 4MHz verringerten Takt, um auf 400kHz zu kommen musst Du den nochmal durch TWBR = 5 teilen, dann wird mit 800kHz getaktet und der Bus läuft mit 400kHz. Für 100kHz wäre TBWR dann 20.

Hast Du den AVR nur mit 1MHz laufen, dann darf der Prescaler nur 1 sein, um mit TWBR = 2 bei 250KHz oder TWBR = 5 bei 100kHz zu laufen, 400kHz sind nicht möglich.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Atmega328p I²C

Beitrag von Mathias »

Ist der Prescaler bei TWI nicht überflüssig, da ich den SCL-Takt auch über F_SCL einstellen kann ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Atmega328p I²C

Beitrag von Timm Thaler »

Und wie machst Du dann eine 10kHz I2C-Verbindung? Ich mach über 20m Cat5-Kabel I2C bei 10kHz, das geht mit 100kHz nicht mehr.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Atmega328p I²C

Beitrag von Mathias »

F_SCL auf 10000, oder geht dies nicht ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten