Ressourcen-Icon

SAM D21J17A im Modularen Board System 2017-06-18

Hallo Dirk
Danke für die Info. Habe es studiert und versuche es nochmal kurz darzustellen.
packet.address = SLAVE_ADDRESS;
Es wird eine Slave Adresse angegeben und diese wird an packer.adress übergeben
packet.data_length = 32; // 32 Byte lesen
packer_length bekommt durch 32 eine Länge von 32 Byte (kannman auch 8 oder 16 angeben?)
packet.data = i2c_read_buffer;
in packer.data stehen beim lesen die Daten und werden an i2c_read_buffer übergeben.
while (i2c_master_read_packet_wait(&i2c_master_instance, &packet) != STATUS_OK) { if (timeout++ == TIMEOUT) { LED_PB30_ON break; } }
es wurde ein timeout von 0 definiert. Wenn keine ACK wird Programm unterbrochen, LED_PB30_on wird eingeschaltet und Programm stopt (break)
#define DATA_LENGTH 32 static uint8_t i2c_write_buffer[DATA_LENGTH];static uint8_t i2c_read_buffer[DATA_LENGTH];
Damit hat Data_Length eine Länge von 32 Bit und es werden 2x static für lesen und schreiben definiert.
packet.address = SLAVE_ADDRESS; // 7bit Adresse packet.data_length = 1; // ein Byte senden packet.data = i2c_write_buffer; // dieser Buffer wird verwendet
Es werden wieder eine Slave Adresse verwendet, Länge festgelegt und an write übergeben und gesendet.
Beim schreiben:
i2c_write_buffer[0] = 0; // 0 wird gesendet
Muss sowas auch nicht read?
i2c_write_buffer[0] = 0; // 0 wird gesendet
gibt es verschiedene write_buffer da [0] steht?
Langsam kommt die Erhellung.
achim
 
packer_length bekommt durch 32 eine Länge von 32 Byte (kannman auch 8 oder 16 angeben?)

Die 32 sind nur ein Beispiel. Du musst wissen, wieviele Daten du an einem Stück senden oder empfangen möchtest/musst.
Du musst auch nicht unbedingt zwei unterschiedliche Arrays für Schreiben und Lesen definieren.

---

in packer.data stehen beim lesen die Daten und werden an i2c_read_buffer übergeben.
packet.data wird hier genau genommen die Adresse des Arrays übergeben. Dadurch "wissen" die I2C Funktionen, wo sie Daten herbekommen oder ablegen sollen.

---

es wurde ein timeout von 0 definiert. Wenn keine ACK wird Programm unterbrochen, LED_PB30_on wird eingeschaltet und Programm stopt (break)
while (i2c_master_read_packet_wait(&i2c_master_instance, &packet) != STATUS_OK) { if (timeout++ == TIMEOUT) { LED_PB30_ON break; } }

bei break wird die while Schleife unterbrochen. Es wird also nicht versucht weiter ein Paket zu lesen, i2c_master_read_packet_wait() wird also nicht mehr wiederholt ausgeführt.

---

Muss sowas auch nicht read?
i2c_write_buffer[0] = 0; // 0 wird gesendet

Nein, bei Read wird das Array ja von der I2C Funktion gefüllt.

Bei Write musst du hier zuvor etwas in das Array schreiben, es sind die Daten, welche nach der Adresse+W gesendet werden.

---

gibt es verschiedene write_buffer da [0] steht?

Nein. Bei der [0] handelt es sich um den Index des ersten Elements im Array. Zu den C Grundlagen, schau mal bei mikrocontroller.net vorbei (https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial)

Wenn ich zum Beispiel 0x55 0x66 senden möchte ...
i2c_write_buffer[0] = 0x55;
i2c_write_buffer[1] = 0x66;

packet.data_length = 2;
packet.data = i2c_write_buffer;
 
Hallo Dirk
habe wahrscheinlich einen Fehler gefunden. Du hast den TS1117 und den Power Switch drauf. Am Power switch liegen konstant 5V an. Am TS1117 kommen allerdings keine 5V an, sondern schwanken sehr stark und liegen bei ca. 2Vbei einer Last vom SAMD21 und 2 LEDs mit je 2mA. Dadurch laufen einige Programme und andere nicht. Müsste noch eine Platine von dir haben. Muss sie aber erst wiederfinden .....
achim
 
Hallo Achim,
das ist seltsam. Es hört sich so an, als würde der Powerswitch den Strom begrenzen. Schau mal, ob du irgendwo in dem 3,3V Pfad eine niederohmige Verbindung hast. Eventuell ist auch inzwischen beim MC im Bereich GPIO etwas defekt weil mal IO Pins falsch zugeordnet waren. Es wäre gut, wenn du testweise ein anderes Modul stecken könntest. Wenn du kein Modul mehr hast und du nicht zurecht kommst, schicke ich dir eins.

Dirk :ciao:
 
Hallo Dirk
habe gestern abend noch mein Ersatzmodul gefunden, hatte sich leider in einer kleinen Tüte ganz unten in einer Kiste versteckt. So ein kleiner Racker, du, du. Habe schnell die Steckerleiste aufgelötet und gemessen. Es stehen 3,3V an wo es sein, toll und sind stabil. Habe noch ein Programm getestet und es lief alles korrekt. Nach deiner Schaltung zu urteilen könnte ich doch zu Testzwecken die 5V direkt auf den TS1117 legen. Leider bin ich jetzt auf Arbeit und kann nichts messen. Hoffe das von den angeschlossenen Teilen und Pegelwandler nichts defekt ist. Wie es dazu gekommen ist kann nicht nachvollziehen. Kann mir nur vorstellen das 5V und 12V Verbindung durch einen Stecker hatten. Da werde ich mir wohl wieder was bei dir bestellen müssen. Werde heute abend testen ob der PCF8574 auch was abbekommen hat.
Könnte doch eigentlich kein Schluss auf der 3,3V Leitung haben, da keine 5V am TS1117 liegen?
achim
 
Theoretisch könntest du wahrscheinlich 5V direkt auf den Eingang des 3V3 Linearreglers legen. Das Signal ist aber nicht an den Pads des Moduls verfügbar und du müsstest aufpassen, dass du nicht den Anschluss des Linearreglers verwechselst und ich bin mir nicht 100%ig sicher, dass der Powerswitch dies an seinem OUT verträgt (vermute aber mal).
Aber es hat ein Grund warum die Versorgungsspannung vor dem Linearregler zu niedrig ist, ich vermute der Powerswitch begrenzt den Strom. Also wenn du 5V direkt auf den Eingang des Linearreglers legst (ich würde es nicht machen), macht das Modul selber keine Strombegrenzung mehr, du solltest dann "extern" dafür sorgen.

Fall 5V kurzzeitig mal mit 12V verbunden waren, kann natürlich alles passieren.

Ich vermute es ist was mit GPIO nicht in Ordnung. Entferne testweise den I2C Teil aus der Software, vielleicht treiben hier zwei Ausgänge permanent gegeneinander (Leveltranslator).

Dirk :ciao:
 
Hallo Dirk
erst eimal die gute Nachricht. Bis auf dein Modul, mit diesem Fehler, funktioniert alles korrekt. Der PCF hat es gut überstanden und der Pegelwandler geht korrekt. Damit kann ich jetzt Daten zum PCF übertragen. Soweit geschafft.
Etwas ist mir aufgefallen, was ich noch nicht verstehe.


CodeBox C
   i2c_write_buffer[0] = 0xff;           //ff-alle aus
   packet.address = SLAVE_ADDRESS;
   //packet.data_length = DATA_LENGTH;
   packet.data_length = 1;
   packet.data = i2c_write_buffer;

habe dazu am Anfang angegeben:


CodeBox C
#define LED1  PIN_PB05           // PA03 / PB30 - 1. Zahl LED+Taster auf P110
#define Button1   PIN_PB23       // PB23 / PA13 - 2. Zahl LED+Taster auf Nano SAM
#define DATA_LENGTH 32
#define Timeout 1000

void configure_i2c(void);       // Angabe Prototype
void touch_write_data(void);
void configure_port_pins(void);   

struct i2c_master_module i2c_master_instance; //generate the instance-struct for I2C-Master
struct i2c_master_packet packet;

Wenn ich bei packet.data = DATA_LENGTH einsetze erfolgt keine korrekt Übertragung. Schreibe ich eine 1 dort hin geht es.
Mach ich wieder was falsch?
achim
 
Hallo Achim,

du verwendest ja ein Array uint8_t als Write Buffer.

Du initialisierst dieses mit Index 0.


CodeBox C
i2c_write_buffer[0] = 0xff;           //ff-alle aus

Index 1 bis Buffergröße-1 ist nicht initialisiert.

Mit packet.data_length = 1 möchtest du 1 Byte übertragen, du überträgst also 0xFF (erster Index des Write Buffer)

Mit


CodeBox C
#define DATA_LENGTH 32
packet.data_length = DATA_LENGTH;

überträgst du 32 Byte. Das erste Byte ist ein 0xFF (kommt von deiner Initialisierung) die nächsten 32 Byte sind unbestimmt, weil nicht initialisiert.

Möchtest du zum Beispiel 0x00 0x01 0x02 übertragen, machst du folgendes:


CodeBox C
i2c_write_buffer[0] = 0x00;
i2c_write_buffer[1] = 0x01;
i2c_write_buffer[2] = 0x02;
packet.data_length = 3;


Dirk :ciao:
 
Hallo Dirk
hat super funktioniert. Damit kann ich jetzt den PCF8574 ansteuern. Damit läuft der I2C Bus jetzt. Geht jetzt an die Anwendungen und entsprechende Programme. Damit haben ich dann ein Problem. Beim Atmega 1284p hatte ich einige Biblitheken in .c und .h. Im Programm konnte ich dann einfach ein Display z.B. mit 4x16 die Schrift übertragen. Im AS 7 habe ich verschiedene Beispiele für Displays gefunden, sind aber alle direkt auf die Pins, nicht auf den Bus. Kennst du einen Beispiel zu dem Thema? Konnte im Netz dazu nichts finden.
achim
 
Hallo Achim,

ich vermute du möchtest das Display am Portexpander betreiben, dann wären ja nur die I2C Funktionen zu ersetzen.

Es kommt nun auf die Bibliothek drauf an, aber im Idealfall sind nur wenige Zeilen auszutauschen.

Wenn du ein AVR Projekt mit der Display Bibliothek postest (ein kleines funktionierendes Beispiel), könnte ich es mir mal anschauen und versuchen dieses für den SAMD21 anzupassen (ich müsste nur ein bisschen Zeit dafür finden, geht leider nicht sofort).

Dirk :ciao:
 
Hallo Dirk
versuche mal ein Projekt von mir hochzuladen. Habe es als zip gepackt, damit zu viele einzelen Datein kommen. Ist das komplette Projekt für einen Bus Scanner mit Displayanzeige auch über Bus. Vielleicht kannst du was draus machen.
achim
Hat mit dem zip nicht geklappt. Versuche es mit den einzelnen Datein
 

Anhänge

  • ATB Bus Scanner Prg 1.c
    4 KB · Aufrufe: 5
  • i2clcd.c
    9,3 KB · Aufrufe: 4
  • i2clcd.h
    14,8 KB · Aufrufe: 5
  • twimaster.c
    6 KB · Aufrufe: 5
  • main.h
    258 Bytes · Aufrufe: 4
  • i2cmaster.h
    5,5 KB · Aufrufe: 4
Hallo Achim,

i2clcd.c und .h habe ich angepasst und beide Dateien angehängt.

Ich kann es leider bei mir nicht testen, da mir die Hardware fehlt.



In i2clcd.c binde ich touch.h ein (#include "touch.h"). Pass das bitte an. Du musst hier deine .h einbinden wo deine Prototypen der I2C Funktionen stehen.

Diese beiden Hilfsfunktionen fügst du in dein .c zu den I2C Funktionen ein:



CodeBox C
enum status_code write_data_i2c(uint8_t address, uint8_t *buffer, uint8_t len)
{
  
   uint16_t timeout;
  
   timeout = 0;
  
   packet.address     = address;
   packet.data_length = len;
   packet.data        = buffer;  
  
  
   while (i2c_master_write_packet_wait(&i2c_master_instance, &packet) != STATUS_OK)
   {
       if (timeout++ == TIMEOUT)
       {
            return STATUS_ERR_TIMEOUT;
            break;
        }
    }

   return STATUS_OK;

};

enum status_code read_data_i2c(uint8_t address, uint8_t *buffer, uint8_t len)
{
  
   uint16_t timeout;
  
   timeout = 0;
  
   packet.address     = address;
   packet.data_length = len;
   packet.data        = buffer;  
      
   while (i2c_master_read_packet_wait(&i2c_master_instance, &packet) != STATUS_OK)
   {
       if (timeout++ == TIMEOUT)
       {
            return STATUS_ERR_TIMEOUT;
            break;
        }
    }

   return STATUS_OK;

};


Dann deklarierst du die Prototypen der beiden Funktionen in der zugehörigen .h Datei


CodeBox C
enum status_code write_data_i2c(uint8_t address, uint8_t *buffer, uint8_t len);
enum status_code read_data_i2c(uint8_t address, uint8_t *buffer, uint8_t len);


Wie oben schon beschrieben, diese .h Datei in i2clcd.c einbinden (anstelle meines touch.h).

Alle Funtionen in i2clcd.c welche AVR FLASH PGM nutzen, habe ich erst mal auskommentiert (funktioniert bei ARM anders/einfacher als bei AVR). Testen kannst du mit String im SRAM.
void lcd_print(char *string)

LCD_I2C_DEVICE ist die 8bit Adresse, das müsste bei dir 0x42 (?) sein.

Falls du nicht klar kommst, zippe dein aktuelles Projekt, ich kann es dir dann einbauen.

Dirk :ciao:
 

Anhänge

  • i2clcd.c
    10 KB · Aufrufe: 1
  • i2clcd.h
    14,8 KB · Aufrufe: 1
Hallo Dirk
du bist ja schnell. Bin am staunen. Mal sehen ob ich das auch so schnell zum laufen bekomme. Vielen Dank schon mal jetzt.
achim
 
Hallo Dirk
habe versucht nach deiner Anleitung es zu machen. Ist mir allerdings noch einiges nicht klar dabei. Schicke dir mal die Datein und versuche es weiter.
achim
 

Anhänge

  • main.c
    3,8 KB · Aufrufe: 2
  • i2clcd.c
    10 KB · Aufrufe: 0
  • i2clcd.h
    14,8 KB · Aufrufe: 0
Achim,
kein Problem, sobald ich am Wochenende Zeit finde, schaue ich mir das mal an und versuche es einzubauen.

Gut wäre, wenn du das komplette Projekt mit dem ASF zippen würdest, dann muss ich mir es nicht erstellen und ich habe dann gleich alle Bereiche aus dem ASF eingebunden, welche dein Projekt nutzt.
 
Verzeichnisse lassen sich nicht anhängen. Am besten, du packst das Projektverzeichnis in eine Zip Datei und hängst diese an.
 

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