USI - Übertragung zwischen Slave und Master geht nicht

  • Frohe Ostern

achim S.

Premium Benutzer
16 Jan 2010
461
6
18
Nähe Basel
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
 

achim S.

Premium Benutzer
16 Jan 2010
461
6
18
Nähe Basel
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

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)