-
+ Antworten
Ergebnis 1 bis 2 von 2

Thema: Frage zu TWI-Programmierung

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    02.02.2009
    Beiträge
    19

    Frage zu TWI-Programmierung

    Hallo!

    Als Vorübung zu meinem nächsten Projekt habe ich zwei AT-Mega8 per TWI verbunden. Die Codes habe ich den Datenblättern und div. Anleitungen entnommen, teilweise auch vom myAVR-CodeWizard.

    Die erste MCU bekommt Daten per USB vom PC (funktioniert) und soll sie per TWI zur zweiten MCU übertragen. Die zweite MCU soll empfangene Daten per LCD darstellen.

    Nun funktioniert aber leider die Kommunikation nicht

    Wo kann der Fehler liegen? Zur Vereinfachung habe ich nur Auszüge meiner Sourcecodes angehängt:

    Master
    Code:
    ;Vorübung für Krabbler: Experimentierplatine an PC über USB, LCD-Erweiterung angeschlossen
    ;a- Zeichen, vom PC gesendet, werden auf dem LCD angezeigt   --------------- erfolgreich beendet
    ;b- beide Experimentierplatinen über TWI verbinden, Daten von PC über beide Platinen auf LCD darstellen 
    ;c- endgültige Krabblersoftware erstellen
    ;+-----------------------------------------------------------------------------
    ;| Titel                            : Krabbler - Vorübung b-
    ;+-----------------------------------------------------------------------------
    ;| Funktion                         : Empfang von Daten vom PC durch MCU, Übertragung auf andere MCU per TWI
    ;|                   : Ausgabe der Zeichen auf dem LCD-Modul
    ;| Schaltung                        : zwei MK2USB-Boards verbunden Port C4 und C5 (TWI) und Spannungsversorgung
    ;|                   : Netzteil angeschlossen
    ;|                   : Port D2 = RS, D3 = E, D4-7 = DB4-7, für LCD
    ;+-----------------------------------------------------------------------------
    ;| Prozessor                        : ATmega8
    ;| Takt                             : 3,6864 MHz
    ;| Sprache                          : Assembler
    ;| Datum                            : 5.4.2012
    ;| Version                          : 2 Teil a
    ;| Autor                            : U.S. / Routinen myAVR
    ;+-----------------------------------------------------------------------------
    .include        "AVR.H"
    .equ F_CPU,3686400
    .equ TWI_CLOCK,100000 ; Geschwindigkeit des TWI-Busses ca., durch Rundungsfehler etwas höher
    .equ FCPU,3686400
    .equ BAUD,9600
    .equ Temp,0x10  ; r16 wird zur Übergabe an Unterprogramme benutzt
    .equ ZSP,0x13  ; r19 Zwischenspeicher für empfangene Zeichen
    ;-----------------------------------------------------------------------------
    begin:  rjmp main ;  RESET External Pin, Power-on Reset, Brown-out Reset and Watchdog Reset
            reti  ;  INT0 External Interrupt Request 0
     reti  ;  INT1 External Interrupt Request 1
     reti  ;  TIMER2 COMP Timer/Counter2 Compare Match
     reti  ;  TIMER2 OVF Timer/Counter2 Overflow
     reti  ;  TIMER1 CAPT Timer/Counter1 Capture Event
     reti  ;  TIMER1 COMPA Timer/Counter1 Compare Match A
     reti  ;  TIMER1 COMPB Timer/Counter1 Compare Match B
     reti  ;  TIMER1 OVF Timer/Counter1 Overflow
     reti  ;  TIMER0 OVF Timer/Counter0 Overflow
     reti  ;  SPI, STC Serial Transfer Complete
     reti  ;  USART, RXC USART, Rx Complete
     reti  ;  USART, UDRE USART Data Register Empty
     reti  ;  USART, TXC USART, Tx Complete
     reti  ;  ADC ADC Conversion Complete
     reti  ;  EE_RDY EEPROM Ready
     reti  ;  ANA_COMP Analog Comparator
     reti  ;  TWI 2-wire Serial Interface
     reti  ;  SPM_RDY Store Program Memory Ready
    ;------------------------------------------------------------------------------
    main: ldi Temp,hi8(RAMEND) ; Main program start
     out SPH,Temp ; Set Stack Pointer to top of RAM
     ldi Temp,lo8(RAMEND)
     out SPL,Temp
     rcall UART_init 
     rcall twiInitMaster
     sbi DDRB,0 
     sbi DDRB,1 
    ;------------------------------------------------------------------------------
    mainloop: rcall UART_Empf ; wartet auf Empfang und übergibt das empfangene Zeichen in ZSP
     rcall   AnzeigeRot
     rcall  twiStart
     ldi  r16,0b11111110 ; Slave-Adresse + W
     rcall twiWriteByte
     mov  r16,ZSP ; Zeichen wird in Register 16 an TWI-Schreibroutine übergeben
     rcall twiWriteByte
     rcall twiStopp
     rcall   AnzeigeGelb
     rjmp mainloop
    ;------------------------------------------------------------------------------
    UART Routinen sind ausgelassen - funktionsfähig
    ;-----------------------------------------------------------------------------
    ; twiInitMaster (ohne Interrupt)
    ; gestattet die Benutzung von TWI und setzt die Master-Clock-Rate
    ;-----------------------------------------------------------------------------
    twiInitMaster:
      push  r16
      ; Clock
      ldi  r16,10  ;((F_CPU/TWI_CLOCK)-16)/2
      out  TWBR,r16
      ;TWI-Status-Register (Vorteiler)
      ldi  r16,0
      out  TWSR,r16
      ; Enable
      ldi  r16,0b11000100 ;_TWINT _TWEA _TWEN
      out  TWCR,r16
      pop  r16
      ret
    ;------------------------------------------------------------------------
    twiStart:  
      push  r16
      ldi  r16,0b10100100 ; TWINT TWSTA TWEN
      out  TWCR,r16
      rcall twiTWINTwarten ; warten bis TWINT gesetzt
      pop  r16
      ret
    ;------------------------------------------------------------------------
    twiStopp:    
      push  r16
      ldi  r16,0b10010100 ; TWINT TWSTO TWEN
      out  TWCR,r16
      pop  r16
      ret
    ;------------------------------------------------------------------------
    twiWriteByte:  ; Write Byte per TWI (ohne Interrupt)
      push  r16 ; Daten in Reg 16 übergeben
      out  TWDR,r16  ; Daten bereitlegen
      ldi  r16,0b11000100 ; TWINT TWEA TWEN   (->ACK??)
      out  TWCR,r16  ; senden
      rcall twiTWINTwarten ; warten bis TWINT gesetzt
      pop  r16
      ret
    ;------------------------------------------------------------------------
    twiTWINTwarten:
     in  r16,TWCR
      sbrs  r16,7  ; TWINT
      rjmp  twiTWINTwarten
      ret
    ;------------------------------------------------------------------------------
    AnzeigeRot: ;LED-Anzeige als Funktionstest
    Slave
    Code:
    ;Vorübung für Krabbler: Experimentierplatine an PC über USB, LCD-Erweiterung angeschlossen
    ;a- Zeichen, vom PC gesendet, werden auf dem LCD angezeigt   --------------- erfolgreich beendet
    ;b- beide Experimentierplatinen über TWI verbinden, Daten von PC über beide Platinen auf LCD darstellen 
    ;c- endgültige Krabblersoftware erstellen
    ;+-----------------------------------------------------------------------------
    ;| Titel                            : Krabbler - Vorübung b-
    ;+-----------------------------------------------------------------------------
    ;| Funktion                         : Empfang von Daten vom PC durch MCU, Übertragung auf andere MCU per TWI
    ;|                   : Ausgabe der Zeichen auf dem LCD-Modul
    ;| Schaltung                        : zwei MK2USB-Boards verbunden Port C4 und C5 (TWI) und Spannungsversorgung
    ;|                   : Netzteil angeschlossen
    ;|                   : Port D2 = RS, D3 = E, D4-7 = DB4-7, für LCD
    ;+-----------------------------------------------------------------------------
    ;| Prozessor                        : ATmega8
    ;| Takt                             : 3,6864 MHz
    ;| Sprache                          : Assembler
    ;| Datum                            : 4.4.2012
    ;| Version                          : 2 Teil b
    ;| Autor                            : U.S. / Routinen myAVR
    ;+-----------------------------------------------------------------------------
    .include        "AVR.H"
    .equ F_CPU,3686400
    .equ TWI_CLOCK,100000 ; Geschwindigkeit des TWI-Busses ca.
    .equ FCPU,3686400
    .equ BAUD,9600
    .equ Temp,0x10  ; r16 wird zur Übergabe an Unterprogramme benutzt
    .equ ZSP,0x13  ; r19 Zwischenspeicher für empfangene Zeichen
    ;-----------------------------------------------------------------------------
    begin:  rjmp main ;  RESET External Pin, Power-on Reset, Brown-out Reset and Watchdog Reset
            reti  ;  INT0 External Interrupt Request 0
     reti  ;  INT1 External Interrupt Request 1
     reti  ;  TIMER2 COMP Timer/Counter2 Compare Match
     reti  ;  TIMER2 OVF Timer/Counter2 Overflow
     reti  ;  TIMER1 CAPT Timer/Counter1 Capture Event
     reti  ;  TIMER1 COMPA Timer/Counter1 Compare Match A
     reti  ;  TIMER1 COMPB Timer/Counter1 Compare Match B
     reti  ;  TIMER1 OVF Timer/Counter1 Overflow
     reti  ;  TIMER0 OVF Timer/Counter0 Overflow
     reti  ;  SPI, STC Serial Transfer Complete
     reti  ;  USART, RXC USART, Rx Complete
     reti  ;  USART, UDRE USART Data Register Empty
     reti  ;  USART, TXC USART, Tx Complete
     reti  ;  ADC ADC Conversion Complete
     reti  ;  EE_RDY EEPROM Ready
     reti  ;  ANA_COMP Analog Comparator
     reti  ;  TWI 2-wire Serial Interface
     reti  ;  SPM_RDY Store Program Memory Ready
    ;------------------------------------------------------------------------------
    main: ldi Temp,hi8(RAMEND) ; Main program start
     out SPH,Temp ; Set Stack Pointer to top of RAM
     ldi Temp,lo8(RAMEND)
     out SPL,Temp
     rcall LCD_init 
     rcall LCD_clear 
     rcall twiInitSlave
     sbi DDRB,0 
    ;------------------------------------------------------------------------------
    mainloop: ; warten bis TWINT
     in  r16,TWCR
      sbrs  r16,7  ;TWINT gesetzt?
      rjmp  mainloop
      rcall   AnzeigeRot ;Funktionstest rote LED für 200 mS an
      in  r16,TWDR
      ;ldi r16,60  ; Testdaten
      rcall LCD_data  ; Zeichen aus Register16 auf LCD ausgeben 
     rjmp mainloop
    ;------------------------------------------------------------------------------   
    ;LCD-Routinen ausgelassen - funktionsfähig
    ;-----------------------------------------------------------------------------
    ;-----------------------------------------------------------------------------
    twiInitSlave:
      push  r16
      ldi  r16,0b11111110 ;TWI_Slave_Adresse ohne General Call
      out  TWAR,r16 ; Adressregister
       ldi  r16,0b11000101 ; TWINT TWEA TWEN TWIE
      out  TWCR,r16 ; Enable
      pop  r16
      ret
    ;------------------------------------------------------------------------------
    AnzeigeRot: ; LED für 200 mS an
    U.

  2. #2
    Neuer Benutzer Öfters hier
    Registriert seit
    02.02.2009
    Beiträge
    19
    Funktioniert jetzt.
    Die bisher im Netz zu findenden Sourcecodes sind immer sehr umfangreich. Deswegen habe ich den Quellcode auf das Minimum reduziert, keine Fehlerroutinen etc.
    Interrupts waren nicht gewünscht.
    Der Teil Slave muss noch verbessert werden - drei Schleifen Mainloop sind nicht wirklich elegant.
    Über Rückmeldungen oder Fragen werde ich mich freuen.
    U.

    Master:
    Code:
    ; zwei ATMega8 sind per TWI verbunden
    
    .equ ZSP,0x13  ; r19 Zwischenspeicher für empfangene Zeichen
    
    ;-----------------------------------------------------------------------------
    begin:  rjmp main ;  RESET External Pin, Power-on Reset, Brown-out Reset and Watchdog Reset
            reti  ;  INT0 External Interrupt Request 0
     reti  ;  INT1 External Interrupt Request 1
     reti  ;  TIMER2 COMP Timer/Counter2 Compare Match
     reti  ;  TIMER2 OVF Timer/Counter2 Overflow
     reti  ;  TIMER1 CAPT Timer/Counter1 Capture Event
     reti  ;  TIMER1 COMPA Timer/Counter1 Compare Match A
     reti  ;  TIMER1 COMPB Timer/Counter1 Compare Match B
     reti  ;  TIMER1 OVF Timer/Counter1 Overflow
     reti  ;  TIMER0 OVF Timer/Counter0 Overflow
     reti  ;  SPI, STC Serial Transfer Complete
     reti  ;  USART, RXC USART, Rx Complete
     reti  ;  USART, UDRE USART Data Register Empty
     reti  ;  USART, TXC USART, Tx Complete
     reti  ;  ADC ADC Conversion Complete
     reti  ;  EE_RDY EEPROM Ready
     reti  ;  ANA_COMP Analog Comparator
     reti  ;  TWI 2-wire Serial Interface
     reti  ;  SPM_RDY Store Program Memory Ready
    ;------------------------------------------------------------------------------
    main: ldi Temp,hi8(RAMEND) ; Main program start
     out SPH,Temp ; Set Stack Pointer to top of RAM
     ldi Temp,lo8(RAMEND)
     out SPL,Temp
     ;.................. 
     rcall twiInitMaster
    ;------------------------------------------------------------------------------
    mainloop: ; zu sendende Daten liegen im Register ZSP
     rcall  twiStart
     ldi  r16,0b11111110 ; Slave-Adresse + W
     rcall twiWriteByte
     mov  r16,ZSP ; Zeichen wird in Register 16 an TWI-Schreibroutine übergeben
     rcall twiWriteByte
     rcall twiStopp
     rjmp mainloop
    ;-----------------------------------------------------------------------------
    twiInitMaster:
      push  r16
      ; Clock
      ldi  r16,10  ;((F_CPU/TWI_CLOCK)-16)/2
      out  TWBR,r16
      ;TWI-Status-Register (Vorteiler)
      ldi  r16,0
      out  TWSR,r16
      ; Enable
      ldi  r16,0b11000100 ;_TWINT _TWEA _TWEN
      out  TWCR,r16
      pop  r16
      ret
    ;------------------------------------------------------------------------
    twiStart:  
      push  r16
      ldi  r16,0b10100100 ; TWINT TWSTA TWEN
      out  TWCR,r16
      rcall twiTWINTwarten ; warten bis TWINT gesetzt
      pop  r16
      ret
    ;------------------------------------------------------------------------
    twiStopp:    
      push  r16
      ldi  r16,0b10010100 ; TWINT TWSTO TWEN
      out  TWCR,r16
      pop  r16
      ret
    ;------------------------------------------------------------------------
    twiWriteByte:  
      push  r16 ; Daten in Reg 16 übergeben
      out  TWDR,r16  ; Daten bereitlegen
      ldi  r16,0b10000100 ; TWINT  TWEN  
      out  TWCR,r16  ; senden
      rcall twiTWINTwarten ; warten bis TWINT gesetzt
      pop  r16
      ret
    ;------------------------------------------------------------------------
    twiTWINTwarten:
     in  r16,TWCR
      sbrs  r16,7  ; TWINT
      rjmp  twiTWINTwarten
      ret
    ;------------------------------------------------------------------------------
    Slave:
    Code:
    .include        "AVR.H"
    .equ Temp,0x10  ; r16 wird zur Übergabe an Unterprogramme benutzt
    ;-----------------------------------------------------------------------------
    begin:  rjmp main ;  RESET External Pin, Power-on Reset, Brown-out Reset and Watchdog Reset
            reti  ;  INT0 External Interrupt Request 0
     reti  ;  INT1 External Interrupt Request 1
     reti  ;  TIMER2 COMP Timer/Counter2 Compare Match
     reti  ;  TIMER2 OVF Timer/Counter2 Overflow
     reti  ;  TIMER1 CAPT Timer/Counter1 Capture Event
     reti  ;  TIMER1 COMPA Timer/Counter1 Compare Match A
     reti  ;  TIMER1 COMPB Timer/Counter1 Compare Match B
     reti  ;  TIMER1 OVF Timer/Counter1 Overflow
     reti  ;  TIMER0 OVF Timer/Counter0 Overflow
     reti  ;  SPI, STC Serial Transfer Complete
     reti  ;  USART, RXC USART, Rx Complete
     reti  ;  USART, UDRE USART Data Register Empty
     reti  ;  USART, TXC USART, Tx Complete
     reti  ;  ADC ADC Conversion Complete
     reti  ;  EE_RDY EEPROM Ready
     reti  ;  ANA_COMP Analog Comparator
     reti  ;  TWI 2-wire Serial Interface
     reti  ;  SPM_RDY Store Program Memory Ready
    ;------------------------------------------------------------------------------
    main: ldi Temp,hi8(RAMEND) ; Main program start
     out SPH,Temp ; Set Stack Pointer to top of RAM
     ldi Temp,lo8(RAMEND)
     out SPL,Temp
     ;.................. 
     rcall twiInitSlave
    ;------------------------------------------------------------------------------
    mainloop: ; warten bis TWINT
     in  r16,TWCR
      sbrs  r16,7  ;TWINT
      rjmp  mainloop
      ;der Slave wurde adressiert
     ldi  r16,0b11000100 ; TWINT TWEA TWEN  ->ACK an Master
      out  TWCR,r16
    ml2: in  r16,TWCR
      sbrs  r16,7  ;TWINT
      rjmp  ml2
      in  r20,TWDR ; Daten sind eingetroffen
     ldi  r16,0b11000100 ; TWINT TWEA TWEN  ->ACK an Master
      out  TWCR,r16
    ml3: in  r16,TWCR  
      sbrs  r16,7  ;TWINT
      rjmp  ml3
      ;Stoppbedingung muss quittiert werden
     ldi  r16,0b11000100 ; TWINT TWEA TWEN  ->ACK an Master
      out  TWCR,r16
      
      ; die empfangenen Daten liegen jetzt in Register R20 zur weiteren Verarbeitung
     rjmp mainloop
    ;------------------------------------------------------------------------------   
    twiInitSlave:   ;ohne Interrupt
      push  r16
      ldi  r16,0b11111110 ;TWI_Slave_Adresse ohne General Call
      out  TWAR,r16 ; Adressregister
       ldi  r16,0b01000100 ;  TWEA TWEN 
      out  TWCR,r16 ; Enable
      pop  r16
      ret

+ Antworten

Ähnliche Themen

  1. Frage zu Programmierung Nibobee
    Von m125 im Forum Sonstige Roboter- und artverwandte Modelle
    Antworten: 26
    Letzter Beitrag: 31.07.2011, 18:37
  2. Frage zur Programmierung des RN-Control (Bascom)
    Von Rumpelfuss im Forum Controller- und Roboterboards von RobotikHardware.de
    Antworten: 5
    Letzter Beitrag: 23.03.2010, 13:31
  3. [ERLEDIGT] Frage zu serieller HV-Programmierung
    Von Henry im Forum AVR Hardwarethemen
    Antworten: 3
    Letzter Beitrag: 21.08.2009, 17:21
  4. Anfäger frage über C Programmierung
    Von SimLock im Forum C - Programmierung (GCC u.a.)
    Antworten: 11
    Letzter Beitrag: 07.11.2007, 16:22
  5. Generelle Frage zur Programmierung (RobbyRP5)
    Von BananenFresser im Forum Robby CCRP5
    Antworten: 4
    Letzter Beitrag: 07.11.2005, 19:05

Berechtigungen

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