mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atxmega TWI Daten in Bausteinregister schreiben


Autor: Andi M. (lesockz)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich arbeite zur Zeit an einem Projekt mit dem Atxmega 128A1. Mit diesem 
versuche ich einen Zooming ADC der Firma Semtech (SX8723) anzusteuern.
Dazu benutze ich die TWI Funktionen die Atmel in AVR1308 bereitstellt.

mit der Funktion
uint8_t TWI_MasterWriteRead(uint16 sx8723_Register, uint8_t write_bytes ,uint8_t read_bytes)

ist das Auslesen eines Registers auch kein Problem
es erfolgt mit der Funktion
TWI_MasterWriteRead(sx8723_Register, 1,1)

 in der Reihenfolge

[Adresse Baustein][Register Adresse][D-Ack][Adresse Baustein][Antwort 
des SX][D-NACK]

soweit kein Problem ich schreibe das Register und lese nach der zweiten 
Adresse dessen Inhalt.

will ich jetzt jedoch Daten in ein Register des SX schreiben habe ich 
mit den mitgelieferten Funktionen nur die Möglichkeit
TWI_MasterWriteRead(sx8723_Register, 2,0)

das heißt 2 Byte schreiben
sieht dann auf dem TWI Bus folgendermaßen aus

[Adresse Baustein][Register Adresse][D-Ack][Daten an den SX][D-ACK]

der Baustein benötigt aber zum Schreiben der Daten das Format

[Adresse Baustein][Ack][Register Adresse][D-Ack][Start][Adresse 
Baustein][Ack][Daten an den SX][ACK]

Habe noch zwei Bilder angehangen
Bild 1: so sieht meine Übertragung zur Zeit aus
Bild 2: So ist es beim SX vorgesehen
zip: AVR1308 Application Note

Die Funktion TWI_MasterWriteRead
sieht folgendermaßen aus:
bool TWI_MasterWriteRead(TWI_Master_t *twi,
                         uint8_t address,
                         uint8_t *writeData,
                         uint8_t bytesToWrite,
                         uint8_t bytesToRead)
{
  /*Parameter sanity check. */
  if (bytesToWrite > TWIM_WRITE_BUFFER_SIZE) {
    return false;
  }
  if (bytesToRead > TWIM_READ_BUFFER_SIZE) {
    return false;
  }

  /*Initiate transaction if bus is ready. */
  if (twi->status == TWIM_STATUS_READY) {

    twi->status = TWIM_STATUS_BUSY;
    twi->result = TWIM_RESULT_UNKNOWN;

    twi->address = address<<1;

    /* Fill write data buffer. */
    for (uint8_t bufferIndex=0; bufferIndex < bytesToWrite; bufferIndex++) {
      twi->writeData[bufferIndex] = writeData[bufferIndex];
    }

    twi->bytesToWrite = bytesToWrite;
    twi->bytesToRead = bytesToRead;
    twi->bytesWritten = 0;
    twi->bytesRead = 0;

    /* If write command, send the START condition + Address +
     * 'R/_W = 0'
     */
    if (twi->bytesToWrite > 0) {
      uint8_t writeAddress = twi->address & ~0x01;
      twi->interface->MASTER.ADDR = writeAddress;
    }

    /* If read command, send the START condition + Address +
     * 'R/_W = 1'
     */
    else if (twi->bytesToRead > 0) {
      uint8_t readAddress = twi->address | 0x01;
      twi->interface->MASTER.ADDR = readAddress;
    }
    return true;
  } else {
    return false;
  }
}

Autor: Andi M. (lesockz)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hab jetzt eine "Lösung" gefunden

in dem ich den in der AppNote gegebenen Code für meinen Bedarf angepasst 
habe.
bool TWI_MasterWriteRegisterData(TWI_Master_t *twi,uint8_t address,uint8_t *writeRegister,uint8_t *writeData,uint8_t bytesToWrite)
{
  
  /*Parameter sanity check. */
  if (bytesToWrite > TWIM_WRITE_BUFFER_SIZE) {
    return false;
  }

  /*Initiate transaction if bus is ready. */
  if (twi->status == TWIM_STATUS_READY) {

    twi->status = TWIM_STATUS_BUSY;
    twi->result = TWIM_RESULT_UNKNOWN;

    twi->address = address<<1;

    /* Fill write data buffer. */
    for (uint8_t bufferIndex=0; bufferIndex < bytesToWrite; bufferIndex++) 
      {
        twi->writeData[bufferIndex] = writeRegister[bufferIndex];
      }

    twi->bytesToWrite = bytesToWrite;
    twi->bytesToRead = 0;
    twi->bytesWritten = 0;
    twi->bytesRead = 0;

    /* If write command, send the START condition + Address +
     * 'R/_W = 0'
     */
    if (twi->bytesToWrite > 0) 
    {
      uint8_t writeAddress = twi->address & ~0x01;
      twi->interface->MASTER.ADDR = writeAddress;
    }
  
    while (twi->status != TWIM_STATUS_READY)
    {}

    for (uint8_t bufferIndex=0; bufferIndex < bytesToWrite; bufferIndex++) 
    {
      twi->writeData[bufferIndex] = writeData[bufferIndex];
    }

    twi->bytesToWrite = bytesToWrite;
    twi->bytesToRead = 0;
    twi->bytesWritten = 0;
    twi->bytesRead = 0;

    if (twi->bytesToWrite > 0) 
    {
      uint8_t writeAddress = twi->address & ~0x01;
      twi->interface->MASTER.ADDR = writeAddress;
    }
    while (twi->status != TWIM_STATUS_READY)
    {}
    return true;
  } 
  else 
  {
    return false;
  }
}

Leider entspricht das noch nicht ganz dem im Datenblatt vom SX8723 
geforderten Aufbau, da nach dem Address Ack noch ein Start Kommando 
gesendet wird was eigentlich entfallen sollte. Hat jemand eine Idee wie 
ich das machen kann?
Im Anhang seht ihr die momentane Übertragung.

Gruß Andi

Autor: Sauger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

Andi M. schrieb:
> Dazu benutze ich die TWI Funktionen die Atmel in AVR1308 bereitstellt.

Andi M. schrieb:
> mit den mitgelieferten Funktionen nur die Möglichkeit :
> TWI_MasterWriteRead(sx8723_Register, 2,0)

Andi M. schrieb:
> zip: AVR1308 Application Note

dir ist schon klar das "Application Note" ein allgemeines Beispiel 
darstellt das zeigt dass es geht, aber nicht auf deine speziellen 
Bedürfnisse eingeht?

MfG

Autor: Andi M. (lesockz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja das ist es aber es passte in dem Fall halt schon ziemlich gut zu dem 
was ich wollte. Bis auf den kleinen Unterschied und ich wollte jetzt 
wissen ob es so wie ich es angepasst hab vernünftig ist oder ob man es 
noch "schöner" machen kann.

bzw. wie ich das mit der Stop Kondition noch verhindern kann

Autor: Dominik M. (lauso)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo ist das Problem?
Du rufst die Funktion zweimal auf.
Zuerst  rufst Du die TWI_MasterWriteRegisterData auf.
und schreibst Du die Slave Adresse und Memory Adresse.
Dann wird im nächsten Funktionsaufruf Slave Adresse und Data 
geschrieben.
Wenn ich das richtig sehe sollte das Klappen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.