Forum: Mikrocontroller und Digitale Elektronik STM32F103 ohne Quartz und Mbed


von Florian F. (flof3000)


Lesenswert?

Hallo Forum,

ich benutze einen STM32F103C8T6 auf einem selbstgestalteten Board in 
Minimalstbeschaltung - nur Abblockkondensatoren, kein Quartz.

Als Umgebung kommt mBed zum Einsatz (unter platformio),
und das initialisiert irgendwo die Uhr.

Und zwar so, dass der Kontroller mit 36 Mhz läuft,
mBed aber glaubt dass er mit 72 Mhz liefe , und jetzt sind alle meine 
Waits doppelt so lang wie sie sein sollten, und mit meinem 
OneWire-Sensor DS18B20 wird das so natürlich nichts.

Nur: Ich bin zu doof rauszugoogeln wo ich
mBed von einer anderen Frequenz überzeugen kann.
Also, dass mBed dann mit einer anderen F_CPU = x rechnet.

(Die Clock selber anzupassen ist zwar auch noch geplant,
aber das steht ja in RM0008. Soll später mal am Akku laufen,
und braucht keinerlei Rechenleistung.)

Gruss
FloF

von Florian F. (flof3000)


Lesenswert?

Korrektur: Er glaubt an 64 Mhz, und es sind 32.

'Einfach' SystemCoreClock in der main() umzusetzen hilft aber auch 
nicht.

von Johannes S. (Gast)


Lesenswert?

Der Timer wird vor Eintritt in die main() initialisiert und die 
Takteinstellungen sind fix im init code. Du kannst versuchen das 
nachträglich wieder umzubiegen, vielleicht klappt das hier (ohne 
Gewähr):

in deine main.cpp:
1
#include <mbed.h>
2
3
#include "stm32f1xx.h" 
4
#include "hal_tick.h"
5
6
/******************************************************************************/
7
/*            PLL (clocked by HSI) used as System clock source                */
8
/******************************************************************************/
9
uint8_t SetSysClock_PLL_HSI(void)
10
{
11
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
12
  RCC_OscInitTypeDef RCC_OscInitStruct;
13
14
  /* Enable HSI oscillator and activate PLL with HSI as source */
15
  RCC_OscInitStruct.OscillatorType      = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSE;
16
  RCC_OscInitStruct.HSIState            = RCC_HSI_ON;
17
  RCC_OscInitStruct.HSEState            = RCC_HSE_OFF;
18
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
19
  RCC_OscInitStruct.PLL.PLLState        = RCC_PLL_ON;
20
  RCC_OscInitStruct.PLL.PLLSource       = RCC_PLLSOURCE_HSI_DIV2;
21
  RCC_OscInitStruct.PLL.PLLMUL          = RCC_PLL_MUL16; // 64 MHz (8 MHz/2 * 16)
22
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
23
  {
24
    return 0; // FAIL
25
  }
26
 
27
  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
28
  RCC_ClkInitStruct.ClockType      = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
29
  RCC_ClkInitStruct.SYSCLKSource   = RCC_SYSCLKSOURCE_PLLCLK; // 64 MHz
30
  RCC_ClkInitStruct.AHBCLKDivider  = RCC_SYSCLK_DIV1;         // 64 MHz
31
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;           // 32 MHz
32
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;           // 64 MHz
33
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
34
  {
35
    return 0; // FAIL
36
  }
37
38
int main() 
39
{
40
    SetSysClock_PLL_HSI();
41
    HAL_InitTick(0);
42
43
    // und ab hier dein Code
44
}

Das ist natürlich ein übler Hack. Besser ist es die Lib selber zu 
kompilieren und die Änderungen in system_stm32f1xx.c ordentlich 
einzupflegen.

von Florian F. (flof3000)


Lesenswert?

Danke!

Stellt sich raus, es ist nicht die die Clock.
Irgendwie wartet wait_us immer mindestens 1 Millisekunde.
Und da meine Pause bei 480us war, sah das aus wie verdopplelt.
Noch dazu dass in der Library auch noch ein wait(2) drin war,
so dass das auch verdopplelt war.

Und fuer ungenaues wait_us findet man dann auch was im Mbed Forum:
https://developer.mbed.org/questions/69346/Wait-function-shows-incorrect-timing-on-/

Danke nochmal,
Gruss
FloF

von Johannes S. (Gast)


Lesenswert?

In der Timer Implementierung für den F103 hatte ich auch schon 
vergeblich Fehler gesucht. Ich habe das IRMP für mbed portiert und auf 
dem F103 lief das nicht wegen des Timerfehlers. In der aktuellen mbed 
Version wurde der Timer überarbeitet und sah besser aus, ist aber 
vielleicht noch nicht perfekt.
Das Ur-mbed war ja für die LPC und die haben 32 Bit Timer, da ist die 
Implementierung einfach. Beim STM32F1 wird ein 16 Bit Timer auf 32 Bit 
erweitert und das hat seine Tücken.
Von der Version 129 sind die aktuellen Quellen auch wieder Online (wenn 
du nicht mbed-os verwendest):
https://developer.mbed.org/users/mbed_official/code/mbed-dev/
Auch wenn da vieles gut funktioniert ist es immer gut zu sehen wie die 
Dinge realisiert sind.

von Florian F. (flof3000)


Lesenswert?

Well, ich hab's auch nicht hinbekommen.
Die Vorschlaege im Forum machen es besser, aber nicht gut.

Habe jetzt 'ne Funktion auf Basis von Data Watchpoint und Trace 
Registern:

https://kbiva.wordpress.com/2013/03/25/microsecond-delay-function-for-stm32/

Mit dem Salea 'getunt' - muss 3 us von der gewünschten Dauer abziehen,
und dann spricht mein DS18B20 mit mir.

Und ich muss mir keine an Platformio vorbei modifizierte Mbed Variante 
hinlegen.

von Johannes S. (Gast)


Lesenswert?

Wird für den DS one wire nicht auch der Ein/Ausgang eines Pins 
umprogrammiert? Da hatte ich gelesen das das auch sehr langsam läuft 
weil es durch den HAL geht und immer ein Init dazwischen ist.

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Wie schon in anderen Threads geschreiben: One-Wire geht auch mit Uart 
oder 2-Kanaltimer und braucht dann kein delay() sondern erzeugt die 
One-Wire Primitive hardwaremaessig. Da One-Wire recht tolerant im Timing 
ist, sollte es auch mit dem internen RC Oszillator gehen.

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.