Ressourcen-Icon

SAM D21J17A im Modularen Board System 2017-06-18

Im Anhang von #61 ist nur die Projektdatei von AtmelStudio im Zip.

Anhänge habe ich auf 2MB erhöht, eventuell noch mal versuchen.

Im Projektverzeichnis hast du eventuell noch weitere Projekte oder irgendwelche anderen Files (PDF, Doku, Beispielcode), so dass du eine zu große Zip Datei erhältst.
 
sieh bitte mal nach ob jetzt alles dabei ist

Da fehlt noch das "main.c". Es sind aktuell gerade mal 13kB. Wenn du das Projektverzeichnis zippst, sollte es nicht viel größer sein (es sei denn da sind noch irgendwelche anderen Daten drin).

Egal, ich erstelle einfach mal ein neues Projekt ... am Wochenende wenn ich dazu komme.
 
Hallo Achim,

ich habe ein neues Projekt erstellt und angehängt.

Ich kann es leider nicht testen und hoffe, ich habe keinen Flüchtigkeitsfehler drin.

Die i2c Funktionen sind nicht mehr in main.c sondern in i2cmaster.c.

In main() initialisiere ich auch das LCD und gebe zwei Strings aus.
Danach blinkt deine LED.

Es wird immer die 7bit I2C Adresse verwendet.


Das gezippte Projekt ist tatsächlich sehr groß, das liegt am ASF welches ebenfalls im Verzeichnis ist. Ich konnte es gerade noch so hochladen.

Dirk :ciao:
 

Anhänge

  • AchimProjekt.zip
    2 MB · Aufrufe: 5
Guten Morgen Dirk
Danke für das Projekt. Habe es geladen, 2M ist ganz schön gross. Es gleich mal gestartet und die ersten Zeilen stehen auf dem Display und die LED geht auch. Werde es noch weiter ansehen. Es wurde ohne Fehler übersetzt. Da gibt es wieder viel zu lernen für mich. Danke für deine Arbeit.
Du hast bestimmt schon gesehen, das es im Netz so gut wie keine Info oder Programme zu SAMD21 und Display über Bus gibt oder habe sie einfach nicht gefunden. Damit ist aber der Grundstein für eine Reihe von Programmen gelegt, die ich vom AVR übernehme, zur Anzeige auf Display, TFT und HT16 K 33. Der letzte IC ist ja ein Liebling von dir. Es betrifft aber auch die TFTs von EA. Von EA habe ich bereits die Displays in Farbe bis 5 Zoll zu liegen. Es sind recht anspruchsvolle Teile. Da mache ich jetzt weiter. Danke nochmal an dich für deine Hilfe.
achim
 
Hallo Achim,
Es gleich mal gestartet und die ersten Zeilen stehen auf dem Display und die LED geht auch. Werde es noch weiter ansehen. Es wurde ohne Fehler übersetzt. Da gibt es wieder viel zu lernen für mich. Danke für deine Arbeit.

Bitteschön :) Gut dass es gleich funktioniert hat.

Ich hatte die I2C-Funktionen ausgetauscht, ansonsten ist die Lib unverändert. So läuft die Lib nun auch auf einem ARM Mikrocontroller :)

Dirk :ciao:
 
Hallo Dirk
habe mit dem Ansteuern der LEDs auf verschiedenen Platinen mit unterschielicher Adresse weitergemacht. Auch mit der Umschaltung dazu. Geht alles super. Wollte jetzt deine read Beispiel einsetzen. Es lässt sich Fehlerfrei kompilieren. Es gibt aber keine Auswertung.
Als Beispiel hast du diesen Code angegeben:


CodeBox C
packet.address     = SLAVE_ADDRESS_2;
     packet.data_length = 32;           //DATA_LENGTH_1;
     packet.data        = i2c_read_buffer;
     timeout = 0;
     while (i2c_master_read_packet_wait(&i2c_master_instance, &packet) != STATUS_OK)
       {
         if (timeout++ == Timeout)
           {
             // Error LED_PB30_ON
             break;
           }
       }

.. die 32 Byte befinden sic h dann im Array i2c_read_buffer.
Was ich daran nicht versteh ist der gemische Betrieb. Am PCF8574, an den Ports 0-3 befinden sich LEDs. An den Ports 4-7 sind Taster angeschlossen.
Wollte es erst so machen:


CodeBox C
while (1)
     {
       // Abfrage Taster
       //if (port_pin_get_input_level(Button1))   // Taster nicht gedrückt
       //if (!port_pin_get_input_level(Button1))       // Taster gedrückt
       if (i2c_read_buffer == ???)       // Taster gedrückt
         {                                           // Schaltet LED       
           write_a_data();                       // Aufruf Bus
           write_c_data();                       // Aufruf Bus
           port_pin_toggle_output_level(LED1);       // Toggelt LED1
           delay_ms(500);                           // Zeit 500ms
           port_pin_toggle_output_level(LED1);       // Toggelt LED1
           delay_ms(500);                           // Zeit 500ms
         }
         else
         {
       write_b_data();                       // Aufruf Bus  
       }
     }

geht aber nicht. Kann ich es genau so machen wie beim Atm 1284, erst senden und dann abfragen?
Gibt es beim SAM etwas zu beachten? Oder liegt es nur an der Auswertun des Arrays?
achim
 
Hallo Achim,
Kann ich es genau so machen wie beim Atm 1284, erst senden und dann abfragen?
es sollte eigentlich auf einem Atmega1284 genauso funktionieren wie auf einen tinyAVR, SAM ARM, RasperryPi, PC .... Das Datenblatt des Portexpanders ändert sich ja nicht ;)

Wie man bei dem PCF8574 Ausgänge setzt oder Eingänge liest oder diesen konfiguriert, weiß ich ehrlich gesagt nicht, da ich ihn selber noch nicht eingesetzt habe. Ich müsste hier also erst mal das Datenblatt durchlesen. Aber du hast es ja schon einmal mit einen Atmega1284-Projekt gemacht. Falls du trotzdem noch mit dem Portexpander Probleme hast, kann dir vielleicht auch mal ein anderer User helfen. Es gibt auch bestimmt im Forum einige Themen zu dem PCF8574.

Was mir oben in deinem Code aufgefallen ist:
  • Du liest anscheinend nirgends Daten über I2C ein?! Dann wäre der Ihnalt des i2c_read_buffer Arrays unbestimmt.
  • Das Argument in deiner if-Anweisung funktioniert so nicht. Wenn du zum Beispiel das erste Byte im Array untersuchen möchtest verwendest du (i2c_read_buffer[0] == 0x45), bei dem zweiten Byte wäre es (i2c_read_buffer[1] == 0x45) usw. Möchtest du untersuchen, ob Bit0 im ersten Byte 1 ist, ist es folgende Bedingung (i2c_read_buffer[0] & 1), das sind nun eigentlich C Grundlagen, schau dir hierzu vielleicht auch mal das AVR GCC Tutorial bei mikrocontroller.net an.
Dirk :ciao:
 
Hallo Dirk
hatte angenommen das mit diesem Teil geht:


CodeBox C
 packet.address     = SLAVE_ADDRESS_2;
     packet.data_length = 1;           //DATA_LENGTH_1;
     packet.data        = i2c_read_buffer;
     timeout = 0;
     while (i2c_master_read_packet_wait(&i2c_master_instance, &packet) != STATUS_OK)

In der letzten Zeile ist doch read drin und wird mit packet.data zu i2c_read_buffer. Habe es aus deinem Beispiel genommen. Werde den Code vom 1284 noch mal genau anschauen und testen ob es so geht.
achim
 
Ja, damit kannst du Daten über I2C lesen.

Du müsstest die "I2C Read" Funktion in der while(1) Schleife einbauen, bevor du i2c_read_buffer auswertest.

Es sollte eigentlich so funktionieren, wie bei dem ATmega1284-Projekt, nur dass du hier andere I2C Funktionen hast die mit einem Daten-Array arbeiten.

Du kannst auch mal den Code posten, wo du eine Taste abfragst, vielleicht kann ich das wieder bearbeiten.

Dirk :ciao:
 
Hallo Dirk
komme endlich wieder an den Rechner. Muss mich ja mit schnöder Arbeit über Wasser halten. Egal.
Habe mal den Code für ein Lesen am 1284 rausgesucht. Werde es genau so am SAM versuchen.


CodeBox C
i2c_init ();
   i2c_start(adr1_w);                   // Schreibbefehl
   i2c_write(0xff);                   // Alle Pins des PCF auf 0
   i2c_stop();
   
   while(1)
   {                                   // Hauptschleife
       
       i2c_start(adr1_r);               // Starte Lesezugriff
       d=i2c_readNak();               // Schreib Leseergebnis in d
       i2c_stop();

       if (~d & 0x02)                   // Abfrage T2
       {                               // Wenn T2 gedrückt ist...
           i2c_start(adr2_w);           // Schreibbefehl
           e = 0x5c;                   // Angabe LED Port0
           i2c_write(e);               // Schreibe e
           i2c_stop();
           _delay_ms(100);               // 100ms warten
       }
       else
       {
           e = 0xff;                   // alle LED aus
           i2c_start(adr2_w);           // Schreibbefehl
           i2c_write(e);               // Schreibe e
           i2c_stop();
       }
   }
   _delay_ms(100);

Vielleicht hast du ein Hinweise für mich
achim
 
Hallo Achim,
Vielleicht hast du ein Hinweise für mich

mit den aktuellen Funktionen könntest du es zum Beispiel so lösen ...



CodeBox C
   uint8_t meinbuffer[10];
   configure_i2c();
  
   // ...
  
   meinbuffer[0] = 0xFF;
   write_data_i2c(LCD_I2C_DEVICE, meinbuffer, 1);
  
   while(1)
   {
       read_data_i2c(LCD_I2C_DEVICE, meinbuffer, 1);
      
       if (~meinbuffer[0] & 0x02)                   // Abfrage T2
       {                               // Wenn T2 gedrückt ist...
          
           meinbuffer[0] = 0x5C;
           write_data_i2c(LCD_I2C_DEVICE, meinbuffer, 1);
          
           delay_ms(100);               // 100ms warten
          
       } else {
                      
           meinbuffer[0] = 0xFF;
           write_data_i2c(LCD_I2C_DEVICE, meinbuffer, 1);
       }
              
   }


Noch ein Hinweis zu deinem Code zuvor:

Das Delay in Zeile 29 wird nie ausgeführt, dies wolltest du sicherlich im Else-Block haben. Dann ist der I2C Bus bei nicht betätigter Taste auch weniger oft aktiv. Eventuell einfach ein Delay vor read_data_i2c().


Dirk :ciao:
 
Hallo Dirk
dieses Teil eines Programmes soll eigentlich dazu dienen an einem PCF8574 (oder mehreren) gleichzeitig abzufragen oder zu setzen. Bei einem gemischten Aufbau mit Taster und LED gibt es sonst Probleme. Der PCF ist ja fast der leichteste IC aus dieser Klasse. Wenn ich einige andere dazu sehe, gibt es echt Probleme, so mit 30 Register und so. Teste es heute abend. Danke für die Hilfe
achim
 
Hallo Dirk
habe deinen Code soweit eingebaut. Ein bischen noch angepasst. Es klappt aber mit dem auslesen nicht.


CodeBox C
void read_data(void)
    {   
     uint16_t timeout;
     timeout = 0;
     packet.address     = SLAVE_ADDRESS_2;
     packet.data_length = 1;
     packet.data        = i2c_write_buffer_a;
     i2c_write_buffer_a[0] = 0;
     while (i2c_master_write_packet_wait(&i2c_master_instance, &packet) != STATUS_OK)
       {
         if (timeout++ == Timeout)
           {
             // Error LED_PB30_ON
             break;
           }
       }
     packet.address     = SLAVE_ADDRESS_2;
     packet.data_length = 1;           //DATA_LENGTH_1;
     packet.data        = i2c_read_buffer[0];
     timeout = 0;
     while (i2c_master_read_packet_wait(&i2c_master_instance, &packet) != STATUS_OK)
       {
         if (timeout++ == Timeout)
           {
             // Error LED_PB30_ON
             break;
           }
       }
    }

Vergleich erfolgt damit


CodeBox C
while (1)
     {
         
       read_data();        // Abfrage Taster
      
       if (i2c_read_buffer[0] & 0xf1)       // Taster gedrückt
       
       //if (~meinbuffer[0] & 0x02)                   // Abfrage T2 ****Dirk
       
         {                                           // Schaltet LED       
           write_a_data();                       // Aufruf Bus
           write_c_data();                       // Aufruf Bus
           port_pin_toggle_output_level(LED1);       // Toggelt LED1
           delay_ms(500);                           // Zeit 500ms
           port_pin_toggle_output_level(LED1);       // Toggelt LED1
           delay_ms(500);                           // Zeit 500ms
         }
         else
         {
       write_b_data();                       // Aufruf Bus  
       }

Die Adresse ist 0x22 und wird weiter oben angegeben.
Habe ich noch was übersehen, besonders im ersten Teil?
achim
 
Hallo Achim,

war die Adresse nicht mal 0x21? Ich weiß es nicht mehr genau. Du hast aber schon mal an einem Output des Expanders eine Led angesteuert, also wird das schon stimmen mit der Adresse.

Im oberen Codeblock sehe ich direkt keine Fehler. Ich kenne mich aber nun mit dem Portexpander nicht aus und müsste erst in das Datenblatt sehen.
Du musst nicht jedesmal das packed komplett neu konfigurieren, es reicht oben data_length und data.
Du musst auch nicht unbedingt zwei buffer für read und write verwenden, es reicht ja ein buffer Array, zumindest im Moment.
Aber beides ist erst mal nicht so wichtig.

Im Moment liest du so einen Wert:
Routine read_data()
(1) I2C Adresse + WR
(2) 0x00 schreiben
(3) I2C Adresse + RD
(4) Daten lesen (befindet sich dann in i2c_read_buffer[0])

ist das so richtig?

Und wenn ja, was erwartest du für einen Wert, wenn deine Taste gedrückt ist?

Dirk :ciao:
 
Hallo Dirk
ich verwende 2 Module mit dem PCF8574. Das Modul mit der Adresse 0x21 hat 8x LEDs. Das Modul mit der Adresse 0x22 hat 8x Taster. Habe die Adressen vorher getestet, die Stimmen. Der PCF hat 8 Pins von 0 bis 7. In der Kombination 0x00 bis 0xff liegen alle Möglichkeite drin. Dabei hat die erste Zahl bei 0x.. die Pins von 4-7 und die zweite Zahl die die Pins von 0-3. Erwarte also einen Wert z.B. von 0xf1. Das müsste der Taster 2 bei den Pins 0-3 sein. Beim AVR geht der Ablauf beim Auslesen (schreiben) nach dem Code:


CodeBox C
i2c_init ();
   i2c_start(adr1_w);                   // Schreibbefehl
   i2c_write(0xff);                   // Alle Pins des PCF auf 0
   i2c_stop();

oder lesen


CodeBox C
i2c_start(adr1_r);               // Starte Lesezugriff
       d=i2c_readNak();               // Schreib Leseergebnis in d
       i2c_stop();

die Adresse gebe ich hier an


CodeBox C
#define CONF_I2C_MASTER_MODULE SERCOM1
#define SLAVE_ADDRESS_1 0x21       // Angabe Slave Adresse 0x21
#define SLAVE_ADDRESS_2 0x22       // Angabe Slave Adresse 0x22

sonst habe ich immer die 40 bis 44 verwendet.
Ist der Unterschied mit 7 und 8 Bit Angabe. Könnte ja auch sein, das ich die Adresse dadurch falsch eingebe.
Beim AVR habe ich immer das lesen/schreiben gestartet und mit Stop beendet. Muss ich das hîer auch machen?
achim
 
Nur kurz, ich schau morgen noch mal genauer, da ich gerade keine Zeit habe.

Ich denke der Fehler liegt an dem Argument der if-Anweisung, an der Konstanten.

I2C Start/Stop machen die Funktionen aus dem ASF, bzw. das Sercom Modul, es sollte also nicht daran liegen.

... also morgen.
 

Ü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)