Baudrate nur 12286 baud statt 34800, (stm32) Cortex m3 + Keil

Gast #2448056
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
#2448069
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.
Gast #2448127
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.
Gast #2448134
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!
Gast #2448149
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.
Gast #2448219
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!
Angehängte Dateien:
Gast #2448256
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);
Gast #2448261
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 !
Gast #2448329
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.
#2448405
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.
Gast #2448408
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 ?
Gast #2448414
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.
#2448415
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.
Gast #2448426
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.
#2448441
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.
Gast #2448553
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.
Angehängte Dateien:
Gast #2448564
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!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren