USI - Übertragung zwischen Slave und Master geht nicht

Dieses Thema im Forum "Software" wurde erstellt von achim S., 10. Februar 2019.

  1. achim S.

    achim S. Mitglied

    Registriert seit:
    16. Januar 2010
    Beiträge:
    423
    Zustimmungen:
    6
    Punkte für Erfolge:
    18
    Sprachen:
    C
    Hallo
    Zur Übertragung mit USI zwischen einem Master (Atmega1284p) und einem Slave (Attiny2313) verwende ich USI. Vom Master zum Slave geht es ohne Probleme. Vom Slave zum Master geht es nicht. Verwende zusätzlich noch ein LCD zur Anzeige von Text und Daten. Vielleicht jemand von euch Idee woran es liegt.
    Code für den Master:


    CodeBox C und C++
    #include <stdbool.h>
           #include <avr/pgmspace.h>
           #include "main.h"
           #include <util/delay.h>
           #include "i2clcd.h"
           #include "i2cmaster.h"
           #include "avr/io.h"
           #include "util/delay.h"
           #include "avr/interrupt.h"
           
           #define slave_adresse 0x52               // Slave Adresse schreiben
           #define slave_adresse_r 0x53              // Slave Adresse lesen
           
           uint8_t ret;                             // Kontrollvariable ob Slave vorhanden
           uint8_t byte1, byte2;                           // Daten zum Senden vom Master zu Slave
           uint8_t byte3, byte4;
           uint8_t byte10;                           // Daten zum holen vom Slave zu Master
           uint8_t wert;
           
    ///////////////////////////////////////////////////////////////////////////////////////////////////
       void startanzeige()                           // Titelbild
         {
           lcd_command(LCD_CLEAR);                   // Leere Display
           _delay_ms(2);                             // Warte 2ms
           lcd_printlc(1,2,"USI Bus M-Prg1");            // Zeile 1
           lcd_printlc(2,2,"Verbindung von");       // Zeile 2
           lcd_printlc(3,2,"Prz ueber I2C ");       // Zeile 3
           lcd_printlc(4,2,"(by P.)");       // Zeile 4
           _delay_ms(3000);                         // Warte 5000ms
         }
    ///////////////////////////////////////////////////////////////////////////////////////////////////
       void slavetest()                           // Abfrage Slave, Fehlermeldung und Anzeige
         {                                           // Abfarge ob Slave vorhanden ist
           ret = i2c_start(slave_adresse);           // Start i2C mit Adresse Slave
           i2c_write(0x00);                       // Sende Daten
           i2c_stop();                               // I2C Stop
           if (ret == 0)                           // Bus ok - 0, kein Bus 1
             {                                       // Anzeige Slave ok
               lcd_command(LCD_CLEAR);               // Leere Display
               _delay_ms(2);                         // Warte 2ms
               lcd_printlc(2,4,"Slave ist ");       // Ausgabe Text
               lcd_printlc(3,5,"OK !!!!!");       // Slave OK
               _delay_ms(2000);                     // Warte 2s
             }
           else                                   // Fehlermeldung
             {                                       // Anzeige Slave nicht ok
               lcd_command(LCD_CLEAR);               // Leere Display
               _delay_ms(2);                         // Warte 2ms
               lcd_printlc(2,5,"Slave ist");       // Ausgabe Schrift
               lcd_printlc(3,5,"Nicht OK");       // Slave Nicht O
               _delay_ms(2000);                     // Warte 2s
             }
           lcd_command(LCD_CLEAR);                   // Leere Display
           _delay_ms(2);                             // Warte 2ms  
           lcd_printlc(1,1,"Taste aus ");   // Ausgabe Text             
         }
    /////////////////////////////////////////////////////////////////////////////////////////////////////  
       void s_write (uint8_t wert)                       // schreibe Daten 2 von Master zu Slave
         {
           i2c_start(slave_adresse);               // Slave ist bereit zum Schreiben
           i2c_write(0x00);                        // Buffer Startadresse setzen
           i2c_write(wert);                        // Drei Bytes schreiben...   43
           i2c_stop();                             // Zugriff beenden
         }
    /////////////////////////////////////////////////////////////////////////////////////////////////
       void s_read1()                               // lese Slave1
         {
           i2c_start(slave_adresse);               // Start Bus schreiben
           i2c_write(0x00);                   
           i2c_rep_start(slave_adresse);           // starte Slave lesen
           byte3=i2c_readAck();                   // 2. Byte lesen und in "gelesen" ablegen
           byte4=i2c_readNak();                   // letztes Byte lesen, darum kein ACK
           i2c_stop();                               // Zugriff beenden   
         }
    ////////////////////////////////////////////////////////////////////////////////////////////////
       int main(void)
         {
           cli();                                     // Interrupts deaktiviert
           i2c_init();                               // Starte I2C Bus
           lcd_init();                               // Starte I2CLCD       
           // Display Befehle
           lcd_command(LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKINGOFF);
           lcd_light(0);                           // Licht an
           startanzeige();
           lcd_command(LCD_CLEAR);                   // Leere Display
           _delay_ms(2);                             // Warte 2ms
           slavetest();
           _delay_ms(2);
           
           DDRC=0b01100000;       //Taster       // setzt Port C auf Ausgang, PC5 und PC6
           DDRA=0b11111111;       //LED           // setzt Port A auf Ausgang, PC5 und PC6
               
           PORTC|=0b01001111;       //Taster       // Deaktiviere Ports C5-6 (LEDs aus)
           PORTA|=0b11111111;       //LED           // Deaktiviere Pins A0-7 (LEDs aus)
           
           while(1)
             {
               // ========>> AUF GELESENE DATEN REAGIEREN
               s_read1();       
               
               if (byte4 == 30)               
                 {                                   // Wenn Wert 30 gelesen wurde...
                     PORTC &= ~((1<<PINC5));       // schalte Port A6  
                   PORTC |=(1<<PINC6);               // wenn nicht lösche Port A6  
                 }
               else
                 {   
                   PORTC |=(1<<PINC5);               // wenn nicht lösche Port A6
                   PORTC &= ~((1<<PINC6));       // schalte Port A6  
                 }
               /*if (byte4 == 40)
                 {                                   // Wenn Wert 40 gelesen wurde...   
                   //PORTC &=~(1<<PINC6);           // schalte Port A7 ein
                 }
               else
                 {
                   //PORTC |=(1<<PINC6);               // wenn nicht lösche
                 }    */
       ///////////////////////////////////////////////////////////////////////////////////////////////     
               // ========>> TASTENEINGABEN T1
               if (!(PINC & (1<<PINC2)) )           // Taster T1
                 {                                   // Wenn T1 gedrückt...
                   PORTA &=~(1<<PINA2);           // LED 2 A1 ein
                   s_write(42);                   // Schreib 1 Funktion aufrufen
                   lcd_printlc(1,1,"Taste 1   ");   // Ausgabe Text
                 }
               else
                 {
                   PORTA |=(1<<PINA1);               // sonst LED 2 A1 aus
                 }
               // ========>> TASTENEINGABEN T3
               if (!(PINC & (1<<PINC4)) )           // Taster T 3
                 {                                   // Wenn T3 gedrückt...
                   PORTA &=~(1<<PINA1);           // LED 3 A2 ein
                   s_write(43);                   // Schreib 2 Funktion aufrufen
                   lcd_printlc(1,1,"Taste 2   ");   // Ausgabe Text       
                 }
               else
                 {
                   PORTA |=(1<<PINA2);               // sonst LED 3 aus
                 }
       /////////////////////////////////////////////////////////////////////////////////////////////////
              /* // vom Slave lesen
               if (!(PINC & (1<<PINC3)) )           // Taster T2 mitte
                 {                                   // Wenn T 2 gedrückt...
                   PORTC &=~(1<<PINC5);           // LED  6 A5 ein   
                   //s_read1();                       // ...Lese-Funktion aufrufen
                 }
               else
                 {
                   PORTC |=(1<<PINC5);               // LED 6 A5 aus
                 }*/                           
             }
            }
    

    Code für den Slave:


    CodeBox C und C++
    #define F_CPU 16000000UL
    #include <stdlib.h>                               // für den Ati 2313A im usiTwiSlave.c A zufügen
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>
    #include "usiTwiSlave.h"
    
    
    #define slave_adresse 0x52                       // Adresse Slave
    
    uint8_t  byte1, byte2, byte3, byte4;
    uint16_t buffer;
    
    int main(void)
      {
       cli();                                       // Interrupts aus
       usiTwiSlaveInit(slave_adresse);               // Init TWI slave
       sei();                                       // Interrupts ein
       
       DDRD=0b00111000;                           // setze Taster + LED DDR D       
       //DDRB=0b10100111;                           // setze LED DDR B               
       
       PORTD|=0b00111000;                           // setze Taster + LED Port D
       //PORTB|=0b00000111;                       // setze LED Port B
       
       while(1)
         {     
           byte1 = rxbuffer[0];                   // schreibe Daten in den Eingangspuffer
           byte2 = rxbuffer[1];
       ///////////////////////////////////////////////////////////////////////   
           if (byte1==43)                           // Abfrage byte1 auf 43
             {                                       // wenn dann ...
               PORTD &=~(1<<PIND5);               // LED 2 B1 ein
               PORTD |=(1<<PIND4);                   // LED 3 B2 aus
             }
           if (byte1==42)                           // Abfrage byte1 auf 42
             {                                       // wenn dann ...
               PORTD &=~(1<<PIND4);               // LED 3 B2 ein
               PORTD |=(1<<PIND5);                   // LED 2 B1 aus   
             }
       //////////////////////////////////////////////////////////////////////   
           if (PIND & (1<<PIND0))                    // Taster T2 PD0
             {                                       // Wenn T1 gedrückt...
               byte3=40;                           // setze byte3 auf 40
               PORTD |=(1<<PIND3);                   // LED 4 D5 aus   
             }
           else
             {
               PORTD &=~(1<<PIND3);               // LED 4 D5 ein
               byte4=30;                           // setze byte4 auf 30
             }
           txbuffer[0]=byte3;                       // byte10 in den Sendepuffer auf [0]
           txbuffer[1]=byte4;
         }                                           // end.while
        }                                           // end.main
    

    Vielleicht hat jemand eine Idee dazu.
    achim
     
  2. achim S.

    achim S. Mitglied

    Registriert seit:
    16. Januar 2010
    Beiträge:
    423
    Zustimmungen:
    6
    Punkte für Erfolge:
    18
    Sprachen:
    C
    Habe eine Lösung gefunden. Kommt ein Tut dazu in den nächsten Tagen. Vielen Dank an die vielen Leser
    achim
     
  • Über uns

    Unsere immer weiter wachsende Community beschäftigt sich mit Themenbereichen rund um Mikrocontroller- und Kleinstrechnersysteme. Neben den Themen Design von Schaltungen, Layout und Software, beschäftigen wir uns auch mit der herkömmlichen Elektrotechnik.

    Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  • Coffee Time

    Unser makerconnect-Team arbeitet hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und unser eigener makerconnekt-Server regelmäßig gewartet wird. Wir nehmen das Thema Datensicherung und Datenschutz sehr ernst und sind hier sehr aktiv, auch sorgen wir uns darum, dass alles Drumherum stimmt!

    Dir gefällt das Forum und die Arbeit unseres Teams und du möchtest es unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft, unser Team freut sich auch über eine Spende für die Kaffeekasse :-)
    Vielen Dank!
    Dein makerconnect-Team

    Spende uns! (Paypal)
  1. Diese Seite verwendet Cookies, um Inhalte zu personalisieren und die Seite optimal für dich anzupassen. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden