Forum: Mikrocontroller und Digitale Elektronik STM32F1 Cube HAL Systemtakt funktioniert nicht


von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
ich glaube, CubeMX erzeugt fehlerhaften Code zur Konfiguration des 
Systemtaktes.

Eigentlich wollte ich die USB Library von Cube HAL auf einem 
STM32F103C8T6 Board aus China ausprobieren. Allerdings blinkt meine LED 
nicht und Windows kann die USB Device-ID nicht abfragen.

Um das Problem weiter einzugrenzen, habe ich den USB Kram mal raus 
gelassen. Die LED blinkt immer noch nicht. Folgendes habe ich gemacht:

1) Neues Projekt mit CubeMX erstellt.
Prozesor ausgewählt, Debugging via SWD eingestellt, HSE Oszillator 
aktiviert, PC13 als Ausgang für die LED eingestellt (Pinout.png).

2) Clock Configuration: 8Mhz HSE mit 6x PLL = 48Mhz 
(Clock-Configuration.png)

3) In die Hauptschleife habe ich folgendes eingefügt:
1
while (1)
2
{
3
     // LED On
4
    HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET);
5
    HAL_Delay(1000);
6
7
    // LED Off
8
    HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_RESET);
9
    HAL_Delay(1000);
10
}

Die LED bleibt jedoch dunkel.

Dann habe ich die Takt-Konfiguration geändert: HSI/2 mit 12x PLL = 48Mhz 
(Clock-Configuration-HSI-geht.png)

Jetzt blinkt die LED im 1 Sekunden Takt. Daher dachte ich zuerst, das 
Board (bzw. der Quarz) sei defekt. Aber mein Gegentest mit folgendem 
Programm (ohne HAL) läuft einwandfrei:
1
#include <stdint.h>
2
#include "stm32f1xx.h"
3
4
// This variable is used by some CMSIS functions
5
uint32_t SystemCoreClock=8000000;
6
7
// Milliseconds counter
8
volatile uint32_t systick_count=0;
9
10
11
void SysTick_Handler(void)
12
{
13
  systick_count++;
14
}
15
16
17
// Called by Assembler startup code
18
void SystemInit(void)
19
{
20
  // Enable HSE oscillator
21
  SET_BIT(RCC->CR, RCC_CR_HSEON);
22
23
  // Wait until HSE oscillator is ready
24
  while(!READ_BIT(RCC->CR, RCC_CR_HSERDY)) {}
25
26
  // 48Mhz using the 8Mhz HSE oscillator divided by 1 with 6x PLL, lowspeed I/O runs at 24Mhz
27
  WRITE_REG(RCC->CFGR, RCC_CFGR_PLLSRC + RCC_CFGR_PLLMULL6 + RCC_CFGR_PPRE1_DIV1);
28
29
  // Flash latency 1 wait state
30
  MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_0);
31
32
  // Enable PLL
33
  SET_BIT(RCC->CR, RCC_CR_PLLON);
34
35
  // Wait until PLL is ready
36
  while(!READ_BIT(RCC->CR, RCC_CR_PLLRDY)) {}
37
38
  // Select PLL as clock source
39
  MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
40
41
  // Update variable
42
  SystemCoreClock=48000000;
43
}
44
45
46
int main(void)
47
{
48
  // Initialize system timer
49
  SysTick_Config(SystemCoreClock/1000);
50
51
  // Enable Port C
52
  SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPCEN);
53
54
  // PC13 = Output
55
  MODIFY_REG(GPIOC->CRH, GPIO_CRH_CNF13 + GPIO_CRH_MODE13, GPIO_CRH_MODE13_0);
56
57
  while(1)
58
  {
59
    // LED On
60
    WRITE_REG(GPIOC->BSRR,GPIO_BSRR_BS13);
61
62
    // Delay 1 second
63
    uint32_t start=systick_count;
64
    while (systick_count-start<1000);
65
66
    // LED Off
67
    WRITE_REG(GPIOC->BSRR,GPIO_BSRR_BR13);
68
69
    // Delay 1 second
70
    start=systick_count;
71
    while (systick_count-start<1000);
72
  }
73
}

Es scheint also, als ob CubeMX einen fehlerhaften Initialisierungscode 
erzeugt. Allerdings ist es mir nicht gelungen, den Knackpunkt zu finden. 
Hierbei bitte ich nun um Hilfe. Kann jemand den folgenden von CubeMX 
erzeugten Code prüfen?

Dieser Code von CubeMX geht (HSI 8Mhz -> 48Mhz):
1
void SystemClock_Config(void)
2
{
3
4
  RCC_OscInitTypeDef RCC_OscInitStruct;
5
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
6
7
    /**Initializes the CPU, AHB and APB busses clocks 
8
    */
9
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
10
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
11
  RCC_OscInitStruct.HSICalibrationValue = 16;
12
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
13
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
14
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;
15
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
16
  {
17
    Error_Handler();
18
  }
19
20
    /**Initializes the CPU, AHB and APB busses clocks 
21
    */
22
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
23
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
24
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
25
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
26
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
27
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
28
29
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
30
  {
31
    Error_Handler();
32
  }
33
34
    /**Configure the Systick interrupt time 
35
    */
36
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
37
38
    /**Configure the Systick 
39
    */
40
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
41
42
  /* SysTick_IRQn interrupt configuration */
43
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
44
}

Dieser Code von CubeMX geht nicht (HSE 8Mhz -> 48Mhz):
1
void SystemClock_Config(void)
2
{
3
4
  RCC_OscInitTypeDef RCC_OscInitStruct;
5
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
6
7
    /**Initializes the CPU, AHB and APB busses clocks 
8
    */
9
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;
10
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
11
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
12
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
13
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
14
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6;
15
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
16
  {
17
    Error_Handler();
18
  }
19
20
    /**Initializes the CPU, AHB and APB busses clocks 
21
    */
22
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
23
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
24
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
25
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
26
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
27
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
28
29
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
30
  {
31
    Error_Handler();
32
  }
33
34
    /**Configure the Systick interrupt time 
35
    */
36
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
37
38
    /**Configure the Systick 
39
    */
40
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
41
42
  /* SysTick_IRQn interrupt configuration */
43
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
44
}

von pegel (Gast)


Lesenswert?

Das ist noch die 4.20.0 oder?
Da gab es einen Bug mit:
1
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;

Das RCC_OSCILLATORTYPE_HSI ist der Störenfried.

Deshalb gab es dann ein Update auf 4.20.1.

Hat sich aber auch schon wieder erledigt, jetzt ist 4.21.0 aktuell.

von Stefan F. (Gast)


Lesenswert?

Wow, darauf wäre ich nie gekommen. Und ja du hast Recht, es ist die 
Version 4.20.0.

Da sehen wir wieder mal, wie super hilfreich diese Codegeneratoren sind 
:-(

Mein eigenen von hand zusammengeklöppelter Code geht, während ich durch 
den generierten Code nicht durchblicke. Scheiß Frameworks.

von STM Apprentice (Gast)


Lesenswert?

Stefan U. schrieb:
> Mein eigenen von hand zusammengeklöppelter Code geht, während ich durch
> den generierten Code nicht durchblicke. Scheiß Frameworks.

Ich schwöre auf die "Mitte" zwische Bare Metal und "High Level":

SPL hat mich noch nie im Stich gelassen, es geht schnell genug
beim Schreiben und es wird wohl weiterhin für mich funktionieren.
Ich brauche ja nicht jede Woche eine neue Version der SPL so
wie man es gefühlt bei CubeMX bekommt.

von Stefan F. (Gast)


Lesenswert?

Na toll, die Installation der Version 4.21 wird vom Windows Defender 
blockiert. Ich bekomme zunehmend der Eindruck, daß STM keine gute 
Software bereit stellt - alles nur eilig zusammengklöppelt.

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.