-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 13

Thema: WinAVR und SIG_2WIRE_SERIAL

  1. #1
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    47
    Beiträge
    497

    WinAVR und SIG_2WIRE_SERIAL

    Anzeige

    Hi,

    möchte einen TWI slave mit WinAVR programmieren

    weiß allerdings nicht wie ich die isr definieren soll

    im AN311 von ATMEL stand:

    #pragma vector=TWI_vect
    __interrupt void TWI_ISR( void )

    Da ging aber schon das pragma nicht. Muss ich vielleicht pragma irgendwie erst zulassen?

    Habe deshalb

    INTERRUPT(SIG_2WIRE_SERIAL)
    {
    ...
    }

    probiert.

    Hier sagt der Compiler:
    Compiling: TWI_slave.c
    avr-gcc -c -mmcu=atmega32 -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=TWI_slave.lst -std=gnu99 TWI_slave.c -o TWI_slave.o
    TWI_slave.c:149: warning: return type defaults to `int'
    TWI_slave.c:149: warning: function declaration isn't a prototype
    TWI_slave.c: In function `INTERRUPT':
    TWI_slave.c:149: warning: type of "__vector_19" defaults to "int"
    TWI_slave.c:223: warning: control reaches end of non-void function

    verstehe ich nicht. Wie kann ein Interrupt einen int zurückgeben? Und an wen?

    Wie muss ich denn nun die isr definieren?

    sast

  2. #2
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    47
    Beiträge
    497
    Fehlermeldung hat sich gerade erübrigt.

    hab mal die signal.h eingebunden und anstelle von INTERRUPT SIGNAL eingegeben.

    sorry

    sast

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    INTERRUPT macht etwas anderes als SIGNAL.
    INTERRUPT macht im ISR-Prolog zusätzlich ein SEI.
    Disclaimer: none. Sue me.

  4. #4
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    47
    Beiträge
    497
    Hi Georg-Johann,
    danke erst mal für deine Antwort.

    Was heißt das jetzt für mich?

    sast

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    01.08.2005
    Ort
    49.80248 8.59252
    Alter
    33
    Beiträge
    172
    Dass SIGNAL das Richtige fuer dich ist.
    INTERRUPT brauchst du nur wenn du in der ISR weiter Interrupts zulassen willst.

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Mit SIGNAL hast du eine 'normale' Interrupt-Routine wie sie AVR vorsieht, d.h. der AVR-Core setzt vorm Sprung zum IRQ-Vektor das I-Flag im SREG. Dadurch kann eine ISR nicht von anderen IRQs unterbrochen werden.
    Mit INTERRUPT wird ein SEI eingefügt, wodurch Interrupts geschachtelt werden können. Deine ISR wird also durch eine andere IRQ unterbrechbar.

    AVRs haben die Schwäche, daß man IRQs nicht priorisieren kann wie bei manch anderem µC. Lässt man geschachtelte IRQs zu, kann man diese Schwäche teilweise wieder beheben.
    Disclaimer: none. Sue me.

  7. #7
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    47
    Beiträge
    497
    OK

    Danke für die Hilfe

    sast

  8. #8
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    47
    Beiträge
    497
    Doch noch mal was zum I2C

    Mein Slave empfängt jetzt zwar das vom Master gesendete Byte und gibt auch ein ACK zurück, aber nachdem der Master ein Stop und danach ein Start bit gesendet hat zieht der Slave den Clock auf 0 und läßt ihn auch nicht wieder los.

    Wie schon gesagt verwende ich die TWI_slave.c aus dem AppNote AN311 ist da vielleicht irgendeine Flageinstellung verkehrt?

    Ich stelle mal die ISR rein und bitte um eure mithilfe.

    sast

    SIGNAL(SIG_2WIRE_SERIAL)
    {
    static unsigned char TWI_bufPtr;

    switch (TWSR)
    {
    case TWI_STX_ADR_ACK: // Own SLA+R has been received; ACK has been returned
    // case TWI_STX_ADR_ACK_M_ARB_LOST: // Arbitration lost in SLA+R/W as Master; own SLA+R has been received; ACK has been returned
    TWI_bufPtr = 0; // Set buffer pointer to first data location
    case TWI_STX_DATA_ACK: // Data byte in TWDR has been transmitted; ACK has been received
    TWDR = TWI_buf[TWI_bufPtr++];
    TWCR = (1<<TWEN)| // TWI Interface enabled
    (1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag to send byte
    (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| //
    (0<<TWWC); //
    break;
    case TWI_STX_DATA_NACK: // Data byte in TWDR has been transmitted; NACK has been received.
    // I.e. this could be the end of the transmission.
    if (TWI_bufPtr == TWI_msgSize) // Have we transceived all expected data?
    {
    TWI_statusReg.lastTransOK = TRUE; // Set status bits to completed successfully.
    }else // Master has sent a NACK before all data where sent.
    {
    TWI_state = TWSR; // Store TWI State as errormessage.
    }
    // Put TWI Transceiver in passive mode.
    TWCR = (1<<TWEN)| // Enable TWI-interface and release TWI pins
    (0<<TWIE)|(0<<TWINT)| // Disable Interupt
    (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Do not acknowledge on any new requests.
    (0<<TWWC); //
    break;
    case TWI_SRX_GEN_ACK: // General call address has been received; ACK has been returned
    // case TWI_SRX_GEN_ACK_M_ARB_LOST: // Arbitration lost in SLA+R/W as Master; General call address has been received; ACK has been returned
    TWI_statusReg.genAddressCall = TRUE;
    case TWI_SRX_ADR_ACK: // Own SLA+W has been received ACK has been returned
    // case TWI_SRX_ADR_ACK_M_ARB_LOST: // Arbitration lost in SLA+R/W as Master; own SLA+W has been received; ACK has been returned
    // Dont need to clear TWI_S_statusRegister.generalAddressCall due to that it is the default state.
    TWI_statusReg.RxDataInBuf = TRUE;
    TWI_bufPtr = 0; // Set buffer pointer to first data location
    // Reset the TWI Interupt to wait for a new event.
    TWCR = (1<<TWEN)| // TWI Interface enabled
    (1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag to send byte
    (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Expect ACK on this transmission
    (0<<TWWC); //
    break;
    case TWI_SRX_ADR_DATA_ACK: // Previously addressed with own SLA+W; data has been received; ACK has been returned
    case TWI_SRX_GEN_DATA_ACK: // Previously addressed with general call; data has been received; ACK has been returned
    TWI_buf[TWI_bufPtr++] = TWDR;
    TWI_statusReg.lastTransOK = TRUE; // Set flag transmission successfull.
    // Reset the TWI Interupt to wait for a new event.
    TWCR = (1<<TWEN)| // TWI Interface enabled
    (1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag to send byte
    (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Send ACK after next reception
    (0<<TWWC); //
    break;
    case TWI_SRX_STOP_RESTART: // A STOP condition or repeated START condition has been received while still addressed as Slave
    // Put TWI Transceiver in passive mode.
    TWCR = (1<<TWEN)| // Enable TWI-interface and release TWI pins
    (0<<TWIE)|(0<<TWINT)| // Disable Interupt
    (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Do not acknowledge on any new requests.
    (0<<TWWC); //
    break;
    case TWI_SRX_ADR_DATA_NACK: // Previously addressed with own SLA+W; data has been received; NOT ACK has been returned
    case TWI_SRX_GEN_DATA_NACK: // Previously addressed with general call; data has been received; NOT ACK has been returned
    case TWI_STX_DATA_ACK_LAST_BYTE: // Last data byte in TWDR has been transmitted (TWEA = “0”); ACK has been received
    // case TWI_NO_STATE // No relevant state information available; TWINT = “0”
    case TWI_BUS_ERROR: // Bus error due to an illegal START or STOP condition
    default:
    TWI_state = TWSR; // Store TWI State as errormessage, operation also clears the Success bit.
    TWCR = (1<<TWEN)| // Enable TWI-interface and release TWI pins
    (0<<TWIE)|(0<<TWINT)| // Disable Interupt
    (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Do not acknowledge on any new requests.
    (0<<TWWC); //
    }
    }

  9. #9
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    47
    Beiträge
    497
    wie immer bin ich einfach zu schnell mit meiner Fragerei.

    Habs allein gefunden. Man muss nach dem Empfang von Daten den Transceiver neu starten, dann gehts.

    Verstehe ich aber nicht so richtig. Was ist wenn ich das nicht will? Dann kann solange der gesamte Bus nicht weiter.

    Hat jemand vielleicht eine andere Lösung des Problems TWI_Slave.

    sast

  10. #10
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Das TWINT-Flag muss man von Hand zurücksetzen, das macht die ISR nicht automatisch. Wenn man es nicht rücksetzt, sagt der Slave mit dem Clock-Stretch, daß er noch busy ist.

    Dein Code bliebe im [code]-Tag *etwas* lesbarer...
    Oder sehen so deine Quellen aus
    Disclaimer: none. Sue me.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •