Forum: Mikrocontroller und Digitale Elektronik Baudrate nur 12286 baud statt 34800, (stm32) Cortex m3 + Keil


von cell85 (Gast)


Lesenswert?

Guten Abend,

ich versuche mit einem angelöteten BT Modul über meine USART2 verbindung 
aufzunehmen. Aber Keil sagt mir das die USART nur mit 12286 baud läuft 
statt eingestellte 34800, mach irgendwas falsch ???

Die USART Konfig


  /* USART2 Clock an*/
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

  /*Init USART2 USART2: CTS PA0, RTS PA1, TX PA2, RX PA3 */

  /* Configure USART2 RTS and USART2 Tx as alternate function push-pull 
*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Configure USART2 CTS and USART2 Rx as input floating */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  USART_InitStructure.USART_BaudRate = 38400;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = 
USART_HardwareFlowControl_RTS_CTS;
  //USART_InitStructure.USART_HardwareFlowControl = 
USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_Init(USART2, &USART_InitStructure);
  USART_Cmd(USART2, ENABLE);

ist da irgendwo ein divider drin oder muss ich vielleicht die baudrate 
so erhöen das ich auf meine 38400 komme??

Viele Grüße!
cell

von (prx) A. K. (prx)


Lesenswert?

In der Baudratenrechnung der Library steckt die angenommene Taktfrequenz 
drin. Wenn die nicht mit der Realität übereinstimmt, dann stimmt die 
Baudrate natürlich auch nicht.

Nehmen wir also an, du willst den Controller mit 24MHz betreiben, hast 
das auch angegeben, er läuft aber tatsächlich noch mit seinen 
ursprünglichen ca. 8MHz. Dann liegt die Baudrate bei ca. 38400/3 = 
12800.

von Peter D. (peda)


Lesenswert?

Versehentlich ein Oberwellenquarz genommen.

Peter

von holger (Gast)


Lesenswert?

>Versehentlich ein Oberwellenquarz genommen.

Eher nicht.

Ruf in main() mal  SystemInit(); auf.
Vieleicht macht dein Startup Code das nicht.

>Nehmen wir also an, du willst den Controller mit 24MHz betreiben, hast

Oder es sind 72MHz angegeben und er läuft nur mit 24MHz.
Bei der ST Lib muss man auch noch angeben ob es ein LD Low Density, HD 
High Density, CL Connectivity Line oder sonst was ist.
Also auch mal die Compiler Optionen checken.

von cell85 (Gast)


Lesenswert?

eigentlich hab ich da ncihts eingestellt und auf dem anderen board geht 
es ja bei selben code.

Ich habe einen quarz des typs benutzt:
SMD crystal ABM3 (Abracon) PDF wurde beigelegt.
auf dem IC steht drauf 160ADOG (Buchstabe O oder Null).
Ich bin der Annahme das er 8Mhz hat.
Im Schematic/Layout steht allerdings HC49UP.

Gute Frage.... was ist das jetzt hier für ein Quarz??
Das könnte vielleicht auch mit meinem Problem zusammenhängen wieso mein 
Trace nicht geht.


Wie kann ich dann von Hse auf Hsi umswitchen ?

mein Code für die RCC init schaut so aus:



void SetupClock (void)
{

    RCC_DeInit ();                                /* RCC system 
reset(for debug purpose)*/
    RCC_HSEConfig (RCC_HSE_ON);                   /* Enable HSE */

/* Wait till HSE is ready */
    while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);

    RCC_HCLKConfig   (RCC_SYSCLK_Div1);           /* HCLK   = SYSCLK  */
    RCC_PCLK2Config  (RCC_HCLK_Div1);             /* PCLK2  = HCLK    */
    RCC_PCLK1Config  (RCC_HCLK_Div2);             /* PCLK1  = HCLK/2  */
    RCC_ADCCLKConfig (RCC_PCLK2_Div6);            /* ADCCLK = PCLK2/6 */

    FLASH_SetLatency(FLASH_Latency_2);            /* Flash 2 wait state 
*/
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

/* PLLCLK = 8MHz * 9 = 72 MHz */
    RCC_PLLConfig (RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

    RCC_PLLCmd (ENABLE);                          /* Enable PLL */

/* Wait till PLL is ready */
    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

/* Select PLL as system clock source */
    RCC_SYSCLKConfig (RCC_SYSCLKSource_PLLCLK);

/* Wait till PLL is used as system clock source */
    while (RCC_GetSYSCLKSource() != 0x08);

    SysTick_Config(72*1000*10);

}



Peda du hast mich echt zum nachdenken gebracht! im guten sinne!

von holger (Gast)


Lesenswert?

>eigentlich hab ich da ncihts eingestellt und auf dem anderen board geht
>es ja bei selben code.

Das hättest du ja auch gleich sagen können.

>Ich habe einen quarz des typs benutzt:
>SMD crystal ABM3 (Abracon) PDF wurde beigelegt.

Wo?

>Ich bin der Annahme das er 8Mhz hat.

Nicht annehmen, MESSEN.

von (prx) A. K. (prx)


Lesenswert?

cell85 schrieb:

> SMD crystal ABM3 (Abracon) PDF wurde beigelegt.

Dem Quarz beigelegt? Nett vom Lieferanten.

von cell85 (Gast)


Angehängte Dateien:

Lesenswert?

Bild des quarz

von cell85 (Gast)


Angehängte Dateien:

Lesenswert?

Bild des Oszilloskop's bei Einstellungen:

10x Tastkopf

TIME/DIV: 0,1µs
mV/DIV: 50
Trig: AC

Hameg 204-2 (20mhz)  Alt aber ausreichend.


Eine Periode = ist 3 Div's lang

3* 0,1µs = 0,3µs
1/0,3µs = 3,33 Mhz???

Hab ich etwa ein Quarz mit 3,33 mhz??? statt 8 bestückt bekommen??

ALTER SCHWEDE sagt mir bitte das ich falsch liege!!! aber die baud der 
USART sprechen für!

von (prx) A. K. (prx)


Lesenswert?

cell85 schrieb:

> Eine Periode = ist 3 Div's lang

Nicht in diesem Bild. Da sind es eher 1,5 Perioden pro Teilung. Das 
wären dann um die 16MHz, was auch besser zur Aufschrift passt. Und beim 
Versuch, dein Controllerchen mit 144MHz zu takten...

Apropos Baudrate: Hast du die genauso mit dem Oszi gemessen wie den 
Quarz?

von cell85 (Gast)


Lesenswert?

sorry das war mein fehler hab ein anderes bild benutzt. -.-

oki, wie müsste ich dann den Code ändern um 16Mhz zu nutzen?

/* PLLCLK = 8MHz * 9 = 72 MHz */
    RCC_PLLConfig (RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

wie mach ich das durch 2 ? so ?

// 16/2 * 9 ?
RCC_PLLConfig (RCC_PLLSource_HSE_Div2, RCC_PLLMul_9);

von cell85 (Gast)


Lesenswert?

Apropos Baudrate: Hast du die genauso mit dem Oszi gemessen wie den
Quarz?:

Ha Ha Ha  :P

nein aber das resultiert bestimmt auf Grund dessen.

Vielen Dank für eure hilfe soweit! Ich hätt geweint :D !

von (prx) A. K. (prx)


Lesenswert?

cell85 schrieb:

> oki, wie müsste ich dann den Code ändern um 16Mhz zu nutzen?

Den HSE halbiert benutzen.
Siehe RCC_CFGR.PLLXTPRE bei manchen der STM32.
In die Lib übersetzen musst du es dir selber.

von cell85 (Gast)


Lesenswert?

hab aber merkwürdigerweise immer noch das drittel der baud.

ich find auch keine Stelle in der LIB oder so wo die PLL für usart 
eingestellt werden kann.

von holger (Gast)


Lesenswert?

>hab aber merkwürdigerweise immer noch das drittel der baud.

Ach was.

>ich find auch keine Stelle in der LIB oder so wo die PLL für usart
>eingestellt werden kann.

Stell erst mal fest mit welchem Takt der ARM jetzt wirklich läuft.
Wenn ich mich nicht irre wolltest du 72MHz. Du hast 24MHz weil
deine Baudrate nicht stimmt. Welche Version der ST Lib hast du?
3.4.0? Nimm mal die 3.5.0. Die zwingt dich dazu ein LD,HD,CL oder
XL per Compiler Option auszuwählen.

Bei GCC -DSTM32F10X_HD als Beispiel.

von cell85 (Gast)


Angehängte Dateien:

Lesenswert?

Ich verwende 3.5.0 und in den defines habe ich bereits STM32F10X_HD, 
USE_STDPERIPH_DRIVER  angegeben.

MCU soll 72mhz haben

Keil zeigt mir an (siehe bild)

von cell85 (Gast)


Angehängte Dateien:

Lesenswert?

hier noch eins von der USART2

von (prx) A. K. (prx)


Lesenswert?

Ok, nun kommt der schöne Teil. Der Teil nämlich, der mit dazu 
beigetragen hat, dass ich einen Bogen um die Library mache und direkt 
auf die Register gehe (zumal die deutlich besser dokumentiert sind).

Jetzt schaust du in den Sourcecode der Baudratenerzeugung in der Lib und 
versuchst heruszubekommen, wie man die mit irgendwelchen Takt- und 
Typ-Defines oder Wasweissich bewerfen muss, damit im Ratenregister der 
richtige Wert drinsteht. Reverse-Engineering.

Ich persönlich mache es mir da einfacher:
   BRR = UART-Takt / Baudrate
Aber es geht natürlich auch komplizierter.

von cell85 (Gast)


Lesenswert?

uint32_t USART_BaudRate;            /*!< This member configures the 
USART communication baud rate.
                                           The baud rate is computed 
using the following formula:
                                            - IntegerDivider = ((PCLKx) 
/ (16 * (USART_InitStruct->USART_BaudRate)))
                                            - FractionalDivider = 
((IntegerDivider - ((u32) IntegerDivider)) * 16) + 0.5 */


PCLK1 hat 36mhz wie man anhand des screenshot sieht. Kann es das sein ?

von holger (Gast)


Lesenswert?

>MCU soll 72mhz haben

Das geht bei einem 16MHz Quarz aber nicht.
Die PLL darf dann maximal Faktor 4 haben.
Das gibt dann 64MHz. Faktor 5 wäre schon 80MHz.
Du gibts aber Faktor 9 an. Und das geht nicht.
Besorg dir einen 8MHz Quarz.

von (prx) A. K. (prx)


Lesenswert?

> using the following formula

Na dann hat jemand das tatsächlich mal renoviert. Als ich da das letzte 
Mal reinsah war das noch Code, der in dezimaler Festkommarechnung mit 
100 (geschrieben als 0x64) multipliziert herumrechnete und so auf höchst 
komplizierte Weise zum gleichen Ergebnis kam.

Ich hatte in meinem Beispiel nur die Rundung weggelassen. Auf die kommts 
praktisch nicht an. Dass das von den Hardware-Leuten geschickt 
konzipierte Layout vom BRR die Rechnerei mit 16 obsolet macht ist aber 
offenbar immer noch niemandem aufgefallen.

von (prx) A. K. (prx)


Lesenswert?

holger schrieb:

> Das geht bei einem 16MHz Quarz aber nicht.

Doch, weil zwischen HSE und PLL ein einstellbarer Vorteiler ist.

von cell85 (Gast)


Lesenswert?

holger schrieb:
> Das geht bei einem 16MHz Quarz aber nicht.
> Die PLL darf dann maximal Faktor 4 haben.
> Das gibt dann 64MHz. Faktor 5 wäre schon 80MHz.
> Du gibts aber Faktor 9 an. Und das geht nicht.
> Besorg dir einen 8MHz Quarz.

kann aber nicht sein, da war doch auch vorher *9 drin ich hab die 16 mit 
DIV2 durch 2 geteilt also wieder meine 8Mhz. In keil wird ja auch 72 
angezeigt.

von cell85 (Gast)


Lesenswert?

in der lib muss man tatsächlich noch 8 auf 16 umstellen. ich werde das 
mal testen!

von (prx) A. K. (prx)


Lesenswert?

Ok, ich weiss nicht was das von dir oben gezeigt für Code war, aber der 
in der FWlib 3.5.0 sieht nur marginal besser aus als der den ich früher 
drin fand. Jedenfalls wärs nicht schlecht, mal auszutesten, was bei
   RCC_GetClocksFreq(&RCC_ClocksStatus);
tatsächlich rauskommt. Also mit welchem Wert von PCLK dieser schaurig 
schöne Baudratencode tatsächlich rechnet.

von cell85 (Gast)


Angehängte Dateien:

Lesenswert?

hi, da bin ich wieder.

so ich hab das projekt komplett neu aufgebaut in keil.
XTAL ist auf 16.0 eingestellt. das bewirkt ja praktisch den define der 
HSE so das man das nich in der stf10x.c bzw. conf.h ändern muss.

jetzt ist das lustige, dass ich statt einem drittel der baud auf einmal 
das doppelte habe, sprich 76xxx baud (siehe screenshot.)

lustig. ich probiere mal mein eval board da sind ja die "musthave 
werte".

das usart2 läuft ja über den RCC_APB2PeriphClock. Kann sein das der 
jetzt doppelt so schnell läuft.

von cell85 (Gast)


Angehängte Dateien:

Lesenswert?

zum vergleich mal das KEIL MCBSTM32EXL board abgesehen von dem 
absichtlich eingestellten ADCclock ist dort der PLLXPRE aus. Für was ist 
der eigentlich?

von cell85 (Gast)


Lesenswert?

Die Lösung!

Keil = XTAL 16.0 einstellen

UND zusätzlich !!! weil Keil scheinbar damit nicht HSE_VALUE definiert

unter den Preprocessor Defines das eintragen:

USE_STDPERIPH_DRIVER, STM32F10X_HD, HSE_VALUE=16000000

tattaaaaa baudrate stimmt :) ich bin glücklich das ich jetzt schlafen 
kann!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.