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 | }
|