zweidimensionales Array auslesen



  • Hallo zusammen

    Ich gebe einer Funktion ein zweidimensionales Array dmaBuffer[0][0] über.

    Init_DMA_ADC1(DMA_DATA_LEN, &dmaBuffer[0][0]);
    

    Am Schluss möchte ich es auslesen mitteils:

    #define DMA_CHANNELS    4
    
    void ReadOutIntArray()
    {   
        for (uint16_t j = 0; j < DMA_CHANNELS; j++)
        {
          for (uint16_t i = 0; i < 1027; i++)
          {             
            adcValue = dmaBuffer[j][i];
            USART_Transmit_Int(adcValue);
            USART_sendChar('\n');
            for (count = 0; count <= 50000; count++);
          } 
        }
    }
    

    Mache ich das richtig so?
    Ich gehe Spalte für Spalte zeilenweise durch.

    Danke vielmals



  • buell schrieb:

    Hallo zusammen

    Ich gebe einer Funktion ein zweidimensionales Array dmaBuffer[0][0] über.

    Init_DMA_ADC1(DMA_DATA_LEN, &dmaBuffer[0][0]);
    

    Am Schluss möchte ich es auslesen mitteils:

    #define DMA_CHANNELS    4
    
    void ReadOutIntArray()
    {   
        for (uint16_t j = 0; j < DMA_CHANNELS; j++)
        {
          for (uint16_t i = 0; i < 1027; i++)
          {             
            adcValue = dmaBuffer[j][i];
            USART_Transmit_Int(adcValue);
            USART_sendChar('\n');
            for (count = 0; count <= 50000; count++);
          } 
        }
    }
    

    Mache ich das richtig so?
    Ich gehe Spalte für Spalte zeilenweise durch.

    Danke vielmals

    ausprobieren.
    wenn es compiled aber mist ausgibt, dann mal in zeile 9 j und i vertauschen.
    🙂



  • Fricky667 schrieb:

    wenn es compiled aber mist ausgibt, dann

    Schwachsinn. Weder das eine noch das andere ist ein Kriterium für ein korrektes Programm. Nur Dilettanten arbeiten so.



  • Wutz schrieb:

    Fricky667 schrieb:

    wenn es compiled aber mist ausgibt, dann

    Schwachsinn. Weder das eine noch das andere ist ein Kriterium für ein korrektes Programm. Nur Dilettanten arbeiten so.

    Mach dir mal keine Sorgen. Das geht erstmal so. Er soll das erstmal machen.


  • Mod

    Fricky667 schrieb:

    Wutz schrieb:

    Fricky667 schrieb:

    wenn es compiled aber mist ausgibt, dann

    Schwachsinn. Weder das eine noch das andere ist ein Kriterium für ein korrektes Programm. Nur Dilettanten arbeiten so.

    Mach dir mal keine Sorgen. Das geht erstmal so. Er soll das erstmal machen.

    Doch, er sollte sich Sorgen machen. Dein "Ratschlag" ist nicht nur nicht-funktionell, sondern sogar gefährlich.



  • SeppJ schrieb:

    Doch, er sollte sich Sorgen machen. Dein "Ratschlag" ist nicht nur nicht-funktionell, sondern sogar gefährlich.

    Das ist nicht gefährlich. Er muss überprüfen ob das plausibel ist, was er dem DMA entlockt. Ich denke, dass er die Möglichkeit dazu hat. Sein Controller wird schon nicht explodieren. Und wenn es immer noch nicht stimmt, wird man ihm hier sicher weiter helfen.


  • Mod

    Fricky667 schrieb:

    SeppJ schrieb:

    Doch, er sollte sich Sorgen machen. Dein "Ratschlag" ist nicht nur nicht-funktionell, sondern sogar gefährlich.

    Das ist nicht gefährlich.

    Wieder mal Quatsch. Funktioniert = Richtig ist eine ganz gefährliche Vorgehensweise. Wenn du selber Code schreibst, musst du ihn auch verstehen. Code ist kein Haufen von wahllos zusammengeschmissenen Buchstaben und Zeichen, Code ist Logik pur. Du musst genau wissen, warum du wo und welches Zeichen setzt.

    Zufälliges Herumprobieren, bis etwas funktioniert, ist genau das Gegenteil davon.



  • SeppJ schrieb:

    Zufälliges Herumprobieren, bis etwas funktioniert, ist genau das Gegenteil davon.

    Nein, ich finde das sogar sehr wichtig, denn man probiert ja nicht wirklich zufällig, sondern lernt auch by trial and error, also durch machen und nicht nur durch lesen. und auch fehler müssen gemacht werden, damit man besser wird.

    im konkreten fall wissen wir nicht einmal, wie sein dma-controller die daten organisiert, ob i[j] oder j[i].


  • Mod

    Fricky667 schrieb:

    SeppJ schrieb:

    Zufälliges Herumprobieren, bis etwas funktioniert, ist genau das Gegenteil davon.

    Nein, ich finde das sogar sehr wichtig,

    Ich denke, darüber ist keiner überrascht. Schließlich triggern 90% deiner sogenannten Hilfestellungen hier im Forum ein promptes Einschreiten von Leuten, die es richtig wissen, und dann nicht nur echte Hilfe geben, sondern zudem noch deinen Unsinn korrigieren müssen.



  • SeppJ schrieb:

    Fricky667 schrieb:

    SeppJ schrieb:

    Zufälliges Herumprobieren, bis etwas funktioniert, ist genau das Gegenteil davon.

    Nein, ich finde das sogar sehr wichtig,

    Ich denke, darüber ist keiner überrascht. Schließlich triggern 90% deiner sogenannten Hilfestellungen hier im Forum ein promptes Einschreiten von Leuten, die es richtig wissen, und dann nicht nur echte Hilfe geben, sondern zudem noch deinen Unsinn korrigieren müssen.

    ich sage ja nur was mir dazu einfällt. wenn das leute triggert die es besser wissen, dann hat der OP auch mehr davon. also zerreißt mich. es kann nur zu allgemeinem vorteil sein.



  • Hat es einen besonderen Sinn, statt des Array die Adresse des 1. Elementes zu übergeben, wenn man sowieso das komplette Array ausliest?

    Zum Thema: Zeilenweise Spalte für Spalte durchgehen ist i.d.R. richtiges Vorgehen.

    Wenn du erst alle Elemente für den 1. Kanal, dann für den 2. Kanal usw. auslesen möchtest, ist das so korrekt.

    Wenn du natürlich erst den 1. Wert des 1. Kanals, dann den 1. Wert des 2. Kanals usw. auslesen möchtest, musst du die beiden Schleifen tatsächlich vertauschen.



  • Wade1234 schrieb:

    Wenn du natürlich erst den 1. Wert des 1. Kanals, dann den 1. Wert des 2. Kanals usw. auslesen möchtest, musst du die beiden Schleifen tatsächlich vertauschen.

    Au weia. Jetzt gibts gleich mecker. 😃



  • Warum? Es steht doch im Einklang mit

    SeppJ schrieb:

    genau wissen, warum [...] wo und welches Zeichen


  • Mod

    Wade1234 schrieb:

    Warum? Es steht doch im Einklang mit

    SeppJ schrieb:

    genau wissen, warum [...] wo und welches Zeichen

    Allerdings.

    Im Gegensatz zu gewissen anderen Leuten propagiert Wade1234 keine gefährlichen Stümpertechniken, sondern erklärt(!) wie es richtig geht.

    👍 👍 👍



  • Wade1234 schrieb:

    Hat es einen besonderen Sinn, statt des Array die Adresse des 1. Elementes zu übergeben, wenn man sowieso das komplette Array ausliest?

    Der Name des Arrays ist die Adresse soviel ich verstanden habe und das erste Element des Arrays hat die selbe Adresse wie das Array, oder nicht?

    Zum Thema: Zeilenweise Spalte für Spalte durchgehen ist i.d.R. richtiges Vorgehen.

    Wenn du erst alle Elemente für den 1. Kanal, dann für den 2. Kanal usw. auslesen möchtest, ist das so korrekt.

    Wenn du natürlich erst den 1. Wert des 1. Kanals, dann den 1. Wert des 2. Kanals usw. auslesen möchtest, musst du die beiden Schleifen tatsächlich vertauschen.

    Also was ich möchte ist ein DMA Array mit 1027 Werten x 4, weil ich 4 Zeilensensoren habe mit 1027 Pixeln. Für mich ist es einfacher, wenn ich alle Werte von den Sensoren in ein Array speichere und daher dann auch nur eine DMA Zieladresse angeben muss, ansonsten muss ich bei Auslesen jedes einzelnen Sensors auch die DMA Zieladresse wechseln..

    Mein Problem ist eben, dass der Code so zum Auslesen nicht funktioniert. Ich wollte mal zuerst sichergehen, dass es nicht am Code liegt, bevor ich die Hardware unter die Lupe nehme.

    (Die Auslesefunktion habe ich ja bereits gepostet. Ich denke, der gewählte Name DMA_CHANNELS war ein wenig verwirrend. Der Code zum Auslesen ist nun angepasst.
    Ich nehme also an, dass mein j und i so stimmt oder liege ich da falsch?
    Falls die DMA Init interessiert, ist diese unten angehängt.

    #define EPC_QUANTITY                                  4
    #define DATALENGTH                                 1027
    #define DMA_DATA_LEN                  (EPC_QUANTITY *DATALENGTH)
    
    static uint16_t dmaBuffer[EPC_QUANTITY][DATALENGTH]; 
    
    void ReadOutIntArray()
    {   
        for (uint16_t j = 0; j < EPC_QUANTITY; j++)
        {
          for (uint16_t i = 0; i < DATALENGTH; i++)
          {             
            adcValue = dmaBuffer[j][i];
            USART_Transmit_Int(adcValue);
            USART_sendChar('\n');
            for (count = 0; count <= 50000; count++);
          } 
        }
    }
    
    #include "dma.h"
    #include "config.h"
    
    /*
      ==============================================================================
                          ##### DMA1 features #####
      ==============================================================================
    */
    
    void Init_DMA_ADC1(uint16_t DataLength, uint16_t* dma_buffer) 
    {                                                                    
      __HAL_RCC_DMA1_CLK_ENABLE();                                                 /* DMA1 CLK einschalten*/
    
      /* Peripheral DMA init for ADC*/
    
      uint32_t SrcAddress = (ADC1_BASE + 0x40);                                    // ADC Datenregisteradresse als Sourceadresse angeben --> Offset--> DR = 0x40   
    
      hdma_adc1.Instance = DMA1_Channel1;                                          // Channel 1 auf ADC1 gemappt page 288
      hdma_adc1.Instance->CPAR = SrcAddress;                                       // Oben definierte Sourceadresse angeben
      hdma_adc1.Init.Request = DMA_REQUEST_0;                                      // Request 0 (only for ADC1) page 288
      hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;                             // Angabe der Richtung von wo nach wo der DMA die Daten speichern soll
      hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;                                 // Zeiger der Peripherieadresse soll nicht inkrementiert werden
      hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;                                     // Zeiger der Memoryadresse inkrementieren
      hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;                // 16-bits, halfword
      hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;                   // 16-bits, halfword
      hdma_adc1.Init.Mode = DMA_CIRCULAR;                                          // konvertiert kontinuierlich --> Normal mode wäre = DMA One shot mode
      hdma_adc1.Init.Priority = DMA_PRIORITY_VERY_HIGH;                            // Priorität setzen
      hdma_adc1.Instance->CNDTR = DataLength;                                      // Datenlänge des DMA Buffers definieren
    
      hdma_adc1.Instance->CMAR = (uint32_t) dma_buffer;                            // Die DMA Zieladresse angeben bzw. definieren
    
      if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
      {
        Error_Handler();
      }
    
    /*
        ###  ADC1 NVIC Konfiguration für den DMA1_Channel1_IRQn - ADC Channel  ###
      ==============================================================================   
    */
      HAL_NVIC_SetPriority(DMA1_Channel1_IRQn,5,1);
      HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn); 
    
    }
    



  • Mod

    glrookie schrieb:

    Vielleicht hilft Dir ja diese mentale Stuetze:

    http://2.bp.blogspot.com/-SXMbF3iVB2s/VDjpPwGSGUI/AAAAAAAACB0/u-0QSuneaaA/s1600/two-dimensional-array-in-java.png

    Deine tolle Stütze ist vollkommener Unsinn. Erstens ist es für eine andere Sprache; zweitens für eine andere, ganz spezielle Situation; drittens ist es syntaktisch falsch; viertens ist es inhaltlich falsch.

    An alle Leser: Den Link unbedingt ignorieren!



  • buell schrieb:

    Ich nehme also an, dass mein j und i so stimmt oder liege ich da falsch?

    Wie sehen denn die Daten aus, die du ausliest und woran machst du fest, dass die Mist sind?

    Btw, an der Init-Funktion kann es natürlich auch liegen. Dazu müsstest du der geneigten Leserschaft hier mal mitteilen, was du für einen Controller benutzt.

    Und sicherlich gibt es auch (vom Hersteller) Beispiele für den Betrieb des DMA-Features.

    Nachtrag: Sieht aus wie ein ST-Typ. frag doch mal dort: https://community.st.com/welcome 😋



  • Fricky667 schrieb:

    buell schrieb:

    Ich nehme also an, dass mein j und i so stimmt oder liege ich da falsch?

    Wie sehen denn die Daten aus, die du ausliest und woran machst du fest, dass die Mist sind?

    Btw, an der Init-Funktion kann es natürlich auch liegen. Dazu müsstest du der geneigten Leserschaft hier mal mitteilen, was du für einen Controller benutzt.

    Und sicherlich gibt es auch (vom Hersteller) Beispiele für den Betrieb des DMA-Features.

    Nachtrag: Sieht aus wie ein ST-Typ. frag doch mal dort: https://community.st.com/welcome 😋

    [quote="Fricky667"]

    buell schrieb:

    Nachtrag: Sieht aus wie ein ST-Typ. frag doch mal dort: https://community.st.com/welcome 😋

    Das habe ich schon gemacht. Hilfreich war das bisher nicht im STM forum.
    Ob die Daten Mist sind kann ich mir nicht vorstellen. Es ist der STM32L431RCI6.
    Der ADC und die DMA funktioniert. Ich hatte mit dem Entwicklungsboard NuCLEO vor einigen Wochen schon einen Test gemacht, bei dem ich einen Sinus mit Offset angelegt habe und die Messung auch richtig war.

    Beim neuen Board habe ich die Schnittstelle, die ich zuvor am Nucleo hatte nicht mehr und muss nun einen Zwischenstecker RS323 auf USB nutzen, um die Daten mit dem HTerm Tool sichtbar zu machen.

    Die Werte werden nach dem Belichten und Triggern des ADCs in den Speicher gelegt. Irgendwie scheinen mir die Werte zu niedrig. Es sind irgendwelche Zahlen im Bereich 100-200 obwohl ich eine 12-bit ADC Auflösung habe.

    Naja, ich kann mit dem Code im HTerm keine Daten sichtbar machen. Jetzt weiss ich im Moment nicht wo der Fehler ist. Deshalb müsste ich mal wissen, ob so das Programm richtig ist. (Readoutfunktion)

    Hier die Bilder

    https://picload.org/view/rppldaci/signale.png.html

    https://picload.org/view/rppldacw/17-07-201711-18-55.png.html



  • buell schrieb:

    Naja, ich kann mit dem Code im HTerm keine Daten sichtbar machen. Jetzt weiss ich im Moment nicht wo der Fehler ist. Deshalb müsste ich mal wissen, ob so das Programm richtig ist.

    Das Programm ist dann "richtig" wenn es ohne Errors und Warnings compiled. Ob es dann allerdings tut was du willst, ist eine andere Frage.

    Ich würde erstmal vorschlagen, die Spannung am Eingang des ADC zu messen und die mit den digitalisierten Werten vergleichen. Bevor Spannungspegel usw. nicht passen, brauchste gar nicht erst auf die Software zu gucken. 🙂


Anmelden zum Antworten