C XMEGA -> USART -> SPI Mode

Dieses Thema im Forum "Software" wurde erstellt von Janiiix3, 20. Juli 2018.

  1. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.230
    Zustimmungen:
    7
    Punkte für Erfolge:
    38
    Sprachen:
    C
    Moin,

    Die Baudrate passt überhaupt nicht habe ich das Gefühl.
    Habe ich was bei der Berechnung übersehen?



    CodeBox C und C++
    
    #define SPI_USART_CALC_BSEL( BSEL ) ([I]uint16_t[/I]) ( F_CPU / ( 2 * ( BSEL + 1 ) ) )
    
    #define SPI_USART_CALC_BAUD( BAUD ) ([I]uint16_t[/I]) ( ( F_CPU / ( SPI_USART_CALC_BSEL( BAUD ) * 2 ) ) - 1 )
    
    
    /* set baudrate */
    
    
    usartx->usartUnit->BAUDCTRLA = ( SPI_USART_CALC_BAUD ( baud ) & 0x00FF );
    
    usartx->usartUnit->BAUDCTRLB = ( ( SPI_USART_CALC_BAUD ( baud ) & 0x0F00 ) >> 8 );
    



    upload_2018-7-20_10-3-0.png
     
  2. Dirk

    Dirk Administrator
    Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.189
    Zustimmungen:
    119
    Punkte für Erfolge:
    63
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Hallo Jan,

    musst du nicht einfach nur die Gleichung in der Tabelle unten rechts verwenden, um BSEL zu ermitteln? Du mixt das irgendwie mit der Gleichung links daneben (die ist aber identisch nur umgestellt nach FBAUD).

    Dirk :ciao:
     
  3. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.925
    Zustimmungen:
    44
    Punkte für Erfolge:
    48
    Sprachen:
    BascomAVR, Assembler
    Ja, in den beiden Baud-Controlregistern stehen die 12 Baud-Rate-Bits (BSEL11..0) und die vier Baud-Rate-Scale-Factor-Bits (BSCALE3..0).
    Wenn also eine vorgegebene Baudrate eingestellt werden soll, müssen die entsprechenden BSELs berechnet und zugewiesen werden. Also die BSEL-Formel verwenden.

    (Die andere Formel brauchst Du nur, wenn Du aus einer gegebenen BSEL-Einstellung die tatsächliche Baudrate berechnen willst (zB zum Bestimmen eines Baudratenfehlers. Ich hatte auch mal einen UART (+PWM-Timer) über 'ne IR-LED und'n TSOPfragmichmal geschickt. Die Baudrate wurde mittels Tastern ähnlich der BSELs eingestellt. Da habe ich dann die tatsächliche Baudrate auf'm Display sehen wollen (um zu sehen, wie weit der TSOP mitkam)).

    In der Tabelle tauchen beim SPI-Mode keine fraktionellen Anteile mehr auf - die greifen nur im konventionellen UART? (will mich jetzt nicht durch das DB kauen...)
     
  4. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    250
    Zustimmungen:
    19
    Punkte für Erfolge:
    18
    Sprachen:
    C, Assembler
  5. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.230
    Zustimmungen:
    7
    Punkte für Erfolge:
    38
    Sprachen:
    C
    Sag nicht das du dafür die Google Suche nehmen musstest um auf meine Frage zu antworten.

    Ja, da für die anderen die Frage wohl zu leicht ist, haben sie es nicht für nötig gehalten mir zu helfen.
    Müssen sie ja auch nicht.

    Ich danke dir @Mikro23 für deine Unterstützung. Weiter so!
     
  6. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    250
    Zustimmungen:
    19
    Punkte für Erfolge:
    18
    Sprachen:
    C, Assembler
    Du hast es grade nötig.

    Wenn man Dich bittet ein compilierbares Projekt zu posten, wirst Du pampig

    Dutzende von crosspostings in einem Jahr, obwohl Du mehrfach darauf hingewiesen wurdest, daß das nicht gerne gesehen wird.

    Danach muß man nicht suchen, die fallen auf, egal unter welchem Pseudonym Du grade schreibst.

    Wer nicht sagen kann oder will, wo er sonst noch überall fragt oder gefragt hat, dem unterstelle ich, daß er entweder zu faul oder zu blöd ist…

    Bricht Dir ein Zacken aus der Krone, wenn Du schreibst (mit Link, und zwar in beiden Foren) wo Du zum Thema noch fragst?

    Mehr verlangt doch niemand.

    Dann weiß man, was andere schon geantwortet haben und braucht nicht nochmal das gleiche zu schreiben und kann sogar noch darauf aufbauen. Es läge also sogar noch in Deinem eigenen Interesse, wenn Du tatsächlich eine Lösung finden wolltest.

    Wenn man allerdings nur raubmordkopieren und nichts lernen will, bleibt man natürlich besser anonym...
     
    #6 Mikro23, 20. Juli 2018
    Zuletzt bearbeitet: 20. Juli 2018
  7. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.230
    Zustimmungen:
    7
    Punkte für Erfolge:
    38
    Sprachen:
    C
    Am Anfang hatte ich diese Formel genommen gehabt.


    CodeBox C und C++
    #define SPI_USART_CALC_BAUD( BAUD ) (uint16_t) ( ( F_CPU / ( F_CPU * 2  )  )  - 1 )
    

    Also sollte es damit gegessen sein?
     
  8. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.230
    Zustimmungen:
    7
    Punkte für Erfolge:
    38
    Sprachen:
    C
    Das man noch auf solch alten Pferden reitet. Das Projekt von damals konnte ich mit einem ATMEL Studio 7.x kompilieren. Ich weiß ehrlich gesagt auch nicht wieso das bei Dir nicht funktionierte.

    Gebe ich ja auch zu. Ich komme mir wirklich "doof" vor, wenn ich etwas nicht verstehe und hier direkt ein "Thema" dazu aufmache. In dem anderen Forum, fallen so "kleine" Fragen überhaupt nicht groß auf.
    Da dort leider auch keine Antwort kam und ich gerne wissen möchte was ich falsch mache, habe ich hier um Hilfe gebeten.

    Das ist deine Sache, was du anderen unterstellst ;)
     
  9. Dirk

    Dirk Administrator
    Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.189
    Zustimmungen:
    119
    Punkte für Erfolge:
    63
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Der Parameter BAUD kommt in der Gleichung nicht vor. Das funktioniert so garnicht.

    Ich habe nicht in das Datenblatt geschaut, nach deinem Screenshot wird es wahrscheinlich so in Ordnung sein:

    BSEL = (FPER / (2 x FBAUD)) -1

    FPER ist die Taktfrequenz für das Peripheriemodul, das wird bei dir FCPU sein.

    Ich habe selber bei Xmega schon das UART Modul im MasterSPI Mode verwendet, müsste aber jetzt mein Projekt raussuchen ... wird aber mit obiger Gleichung schon stimmen.

    Berechne BSEL doch einfach auch mal manuell für deinen Fall.

    Offtopic:
    Wegen den Crosspostings, wäre es schon gut, wenn du kurz drauf hinweist.
    Das wäre fair zu denjenigen, welche dir hier versuchen zu helfen.
    https://de.wikipedia.org/wiki/Crossposting#Crossposting_in_Webforen
     
  10. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.230
    Zustimmungen:
    7
    Punkte für Erfolge:
    38
    Sprachen:
    C
  11. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.230
    Zustimmungen:
    7
    Punkte für Erfolge:
    38
    Sprachen:
    C
    Moin,

    @Dirk bist Du sicher das dass richtig ist?
    9600 Baud ist langsamer..


    CodeBox C und C++
    spiUsartxInit( spiUsart , 9600 , USART_SPI_MODE0 , USART_SPI_MSB_FIRST );
    


    als wenn ich z.B


    CodeBox C und C++
    spiUsartxInit( spiUsart , 40 , USART_SPI_MODE0 , USART_SPI_MSB_FIRST );
    

    nehme..

    Müsste es nicht eigentlich bei höheren Baudraten schneller gehen und nichts anders herum 0.o?

    Hier initialisiere ich das Modul..


    CodeBox C und C++
    void spiUsartxInit( spiIO_t *usartx , uint16_t baud , usartxSpiMode_enum mode , usartxSpiDataOrder_enum dataOrder )
    {
     usartx->ports.spi->DIRSET   = (1<<usartx->bitPos.mosi);
     usartx->ports.spi->DIRSET   = (1<<usartx->bitPos.sck);
     
     usartx->ports.spi->DIRCLR   = (1<<usartx->bitPos.miso);
    
     
     /* master spi mode */
     usartx->usartUnit->CTRLC   = USART_CMODE_MSPI_gc;
     
      /* set baudrate */
     usartx->usartUnit->BAUDCTRLA  = SPI_USART_CALC_BSEL( baud ) & 0x00FF;
     usartx->usartUnit->BAUDCTRLB  = ( SPI_USART_CALC_BSEL( baud ) & 0x0F00 ) >> 8;
     
     switch ( dataOrder )
     {
      case USART_SPI_LSB_FIRST:
      {
       usartx->usartUnit->CTRLC |= ( 1<<USARTx_UDORD_bp ); // lsb first
      }break;
     
      case USART_SPI_MSB_FIRST:
      {
       usartx->usartUnit->CTRLC &= ~( 1<<USARTx_UDORD_bp ); // msb first
      }break;
     
      default:
      {
       usartx->usartUnit->CTRLC |= ( 1<<USARTx_UDORD_bp ); // lsb first
      }
     }
    
     
     /* set spi mode */
     switch ( mode )
     {
      case USART_SPI_MODE0: // Rising, sample  | Falling, setup
      {
       usartx->ports.spi->PIN1CTRL &= ~( PORT_INVEN_bm ); // clear inverted mode
       usartx->usartUnit->CTRLC &= ~( 1<<USARTx_UCPHA_bp );
      }break; // mode 0
      
      case USART_SPI_MODE1: // Rising, setup   | Falling, sample
      {
       usartx->ports.spi->PIN1CTRL &= ~( PORT_INVEN_bm ); // clear inverted mode
       usartx->usartUnit->CTRLC |=  ( 1<<USARTx_UCPHA_bp );
      }break; // mode 1
      
      case USART_SPI_MODE2: // Falling, sample | Rising, setup
      {
       usartx->ports.spi->PIN1CTRL |=  (PORT_INVEN_bm); // set inverted mode
       usartx->usartUnit->CTRLC &= ~(1<<USARTx_UCPHA_bp);
      }break; // mode 2
      
      case USART_SPI_MODE3: // Falling, setup  | Rising, sample
      {
       usartx->ports.spi->PIN1CTRL |= (PORT_INVEN_bm); // set inverted mode
       usartx->usartUnit->CTRLC |= (1<<USARTx_UCPHA_bp);
      }break; // mode 3
      
      default: // Falling, setup  | Rising, sample
      {
       usartx->ports.spi->PIN1CTRL |= (PORT_INVEN_bm); // set inverted mode
       usartx->usartUnit->CTRLC |= (1<<USARTx_UCPHA_bp);
      }break; // mode 3
     }
    
     PR.PRPC &= ~PR_USART0_bm; // enable USART
     
      /* enable spi receive enable & transmit enable */
      usartx->usartUnit->CTRLB |= ( ( 1<<USARTx_RXEN_bp ) | ( 1<<USARTx_TXEN_bp ) );
    }
    
     
  12. Dirk

    Dirk Administrator
    Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.189
    Zustimmungen:
    119
    Punkte für Erfolge:
    63
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Wie sieht denn nun deine Berechnung von BSEL aus?

    SPI_USART_CALC_BSEL( baud )

    Zuvor hatte hier ja etwas nicht gestimmt.
     
  13. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.230
    Zustimmungen:
    7
    Punkte für Erfolge:
    38
    Sprachen:
    C


    CodeBox C und C++
    #define SPI_USART_CALC_BSEL( BAUD ) ([I]uint16_t[/I]) ( F_CPU / ( 2 * BAUD ) ) - 1
    
     
  14. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    250
    Zustimmungen:
    19
    Punkte für Erfolge:
    18
    Sprachen:
    C, Assembler
    Hast Du einen Taschenrechner?
    Dann kannst Du sehr leicht ausrechnen, was da passiert.
    BSEL hat 12 Bit, also paßt da keine Zahl rein, die größer als 4095 bzw. 0xFFF ist.
    Setz mal 40 in die Formel ein (in die Formel für die Baudrate natürlich und nicht in die für BSEL).
    Um eine Baudrate von 40 einzustellen, darf F_CPU nicht größer als 327,68 kHz sein.

    Das passiert, wenn man Code kopiert, der keine Überprüfung sinnvoller Grenzen macht...
     
  15. Dirk

    Dirk Administrator
    Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.189
    Zustimmungen:
    119
    Punkte für Erfolge:
    63
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Ja, ich hatte auch gerade nachgerechnet.

    Wahrscheinlich ist F_CPU 32.000.000
    Dann wäre bei 40 Baud BSEL ca. 40.000, das geht somit nicht.
     
  16. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.925
    Zustimmungen:
    44
    Punkte für Erfolge:
    48
    Sprachen:
    BascomAVR, Assembler
    Zettel und Bleistift tun's auch..
    In dem Zusammenhang hat mich mal geärgert, daß man im Studio beim kompilieren zwar Warnings und Errors werfen lassen kann, aber dabei leider keine berechneten Compilerkonstanten ausgeben lassen kann...
     
  17. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.230
    Zustimmungen:
    7
    Punkte für Erfolge:
    38
    Sprachen:
    C
    Stimmt. Er war bei 40 nur flotter weil die Berechnungen übergelaufen ist.. Bei 40 komme ich auf 65535. Das heißt es müsste dann im Register ne 1 stehen?
     
  18. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.230
    Zustimmungen:
    7
    Punkte für Erfolge:
    38
    Sprachen:
    C
    Stimmt.
    Vill. werden unsere Wünsche irgendwann nochmal erhöhrt.
     
  19. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.230
    Zustimmungen:
    7
    Punkte für Erfolge:
    38
    Sprachen:
    C
    Okay..
    Was genau ist der Unterschied zwischen


    CodeBox C und C++
    #define F_CPU         32e6
    


    Und..


    CodeBox C und C++
    #define F_CPU         32000000
    

    ???

    Mit


    CodeBox C und C++
    #define F_CPU         ( uint32_t ) 32e6
    

    klappt es dann.. muss ich alles was größer als int ist bei nem #define casten?
     
  20. Dirk

    Dirk Administrator
    Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.189
    Zustimmungen:
    119
    Punkte für Erfolge:
    63
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Wie kommst du auf 65535 und 1?

    Wenn du F_CPU 32MHz hast, kommt für BSEL 399.999 raus, geht also nicht. Max zulässig wären BSEL 4095d (12bit, 0xFFF).

    Kleinstes FBAUD bei 32MHz wären 3906,25, wenn ich mich jetzt nicht vertippt habe.
     
  • Ü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)
  1. Diese Seite verwendet Cookies, um Inhalte zu personalisieren und die Seite optimal für dich anzupassen. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden