Willkommen in unserer Community

Werde Teil unserer Community und registriere dich jetzt kostenlos ...

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

C Adresse vom Array?!

Dieses Thema im Forum "Software" wurde erstellt von Janiiix3, 23. November 2017.

  1. Janiiix3

    Janiiix3 Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    987
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map
    Mooin ;)

    ich habe mal wieder ein Problemchen.. :(
    Versuche gerade was mit einem "HC06" Bluetooth Modul auf zu bauen.
    Empfangen und alles klappt soweit.

    Nun benutze ich die UART Bibliothek von "Peter Flury".
    Dort ist das Empfangen mit einem Buffer realisiert.



    CodeBox C und C++
    static volatile unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
    


    Wenn ich was auf dem Puffer auslesen möchte, gibt es die Funktion..


    CodeBox C und C++
    unsigned int uart_getc(void)
    {  
    
    
    unsigned char tmptail;
    unsigned char data;
    
    if ( UART_RxHead == UART_RxTail ) {
    return UART_NO_DATA; /* no data available */
    
    }
    
    /* calculate /store buffer index */
    
    tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
    UART_RxTail = tmptail;
    
    
    
    /* get data from receive buffer */
    
    data = UART_RxBuf[tmptail];
    
    data = (UART_LastRxError << 8) + data;
    UART_LastRxError = 0;
    return data;
    
    }/* uart_getc */
    


    Wenn ich diese Funktion nutze und den Speicherinhalt von diesem Puffer in einen anderen kopiere, klappt es.

    Schreibe ich in den Puffer, den String statisch rein, den ich eigentlich erwarte, klappt es auch.


    CodeBox C und C++
    while(1)
    {
    
    [I]strcpy[/I]((char*)UART_RxBuf,"LEDon");
    getState((char*)UART_RxBuf);
    }
    


    Laut Terminal empfange ich auch genau diesen String, also diese Zeichen empfange ich richtig und ohne Sonderzeichen.

    Hat jemand eine Idee?
     
  2. Dirk

    Dirk Administrator Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.070
    Zustimmungen:
    100
    Ort:
    Mittelhessen, Giessen
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Map
    Hallo Jan,

    du schreibst eigentlich, dass mehrere Sachen "klappen". Was funktioniert denn nun nicht, wo liegt dein Problem?

    Und du möchtest wissen, wie man an die Adresse eines Arrays heran kommt?

    Dirk :ciao:
     
  3. Janiiix3

    Janiiix3 Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    987
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map
    Ich weiß nicht wie ich das beschreiben soll, so das es jeder versteht :D
    Also, immer wenn ich ein Zeichen empfange, wird dieses in diesen Buffer geschrieben, diesen Buffer möchte ich jetzt einfach mal ausgeben ohne die Funktion "uart_getc()" zu nutzen.



    CodeBox C und C++
    ISR (UART0_RECEIVE_INTERRUPT)
    
    
    /*************************************************************************
    
    Function: UART Receive Complete interrupt
    
    Purpose: called when the UART has received a character
    
    **************************************************************************/
    
    {
    
    unsigned char tmphead;
    
    unsigned char data;
    
    unsigned char usr;
    
    unsigned char lastRxError;
    
    
    
    
    
    /* read UART status register and UART data register */
    
    
    usr = UART0_STATUS;
    
    data = UART0_DATA;
    
    
    
    /* */
    
    
    #if defined( AT90_UART )
    
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
    
    #elif defined( ATMEGA_USART )
    
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
    
    #elif defined( ATMEGA_USART0 )
    
    lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
    
    #elif defined ( ATMEGA_UART )
    
    lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
    
    #elif defined( AT90USB_USART )
    
    lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) );
    
    #endif
    
    
    
    /* calculate buffer index */
    
    
    tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
    
    
    
    if ( tmphead == UART_RxTail ) {
    
    /* error: receive buffer overflow */
    
    
    lastRxError = UART_BUFFER_OVERFLOW >> 8;
    
    }else{
    
    /* store new index */
    
    
    UART_RxHead = tmphead;
    
    /* store received data in buffer */
    
    
    UART_RxBuf[tmphead] = data;
    
    }
    
    UART_LastRxError |= lastRxError;
    
    
    }
    
    


    Hier wird der Buffer beschrieben, diesen möchte ich einfach mal Ausgeben lassen. Wenn ich was Empfangen habe und diesen Ausgeben will, erscheint aber nichts?!
     
  4. Dirk

    Dirk Administrator Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.070
    Zustimmungen:
    100
    Ort:
    Mittelhessen, Giessen
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Map
    Ich vermute, dass die Uart-Funktionen einen FiFo Buffer realisieren, dann kannst du nicht einfach ab Index 0 des Buffers einen String ausgeben.

    Du müsstest ab dem letzten Lese-Index auslesen, bzw. diese Adresse verwenden.

    Ich habe jetzt leider nicht so die Zeit, mir die Lib anzusehen.

    Im Prinzip gehts so:

    &MeinRingBuffer[LeseIndex]

    Dies ist die Adresse des ersten zu lesenden Zeichens im Buffer.
    Vorher sollte man ggf. noch prüfen, ob etwas zu lesen ist und wenn wieviele Daten. Da müsstest du dir die Funktionen in der Lib anschauen.

    Dirk :ciao:
     
  5. Janiiix3

    Janiiix3 Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    987
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map
    Das leuchtet mir ein, habe ich schon Probiert.


    CodeBox C und C++
    unsigned int uart_getc(void)
    {    
    
    unsigned char tmptail;
    unsigned char data;
    
    
    
    
    if ( UART_RxHead == UART_RxTail ) {
    return UART_NO_DATA; /* no data available */
    
    }
    
    /* calculate /store buffer index */
    
    tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
    [B]UART_RxTail = tmptail;[/B]
    
    /* get data from receive buffer */
    
    data = UART_RxBuf[tmptail];
    
    data = (UART_LastRxError << 8) + data;
    UART_LastRxError = 0;
    return data;
    
    }/* uart_getc */
    


    Ich habe den Index mal FETT markiert. Ab da lese ich auch aus, das klappt jedoch nicht.



    CodeBox C und C++
    uart_puts("LiveMessage\r\n");
    uart_puts((char*)&UART_RxBuf[UART_RxTail]);
    
     
  6. Dirk

    Dirk Administrator Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.070
    Zustimmungen:
    100
    Ort:
    Mittelhessen, Giessen
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Map
    Probiere mal vorher den Index um 1 zu erhöhen ...



    CodeBox C und C++
    uart_puts((char*)&UART_RxBuf[UART_RxTail+1]);
    


    Siehe auch Zeile 17 und 18 in der ersten Codebox.
     
  7. Janiiix3

    Janiiix3 Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    987
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map
    Leider nach wie vor das gleiche Ergebnis..
     
  8. Dirk

    Dirk Administrator Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.070
    Zustimmungen:
    100
    Ort:
    Mittelhessen, Giessen
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Map
    Dann habe ich im Moment auch keine weitere Idee mehr. Ich müsste mal in die Lib reinschauen ... nur fehlt mir die Zeit dafür :(

    Vielleicht hat ja sonst noch jemand eine Idee.
     
  9. Janiiix3

    Janiiix3 Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    987
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map


    CodeBox C und C++
    while(1)
    
    {
    
    
    unsigned char tmpBuff[UART_RX_BUFFER_SIZE];
    unsigned char *tmpBuffPtr = &tmpBuff[0];
    
    uart_puts("LiveMessage\r\n");
    
    /* So werden die Bytes nacheinander verschickt. Das haut hin. */
    
    //uart_putc(uart_getc());
    
    /* Warum werden hier nicht die empfangenen Daten rüber kopiert? */
    
    while(*tmpBuffPtr != '\0')
    {
    *tmpBuffPtr++ = uart_getc();
    }
    uart_puts((char*)tmpBuffPtr);
    uart_puts("\r\n");
    [I]_delay_ms[/I](250);
    }
    
     
  10. Dirk

    Dirk Administrator Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.070
    Zustimmungen:
    100
    Ort:
    Mittelhessen, Giessen
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Map
    Wenn du deinen Buffer füllst und danach mit _puts einen String ausgeben möchtest, zeigt dein Pointer auf den Index nach dem String, bzw. nach dem letzten empfanenen Zeichen.

    Noch ein Hinweis:
    uart_getc gibt uint16_t zurück, das solltest du ggf. noch berücksichtigen (Fehlerbehandlung o. ä)
     
  11. Janiiix3

    Janiiix3 Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    987
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map
    Achja..! Stimmt ja!

    Das heißt würde ich es mit dem Pointer machen, müsste ich die Länge ermitteln und das später von der aktuellen Adresse abziehen..
    Was geht schneller bzw. ist Effektiver..

    Mit for arbeiten oder eher mit einem Pointer?
     
  12. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    83
    Zustimmungen:
    7
    Ort:
    Großraum Hannover
    Sprachen:
    C, Assembler
    Map
    Du hast es hier mit einem Ringbuffer zu tun. Um diesen Ringbuffer auszulesen, empfiehlt es sich, die gleiche Funktionalität zu benutzen, wie die Funktion uart_getc().

    Warum also nicht gleich diese schon vorhandene Funktion benutzen?
     
  13. Janiiix3

    Janiiix3 Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    987
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map
    Habe ich jetzt so gemacht. Da ich nicht jedes Byte einzeln testen möchte, habe ich mich für einen ganzen String entschieden.



    CodeBox C und C++
    unsigned char tmpBuff[UART_RX_BUFFER_SIZE];
    
    
    for([I]uint8_t[/I] x = 0 ; x < UART_RX_BUFFER_SIZE ; x++)
    {
    tmpBuff[x] = uart_getc();
    }
    
    uart_puts((char*)tmpBuff);
    int8_t indexOfCmd = 0x00;
    indexOfCmd = readCmd((char*)tmpBuff,"LEDoff",allowedCmd);
    


    Ich habe gehofft das ich den vorhandenen Puffer schon nehmen hätte können.
    So muss ich das ganze um kopieren und verschwende doppelten Speicher..
     
  14. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.698
    Zustimmungen:
    38
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    Müssen nicht sowieso irgendwann alle Daten mit (einer) der bibliothekseigenen Lesemethode(n) aus dem Puffer gelesen werden (eine eventuelle Buffer-Clear-Methode zählt dazu), um einen früher oder später auftretenden Bufferoverrun zu verhindern?
    Ob man die gelesenen Daten zur Weiterverwendung speichert, oder verwirft ist ja egal...

    P.S.: Wie sehen denn die zu sendenden/zu empfangenen Telegramme aus?
    Möglicherweise wäre es für Dich besser, eben keine vorhandene Ringpuffer-Bilbiothek zu verwenden, sondern eigene "lineare Puffer" mit, auf die Telegrammstruktur angepaßten Schreib-/Leseroutinen zu implementieren...
     
    #14 LotadaC, 23. November 2017
    Zuletzt bearbeitet: 23. November 2017
  15. addi

    addi Mitglied

    Registriert seit:
    2. September 2013
    Beiträge:
    79
    Zustimmungen:
    3
    Ort:
    Hamminkeln
    Sprachen:
    BascomAVR, C, Assembler
    Hmmm...wuerde mich in den teil der empfangsroutine einklinken, wo das empf. Byte aus dem hardware teil gelesen wird. Den vorhandenen ringbuffer auf 1 byte setzen. Dafür einen eigenen buffer aufmachen und das receive byte dort ablegen.vor dem ablegen auf ein endezeichen testen und damit die routine aufrufen, die dir den buffer leert.
    Addi
     
  16. Dirk

    Dirk Administrator Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.070
    Zustimmungen:
    100
    Ort:
    Mittelhessen, Giessen
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Map
    Ich hatte schon einmal erwähnt, dass uart_getc() uint16_t zurück gibt.

    Dies geht so eigentlich nicht ...


    CodeBox C und C++
    for(uint8_t x = 0 ; x < UART_RX_BUFFER_SIZE ; x++)
    {
       tmpBuff[x] = uart_getc();
    }


    ... da uart_getc() gundsätzlich etwas zurück gibt, auch wenn der Buffer leer ist, nichts empfangen oder ein Fehler erkannt wurde.
    tmpBuff ist also ganz schnell voll, aber nicht unbedingt mit den empfangenen Daten.
     

Diese Seite empfehlen

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