Forum: Mikrocontroller und Digitale Elektronik clock configuration


von Fragender (Gast)


Lesenswert?

Hallo miteinander

Ich bin gerade wieder dabei herauszufinden, warum mein clock mit 
externem 8MHz Quarz anders ist als mein interner Clock.
Ich teste dies mit einem Systick Interrupt, der 1ms aufgerufen wird.
transmitCounter wird dort inkrementiert
transmitCounterLimit = 200
Mit dem internen Clock komme ich in die if nach 200ms wie eingestellt, 
mit dem Quarz aber schon nach 100ms.
Mein Buzzer beept auch nicht wirklich 2sec. mit der Quarzeinstellung.
1
// sends every 200ms a message     
2
if(transmitCounter >= transmitCounterLimit)            
3
{
4
}
Ich habe die Konfiguration unten mit dem CubeMx zur Sicherheit auch 
eingestellt, sodass ich meine eigenen Fehler ausschliesse. Aber 
irgendwie, obwohl ich alles mit der PLL auf 48MHz einstelle, verhält 
sich das Programm nicht gleich.

Was mache ich nur nicht richtig?
Ich wäre euch für Ratschläge sehr dankbar.
1
#define INTERN_CLOCK
2
//define MHZ_8
3
4
#if INTERN_CLOCK
5
6
void systemClockConfig(uint32_t sysTickDevider)
7
{
8
  __HAL_RCC_SYSCFG_CLK_ENABLE();
9
  __HAL_RCC_PWR_CLK_ENABLE();
10
11
  RCC_OscInitTypeDef RCC_OscInitStruct;
12
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
13
  RCC_PeriphCLKInitTypeDef PeriphClkInit;
14
15
    /**Initializes the CPU, AHB and APB busses clocks 
16
    */
17
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
18
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
19
  RCC_OscInitStruct.HSICalibrationValue = 16;
20
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
21
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
22
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6;
23
  RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
24
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
25
  {
26
    _Error_Handler(__FILE__, __LINE__);
27
  }
28
29
    /**Initializes the CPU, AHB and APB busses clocks 
30
    */
31
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
32
                              |RCC_CLOCKTYPE_PCLK1;
33
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
34
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
35
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
36
37
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
38
  {
39
    _Error_Handler(__FILE__, __LINE__);
40
  }
41
42
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
43
  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;
44
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
45
  {
46
    _Error_Handler(__FILE__, __LINE__);
47
  }
48
49
    /**Configure the Systick interrupt time 
50
    */
51
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/sysTickDevider);
52
53
    /**Configure the Systick 
54
    */
55
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
56
57
  /* SysTick_IRQn interrupt configuration */
58
  HAL_NVIC_SetPriority(SysTick_IRQn, 2, 2); 
59
}
60
61
#elif MHZ_8
62
void systemClockConfig(uint32_t sysTickDevider)
63
{  
64
  __HAL_RCC_SYSCFG_CLK_ENABLE();
65
  __HAL_RCC_PWR_CLK_ENABLE();
66
  
67
  RCC_OscInitTypeDef RCC_OscInitStruct;
68
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
69
  RCC_PeriphCLKInitTypeDef PeriphClkInit;
70
71
    /**Initializes the CPU, AHB and APB busses clocks 
72
    */
73
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;
74
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
75
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
76
  RCC_OscInitStruct.HSICalibrationValue = 16;
77
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
78
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
79
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6;
80
  RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
81
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
82
  {
83
    _Error_Handler(__FILE__, __LINE__);
84
  }
85
86
    /**Initializes the CPU, AHB and APB busses clocks 
87
    */
88
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
89
                              |RCC_CLOCKTYPE_PCLK1;
90
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
91
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
92
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
93
94
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
95
  {
96
    _Error_Handler(__FILE__, __LINE__);
97
  }
98
99
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C1;
100
  PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_HSI;
101
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
102
  {
103
    _Error_Handler(__FILE__, __LINE__);
104
  }
105
106
    /**Configure the Systick interrupt time 
107
    */
108
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/sysTickDevider);
109
110
    /**Configure the Systick 
111
    */
112
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
113
114
  /* SysTick_IRQn interrupt configuration */
115
  HAL_NVIC_SetPriority(SysTick_IRQn, 2, 2);
116
}
117
118
#endif

von Fragender (Gast)


Lesenswert?

Ich arbeite mit dem STM32F072.
systickDevider = 1000

von pegel (Gast)


Lesenswert?

Hänge mal für beide Varianten die .ioc CubeMX Projekt Datei an,
da sollte der Unterschied sofort sichtbar sein.

von Fragender (Gast)


Lesenswert?

Hallo pegel

Ich habe gerade noch eine Vermutung was es sein könnte.
Das werde ich am Montag dann überprüfen und falls es das nicht ist, 
nochmals darauf zurück kommen und die files, wie von dir gewünscht, hier 
posten.

Vielen Dank nochmals bis dahin

von Fragender (Gast)


Angehängte Dateien:

Lesenswert?

Hallo

Ich habe versuchshalber mit meinem stm32L476 die clocks eingestellt. 
(Ebenfalls mit dem CUBEMX)
Um den Clock zu testen, habe ich den Timer6 benutzt und mit dem 80MHz 
clock einen Interrupt eingestellt, der alle 1us aufgerufen wird.

1/80MHz mit prescaler 0 ergibt 12.5ns
Mit einer Periode von 80 ergibt das also 1us

counterLimit = 1 000 000
Also sollte mir die LED eigentlich im Sekundentakt blinken. Tut sie aber 
nicht. Ich weiss nicht, warum ich auf einmal solche Probleme mit den 
Clockeinstellungen habe.
Was mache ich nur falsch?

Daten sind im Anhang

von Harry L. (mysth)


Lesenswert?

Zeig mal deine CubeMX-Datei! (.ioc)

Die ist viel interessanter.

Bei dem F072 ist der max. HCLK bei dem internen Osc.45 MHz und bei einem 
ext.Quarz 48MHz.

: Bearbeitet durch User
von Fragender (Gast)


Angehängte Dateien:

Lesenswert?

Harry L. schrieb:
> Zeig mal deine CubeMX-Datei! (.ioc)
>
> Die ist viel interessanter.
>
> Bei dem F072 ist der max. HCLK bei dem internen Osc.45 MHz und bei einem
> ext.Quarz 48MHz.

Hallo
Hier ist sie.

von Fragender (Gast)


Lesenswert?

Harry L. schrieb:
> Bei dem F072 ist der max. HCLK bei dem internen Osc.45 MHz und bei einem
> ext.Quarz 48MHz.

Ich habe jetzt im Datenblatt und im Reference Manual danach gesucht, 
dass der interne Clock max. 45MHz hat konnte ich nirgends finden.

von Christopher J. (christopher_j23)


Lesenswert?

Fragender schrieb:
> Harry L. schrieb:
>> Bei dem F072 ist der max. HCLK bei dem internen Osc.45 MHz und bei einem
>> ext.Quarz 48MHz.
>
> Ich habe jetzt im Datenblatt und im Reference Manual danach gesucht,
> dass der interne Clock max. 45MHz hat konnte ich nirgends finden.

Das wäre auch sehr verwunderlich, bewirbt doch ST die F0-Serie mit 
"crystal-less USB".

von Fragender (Gast)


Lesenswert?

Christopher J. schrieb:
> Fragender schrieb:
>> Harry L. schrieb:
>>> Bei dem F072 ist der max. HCLK bei dem internen Osc.45 MHz und bei einem
>>> ext.Quarz 48MHz.
>>
>> Ich habe jetzt im Datenblatt und im Reference Manual danach gesucht,
>> dass der interne Clock max. 45MHz hat konnte ich nirgends finden.
>
> Das wäre auch sehr verwunderlich, bewirbt doch ST die F0-Serie mit
> "crystal-less USB".

1. Auf die 3MHz kommt es ja auch nicht mehr so drauf an. Da frage ich 
mich wieso das so sein sollte und ST auf die Idee kommt die clock intern 
extern auf 3MHz unterschiedlich zu machen.
2. lese ich beim stm32f0 und stm32L4 einen maximalen Clock von f_HCLK = 
48 und 80 MHz für L4.

Im Moment frage ich mich auch, warum der Clock auch nicht stimmt, wenn 
ich auf dem Nucleo stm32L4 Board den externen Quarz verwende mit den 
gleichen Einstellungen vom Timer. Dann warte ich im Gegensatz zum 
internen eine Ewigkeit bis der counter mal auf 1000000 ist. Beim 
internen sind es gefühlte 5 sec statt 1 sec. Beim externen 40sec.
Ich verstehe das einfach nicht.
Ich messe das mal mit dem Oszi, was ich da mit dem Timer wirklich 
erreiche.

von Fragender (Gast)


Angehängte Dateien:

Lesenswert?

Ich bin also halb so schnell.
Im Interrupt habe ich nur noch den Befehl GPIOA->ODR ^= GPIO_PIN_5;

Woran liegt es?

von Christopher J. (christopher_j23)


Lesenswert?

Fragender schrieb:
> Ich bin also halb so schnell.
> Im Interrupt habe ich nur noch den Befehl GPIOA->ODR ^= GPIO_PIN_5;
>
> Woran liegt es?

Was soll das Bild jetzt zeigen? Das der Interrupt nur alle 2us feuert?

Woran hängt denn dein Timer? AHB, APB1, APB2? Wie sind da die Prescaler? 
Nicht alle Timer laufen mit HCLK!

von Fragender (Gast)


Angehängte Dateien:

Lesenswert?

Christopher J. schrieb:
> Fragender schrieb:
>> Ich bin also halb so schnell.
>> Im Interrupt habe ich nur noch den Befehl GPIOA->ODR ^= GPIO_PIN_5;
>>
>> Woran liegt es?
>
> Was soll das Bild jetzt zeigen? Das der Interrupt nur alle 2us feuert?

Ja

> Woran hängt denn dein Timer? AHB, APB1, APB2? Wie sind da die Prescaler?
> Nicht alle Timer laufen mit HCLK!

Timer 6 hängt an HCLK (APB1), letztendlich am PCLK1
Prescalers sind auf 1, auch AHB (siehe Bilder)

Den Timer Prescaler habe ich auf 0, laut der Rechnung oben.

von Fragender (Gast)


Angehängte Dateien:

Lesenswert?

Ich komme mir nun langsam schon echt doof vor.

Jetzt verstehe ich gar nichts mehr.
Die Bilder vom Oszi deuten auf halbe Geschw., nämlich 40 statt 80 MHz.
Aber das Auslesen des PCLK1 sagt mir 4 MHz

von Fragender (Gast)


Angehängte Dateien:

Lesenswert?

So nun habe ich in der CUBE MX Datei lediglich nur vom HSI auf den 
externen Quarz 8MHz eingestellt mit den genau gleichen Einstellungen.

Nun lasse ich das Programm laufen und der PCLK1 wird mir ebenfalls mit 4 
000 000 MHz angezeigt in der Software aber das Oszibild zeigt mir nun 
statt 2us, 20us an. Also gerade nochmals 10x langsamer.
Das soll nun noch jemand verstehen...

Mit meinem Nucleo habe ich schon öfters gearbeitet.
Die Probleme mit dem Clock hatte ich bisher noch nicht. Ich glaube 
langsam, dass die da mit der CubeMx Software etwas verbockt haben.

Was kann ich denn nun machen, ohne das es ein Gebastel ist?

von Fragender (Gast)


Lesenswert?

Fragender schrieb:

> Nun lasse ich das Programm laufen und der PCLK1 wird mir ebenfalls mit 4
> 000 000 MHz angezeigt in der Software aber das Oszibild zeigt mir nun
> statt 2us, 20us an.


Nein falsch: Ich lese 40us ab. Falsch geschaut.

1/4MHz * Periode 80 = 20us, raus kommen aber 40us
1/4MHz * Periode 4 sollte denmach genau 1us ergeben, raus kommt aber ca. 
32.8us

Oh mann...
Ich dreh langsam durch.

von Fragender (Gast)


Angehängte Dateien:

Lesenswert?

So meine Signale habe uch in der Zwischenzeit zusammen.

Jetzt benötige ich nur noch den heissen Tipp von euch.
Die Clocks von Hand für jede einzelne Peripherie einzustellen würde ich 
mir gerne ersparen.

von pegel (Gast)


Lesenswert?

Warum nutzt du nicht einfach den MCO?

Dann stellt sich heraus ob es ein CubeMX Problem ist.
Inzwischen gibt es die neue Version 5.1.0, sollte es daran liegen.

von pegel (Gast)


Angehängte Dateien:

Lesenswert?

Wenn ich nicht irre, werden Prescaler wie auch Periode Werte -1 
angegeben.
Für PWM ein Beispiel von 72MHz auf 1KHz PWM.

Lässt sich auch so in CubeMX eintragen.

von Christopher J. (christopher_j23)


Lesenswert?

Fragender schrieb:
> Ich komme mir nun langsam schon echt doof vor.
>
> Jetzt verstehe ich gar nichts mehr.
> Die Bilder vom Oszi deuten auf halbe Geschw., nämlich 40 statt 80 MHz.
> Aber das Auslesen des PCLK1 sagt mir 4 MHz

Der Breakpoint in deinem Screenshot ist ja auch vor der 
SystemClock_Config(), also bevor die PLL konfiguriert wird. So lange 
rennt die Kiste mit dem 4MHz MSI.

Fragender schrieb:
> So meine Signale habe uch in der Zwischenzeit zusammen.
>
> Jetzt benötige ich nur noch den heissen Tipp von euch.
> Die Clocks von Hand für jede einzelne Peripherie einzustellen würde ich
> mir gerne ersparen.

Helau! Hast du vielleicht den Timer auf Up-Down konfiguriert? Generell 
vermisse ich bei allem was du hier veröffentlicht hast die eigentliche 
Timer-Konfiguration.

Edit: Irrsinn gelöscht

: Bearbeitet durch User
von Fragender (Gast)


Angehängte Dateien:

Lesenswert?

Christopher J. schrieb:
> Fragender schrieb:
>> Ich komme mir nun langsam schon echt doof vor.
>>
>> Jetzt verstehe ich gar nichts mehr.
>> Die Bilder vom Oszi deuten auf halbe Geschw., nämlich 40 statt 80 MHz.
>> Aber das Auslesen des PCLK1 sagt mir 4 MHz
>
> Der Breakpoint in deinem Screenshot ist ja auch vor der
> SystemClock_Config(), also bevor die PLL konfiguriert wird. So lange
> rennt die Kiste mit dem 4MHz MSI.

auch nach dem systemclockinit 4MHz

>
> Fragender schrieb:

> Helau! Hast du vielleicht den Timer auf Up-Down konfiguriert? Generell
> vermisse ich bei allem was du hier veröffentlicht hast die eigentliche
> Timer-Konfiguration.
>
> Edit: Irrsinn gelöscht

Ich habe alles als file oben angehängt, aber hier nochmals die main.c
1
C-Code
2
------------------------------------------------------------------*/
3
#include "main.h"
4
5
6
TIM_HandleTypeDef htim6;
7
8
9
void SystemClock_Config(void);
10
static void MX_GPIO_Init(void);
11
static void MX_TIM6_Init(void);
12
13
14
15
int main(void)
16
{
17
  /* USER CODE BEGIN 1 */
18
19
  /* USER CODE END 1 */
20
21
  /* MCU Configuration--------------------------------------------------------*/
22
23
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
24
  HAL_Init();
25
26
  /* USER CODE BEGIN Init */
27
28
  /* USER CODE END Init */
29
30
  /* Configure the system clock */
31
  SystemClock_Config();
32
  freqPCLK1 = HAL_RCC_GetPCLK1Freq();
33
  /* USER CODE BEGIN SysInit */
34
35
  /* USER CODE END SysInit */
36
37
  /* Initialize all configured peripherals */
38
  MX_GPIO_Init();
39
  MX_TIM6_Init();
40
  /* USER CODE BEGIN 2 */
41
  HAL_TIM_Base_Start_IT(&htim6);
42
  /* USER CODE END 2 */
43
44
  /* Infinite loop */
45
  /* USER CODE BEGIN WHILE */
46
  while (1)
47
  {
48
    /* USER CODE END WHILE */
49
50
    /* USER CODE BEGIN 3 */
51
  }
52
  /* USER CODE END 3 */
53
}
54
55
/**
56
  * @brief System Clock Configuration
57
  * @retval None
58
  */
59
void SystemClock_Config(void)
60
{
61
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
62
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
63
64
  /**Initializes the CPU, AHB and APB busses clocks 
65
  */
66
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
67
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
68
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
69
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
70
  RCC_OscInitStruct.PLL.PLLM = 1;
71
  RCC_OscInitStruct.PLL.PLLN = 20;
72
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
73
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
74
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
75
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
76
  {
77
    Error_Handler();
78
  }
79
  /**Initializes the CPU, AHB and APB busses clocks 
80
  */
81
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
82
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
83
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
84
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
85
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
86
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
87
88
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
89
  {
90
    Error_Handler();
91
  }
92
  /**Configure the main internal regulator output voltage 
93
  */
94
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
95
  {
96
    Error_Handler();
97
  }
98
}
99
100
/**
101
  * @brief TIM6 Initialization Function
102
  * @param None
103
  * @retval None
104
  */
105
static void MX_TIM6_Init(void)
106
{
107
108
  /* USER CODE BEGIN TIM6_Init 0 */
109
110
  /* USER CODE END TIM6_Init 0 */
111
112
  TIM_MasterConfigTypeDef sMasterConfig = {0};
113
114
  /* USER CODE BEGIN TIM6_Init 1 */
115
116
  /* USER CODE END TIM6_Init 1 */
117
  htim6.Instance = TIM6;
118
  htim6.Init.Prescaler = 1;
119
  htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
120
  htim6.Init.Period = 4;
121
  htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
122
  if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
123
  {
124
    Error_Handler();
125
  }
126
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
127
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
128
  if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
129
  {
130
    Error_Handler();
131
  }
132
  /* USER CODE BEGIN TIM6_Init 2 */
133
134
  /* USER CODE END TIM6_Init 2 */
135
136
}
137
138
/**
139
  * @brief GPIO Initialization Function
140
  * @param None
141
  * @retval None
142
  */
143
static void MX_GPIO_Init(void)
144
{
145
  GPIO_InitTypeDef GPIO_InitStruct = {0};
146
147
  /* GPIO Ports Clock Enable */
148
  __HAL_RCC_GPIOH_CLK_ENABLE();
149
  __HAL_RCC_GPIOA_CLK_ENABLE();
150
151
  /*Configure GPIO pin Output Level */
152
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8 
153
                          |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11, GPIO_PIN_RESET);
154
155
  /*Configure GPIO pins : PA5 PA6 PA7 PA8 
156
                           PA9 PA10 PA11 */
157
  GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8 
158
                          |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11;
159
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
160
  GPIO_InitStruct.Pull = GPIO_NOPULL;
161
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
162
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
163
164
}
165
166
/* USER CODE BEGIN 4 */
167
168
/* USER CODE END 4 */
169
170
/**
171
  * @brief  This function is executed in case of error occurrence.
172
  * @retval None
173
  */
174
void Error_Handler(void)
175
{
176
  /* USER CODE BEGIN Error_Handler_Debug */
177
  /* User can add his own implementation to report the HAL error return state */
178
179
  /* USER CODE END Error_Handler_Debug */
180
}
181
182
#ifdef  USE_FULL_ASSERT
183
/**
184
  * @brief  Reports the name of the source file and the source line number
185
  *         where the assert_param error has occurred.
186
  * @param  file: pointer to the source file name
187
  * @param  line: assert_param error line source number
188
  * @retval None
189
  */
190
void assert_failed(char *file, uint32_t line)
191
{ 
192
  /* USER CODE BEGIN 6 */
193
  /* User can add his own implementation to report the file name and line number,
194
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
195
  /* USER CODE END 6 */
196
}
197
#endif /* USE_FULL_ASSERT */
198
199
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
200
201
Interrupt
202
[c]
203
void TIM6_DAC_IRQHandler(void)
204
{
205
  /* USER CODE BEGIN TIM6_DAC_IRQn 0 */
206
207
     GPIOA->ODR ^= GPIO_PIN_5;
208
209
   
210
211
   
212
  
213
  /* USER CODE END TIM6_DAC_IRQn 0 */
214
  HAL_TIM_IRQHandler(&htim6);
215
  /* USER CODE BEGIN TIM6_DAC_IRQn 1 */
216
217
  /* USER CODE END TIM6_DAC_IRQn 1 */
218
}

von Fragender (Gast)


Lesenswert?

pegel schrieb:
> Warum nutzt du nicht einfach den MCO?

MCO?

von pegel (Gast)


Lesenswert?

Fragender schrieb:
> MCO?

Schau mal in der Clock Configuration in den unteren linken Teil den du 
in deinen Bildern immer abgeschnitten hast.

Wird unter RCC aktiviert. PA8 gibt den gewählten Takt aus.

von Christopher J. (christopher_j23)


Lesenswert?

Fragender schrieb:
> htim6.Init.Prescaler = 1;

Da liegt der Hund begraben. Ein Prescaler-Wert von 1 bedeutet effektiv 
einen Teiler von 2!
Was du brauchst ist ein PSC-Wert von 0, der teilt nämlich nicht durch 
0 (das wäre ja auch übel), sondern durch 1 ;)

Es hilft übrigens ungemein sich (gerade bei den Timern) mal die Register 
im Refman anzuschauen. Hier kommen jeden Tag Leute mit ewig viel 
generiertem Code und sehen den Wald vor lauter Bäumen nicht.

PS: Das gleiche was für PSC gilt, gilt auch für ARR (in HAL-Sprech 
"period"). Ein Wert von 4 bedeutet 0..4, also 5 Takte für eine Periode.

: Bearbeitet durch User
von Prozessor Dokter Schmunz (Gast)


Lesenswert?

Fragender schrieb:
>   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
>                               |RCC_CLOCKTYPE_PCLK1;
>   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
>   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
>   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

>   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) !=
> HAL_OK)
>
>     /**Initializes the CPU, AHB and APB busses clocks
>     */
>   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
>                               |RCC_CLOCKTYPE_PCLK1;

Längere Namen sind dir nicht eingefallen?

In meiner Funktion als Prozessor Dokter Schmunz würde ich sagen: DAS IST 
DAS PROBLEM! Dein Programm (oder ist es ein Sketch? ;) ) sieht aus, als 
wäre ein Huhn drüber gelaufen. Das kann keiner mehr lesen und so 
entstehen Fehler.

von pegel (Gast)


Lesenswert?

Prozessor Dokter Schmunz schrieb:
> Längere Namen sind dir nicht eingefallen?

Diese Namen sind den HAL Machern eingefallen und werden von CubeMX 
benutzt.

Diese sollte man nicht von Hand ändern, ist auch nicht erforderlich.

Das ist ein Sketch:

https://www.youtube.com/watch?v=lI1C_q8QOVU

von Stefan F. (Gast)


Lesenswert?

Prozessor Dokter Schmunz schrieb:
> Längere Namen sind dir nicht eingefallen?

Ich in meiner Rolle als Doktor SchlagInDenNacken würde Dir intravenös 
eintrichtern, dass diese Namen vom Framework vorgegeben sind.

von Fragender (Gast)


Lesenswert?

Christopher J. schrieb:
> Fragender schrieb:
> htim6.Init.Prescaler = 1;
>
> Da liegt der Hund begraben. Ein Prescaler-Wert von 1 bedeutet effektiv
> einen Teiler von 2! Was du brauchst ist ein PSC-Wert von 0, der teilt
> nämlich nicht durch 0 (das wäre ja auch übel), sondern durch 1 ;)
>
> Es hilft übrigens ungemein sich (gerade bei den Timern) mal die Register
> im Refman anzuschauen. Hier kommen jeden Tag Leute mit ewig viel
> generiertem Code und sehen den Wald vor lauter Bäumen nicht.
>
> PS: Das gleiche was für PSC gilt, gilt auch für ARR (in HAL-Sprech
> "period"). Ein Wert von 4 bedeutet 0..4, also 5 Takte für eine Periode.

ob 4 oder 5
prescaler 0 oder 1

alles tut nicht
Ich liege immer mindestens 2 fach daneben

von pegel (Gast)


Lesenswert?

Ich denke schon das es einen Unterschied macht, ob man 80MHz durch 2 
teilt oder nicht.
Hast du auch neu kompiliert und neu übertragen danach?

MCO probiert um die internen Takte zu prüfen?

von Christopher J. (christopher_j23)


Lesenswert?

Fragender schrieb:
> Ich liege immer mindestens 2 fach daneben

Ist dabei auch schon einkalkuliert, dass du nur toggelst?

von Fragender (Gast)


Lesenswert?

Christopher J. schrieb:
> Fragender schrieb:
> Ich liege immer mindestens 2 fach daneben
>
> Ist dabei auch schon einkalkuliert, dass du nur toggelst?

Ja der interrupt kommt und ich schalte ein
beim nächsten interr wieder aus

da muss ich jetzt 1us messen zwischen einer steigenden und einer 
fallenden Flanke. messe aber 2us, beim HSI
mit dem HSE dann aber 40 statt 20us
mit gleichen Einstellungen ?

von Fragender (Gast)


Angehängte Dateien:

Lesenswert?

Naja, auch mit dem neuen Update nicht besser..
Für heute habe ich genug.

von Fragender (Gast)


Lesenswert?

Guten Morgen

Die Diskussion würde sich glaube ich erledigen, wenn jemand einfach mal 
mit irgend einem STM den TIM6 mal auf 1us einstellt.

Ich weiss nicht, warum 1us nicht funktioniert beim TIM6.
1sec. funktioniert.

1sec. =
prescaler = 48000-1
CounteMode = UP
Periode = 1000-1

1us =
prescaler = 12-1
CountermOde = up
periode = 4-1

Dann hätten wir das Problem mit dem Prescaler 0 oder 1 einmal beseitigt.

Ich bekomme das nicht hin mit 1us. Ich messe etwas über 3.5us
Schafft es jemand von euch?
Die STMs sind ja meistens gleich.
Ich bekomme es mit dem STM32L4 und STM32F0 nicht hin.

Braucht der Interrupt so lange in die Funktion zu gelangen oder was ist 
das Problem?

von pegel (Gast)


Lesenswert?

Mangels TIM6 habe ich es auf dem Bluepill mit TIM4 getestet.
Und ja, es dauert seine Zeit bis alle Befehle ausgeführt sind.
Darum geht es einfach nicht schneller.

Ich habe den OC1 Ausgang und die LED (getoggelt durch die Callback 
Funktion des Timers) auf dem Oszi beobachtet. Da sieht man sehr schön 
wie sich die Signale bei zunehmender Frequenz gegenseitig beeinflussen.

Dann funkt auch noch der Systick dazwischen und die Waitstates des Flash 
darf man auch nicht vergessen.

Die eigentliche Frage war ja, ob es einen Unterschied macht, ob HSE oder 
HSI verwendet wird. Das probiere ich noch mit 48MHz.

Du kannst ja nachsehen, ob z.B. die Waitstates oder eine andere 
Einstellung unterschiedlich je nach Taktquelle sind.

von pegel (Gast)


Lesenswert?

Wie zu erwarten war, ist ausser einer Abweichung der Frequenz und etwas 
Instabilität kein Unterschied zwischen HSE und HSI zu erkennen.

von Fragender (Gast)


Lesenswert?

Hallo Freunde

Bei mir stimmen die Clocks irgendwie immer noch nicht und ich begreife 
nicht warum.
Ich arbeite derzeit mit dem STM32L476RG Nucleo Board.
Mit dem Timer 6 möchte ich eigentlich einen 1us Interrupt generieren.
Das funktioniert ja soweit festgestellt ja nicht.

Das ist ein Beitrag aus dem Arduino Forum:

 Apr 11, 2018, 05:40 pm Last Edit: Apr 11, 2018, 05:41 pm by Doc_Arduino
Hallo,

auch wenn es vielleicht nicht mehr benötigt wird wegen dem Problem mit 
dem Multiplexing, möchte ich dennoch zeigen wie man das mit einem Timer 
erschlagen kann. Es ist beliebig erweiterbar. Im Grunde basiert es auf 
einem Servo Sketch. Der benötigt aber keine künstliche Totzeit zwischen 
den Pulsen. Die maximale Zeit für irgendwelche Pulsformung oder Totzeit 
ergibt sich aus dem maximalen Timercount von 65535 und dem aktuellen 
Prescaler 8. Ein Timercount entspricht 1 / 16MHz * 8 = 0,5µs. Das wäre 
gleichzeitig die Auflösung. Daraus ergibt sich 0,5µs * 65535 = 32,767ms 
was maximal einstellbar wäre mit Prescaler 8.

Meine Frage ist an diesem Punkt: Was ist, wenn ich einen Interrupt alle 
1us haben möchte? Warum bekommt das ein AVR hin und ein STM32 nicht?
Wie stelle ich einen 1us Interrupt mit dem STM32 ein?
Ich lese beim Timer einen Wert von 80MHz für PLCK1 aus. Das ist der Clk 
für die Timer. Daher dividiere ich bei der TIM6 Configuration durch 80 
(80-1) und stelle die Periode auf 5 (5-1). Dann stelle ich den Limit im 
Interrupt auf 250 und sollte nun eine Pulslänge von 5x250us = 1250us 
bekommen, wenn ich einen Eingang ein und beim nächsten Mal wieder 
ausschalte.
Ich bekomme aber immer das Doppelte, also 2500us.
Warum? Ich wäre nun wirklich dankbar, wenn mir jemand aus diesem 
Schlamassel helfen würde.

Das ist meine Timer und SystemClock Initialisierung:
1
void SystemClock_Config(void)
2
{
3
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
4
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
5
6
  /**Initializes the CPU, AHB and APB busses clocks 
7
  */
8
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
9
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
10
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
11
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
12
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
13
  RCC_OscInitStruct.PLL.PLLM = 1;
14
  RCC_OscInitStruct.PLL.PLLN = 10;
15
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
16
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
17
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
18
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
19
  {
20
    Error_Handler();
21
  }
22
  /**Initializes the CPU, AHB and APB busses clocks 
23
  */
24
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
25
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
26
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
27
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
28
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
29
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
30
31
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
32
  {
33
    Error_Handler();
34
  }
35
  /**Configure the main internal regulator output voltage 
36
  */
37
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
38
  {
39
    Error_Handler();
40
  }
41
  
42
43
}
44
45
/**
46
  * @brief TIM6 Initialization Function
47
  * @param None
48
  * @retval None
49
  */
50
static void MX_TIM6_Init(void)
51
{
52
53
  /* USER CODE BEGIN TIM6_Init 0 */
54
55
  /* USER CODE END TIM6_Init 0 */
56
57
  TIM_MasterConfigTypeDef sMasterConfig = {0};
58
59
  /* USER CODE BEGIN TIM6_Init 1 */
60
61
  /* USER CODE END TIM6_Init 1 */
62
  htim6.Instance = TIM6;
63
  htim6.Init.Prescaler = 79;
64
  htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
65
  htim6.Init.Period = 4;
66
  htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
67
  if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
68
  {
69
    Error_Handler();
70
  }
71
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
72
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
73
  if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
74
  {
75
    Error_Handler();
76
  }
77
  /* USER CODE BEGIN TIM6_Init 2 */
78
79
  /* USER CODE END TIM6_Init 2 */
80
81
}
82
83
void TIM6_DAC_IRQHandler(void)
84
{
85
  /* USER CODE BEGIN TIM6_DAC_IRQn 0 */
86
   
87
   if(waitCounter >= Limit)
88
   {    
89
           waitCounter = 0;
90
           toggleLED();
91
   }

von Fragender (Gast)


Lesenswert?

wenn ich einen Eingang ein und beim nächsten Mal wieder
ausschalte.

Hier meine ich natürlich einen Pin toggle.

von Stefan F. (Gast)


Lesenswert?

Gebe mal deine ganzen Prescaler und Multiplikatoren, sowie die Frequenz 
des Quarzes in CubeMX ein. Dann schaust du in dem hübschen Diagramm 
nach, welche Taktfrequenz am Timer ankommt.

Zeige mal einen Screenshot von dieser Ansicht. Das hilft sicher bei der 
Klärung.

von Fragender (Gast)


Lesenswert?

Stefanus F. schrieb:
> Gebe mal deine ganzen Prescaler und Multiplikatoren, sowie die
> Frequenz
> des Quarzes in CubeMX ein. Dann schaust du in dem hübschen Diagramm
> nach, welche Taktfrequenz am Timer ankommt.
>
> Zeige mal einen Screenshot von dieser Ansicht. Das hilft sicher bei der
> Klärung.

Morgen Stefan

Das habe ich schon mindestens 100000 mal gemacht, aber meinetwegen machs 
ich nochmals, damit es für jeden nachvollziehbar ist.
bis dann

von pegel (Gast)


Lesenswert?

Ich würde meinen Vorschlag von oben probieren.
Beginne mit grossen Teiler Einstellungen die eine niedrige Frequenz 
erzeugen, rechne diese nach und vergleiche. Am Besten mit Oszi.

Dann verkleinere die Teiler Einstellungen, miss die Frequenz und du 
wirst sehen das du an einen Punkt kommst, an dem sich die Frequenz durch 
die Zeit, die die Abarbeitung der Befehle benötigt nicht mehr verändert.

Das lässt sich prima durch "unsaubere" Signale am Oszi beobachten.

von Fragender (Gast)


Lesenswert?

pegel schrieb:
> Ich würde meinen Vorschlag von oben probieren.
> Beginne mit grossen Teiler Einstellungen die eine niedrige Frequenz
> erzeugen, rechne diese nach und vergleiche. Am Besten mit Oszi.
>
> Dann verkleinere die Teiler Einstellungen, miss die Frequenz und du
> wirst sehen das du an einen Punkt kommst, an dem sich die Frequenz durch
> die Zeit, die die Abarbeitung der Befehle benötigt nicht mehr verändert.
>
> Das lässt sich prima durch "unsaubere" Signale am Oszi beobachten.

Hallo Pegel

Das habe ich versucht.
Ich komme, wenn Timer 3 und der Interrupt selbst so konfiguriert ist auf 
4.15us. Das ist das Minimum, was ich heraus bekomme.
Ich habe den HAL_TIM_IRQHandler(&htim3); im Interrupt weggelassen

Jetzt komme ich auch auf das was ich einstelle.

Zumindest ein Problem gelöst.
Nun habe ich das Problem mit dem Quarz noch.

von Fragender (Gast)


Lesenswert?

Fragender schrieb:

>
> Das habe ich versucht.
> Ich komme, wenn Timer 3 und der Interrupt selbst so konfiguriert ist auf
> 4.15us. Das ist das Minimum, was ich heraus bekomme.
> Ich habe den HAL_TIM_IRQHandler(&htim3); im Interrupt weggelassen
>
> Jetzt komme ich auch auf das was ich einstelle.
>
> Zumindest ein Problem gelöst.
> Nun habe ich das Problem mit dem Quarz noch.

Habe die Konfigurationen vergessen:
1
void TIM3_IRQHandler(void)
2
{
3
  /* USER CODE BEGIN TIM3_IRQn 0 */
4
  if(__HAL_TIM_GET_FLAG(&htim3, TIM_FLAG_UPDATE) != 0)
5
  {
6
    __HAL_TIM_CLEAR_FLAG(&htim3, TIM_FLAG_UPDATE);
7
8
    GPIOB->ODR ^= GPIO_PIN_7;
9
  }
10
  /* USER CODE END TIM3_IRQn 0 */
11
 // HAL_TIM_IRQHandler(&htim3);
12
  /* USER CODE BEGIN TIM3_IRQn 1 */
13
14
  /* USER CODE END TIM3_IRQn 1 */
15
}
16
17
static void MX_TIM3_Init(void)
18
{
19
20
  TIM_ClockConfigTypeDef sClockSourceConfig;
21
  TIM_MasterConfigTypeDef sMasterConfig;
22
23
  htim3.Instance = TIM3;
24
  htim3.Init.Prescaler = 0;
25
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
26
  htim3.Init.Period = 24000;
27
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
28
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
29
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
30
  {
31
    _Error_Handler(__FILE__, __LINE__);
32
  }
33
34
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
35
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
36
  {
37
    _Error_Handler(__FILE__, __LINE__);
38
  }
39
40
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
41
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
42
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
43
  {
44
    _Error_Handler(__FILE__, __LINE__);
45
  }
46
47
}

von Fragender (Gast)


Lesenswert?

Jetzt muss ich nochmals nachfragen.

Ich stelle ein neues CUBEMX file her mit externem Quarz 8MHz und bekomme 
dann einen Takt von 48 MHz.

In meinem Programm aber nicht. Die Timerkonfiguration ist aber exakt 
gleich.
Woran liegt das?

von pegel (Gast)


Lesenswert?

Fragender schrieb:
> htim3.Init.Period = 24000;

Bei 48MHz müsste die Led dann 2kHz toggeln, also mit 1kHz blinken.
Tut sie das?

von Stefan F. (Gast)


Lesenswert?

Fragender schrieb:
> Ich stelle ein neues CUBEMX file her mit externem Quarz 8MHz und bekomme
> dann einen Takt von 48 MHz.
>
> In meinem Programm aber nicht. Die Timerkonfiguration ist aber exakt
> gleich.
>
> Woran liegt das?

Wenn du das *.ioc File oder wenigstens den versprochenen Screenshot 
zeugen würdest, könnten wir uns die vernünftig Sache anschauen.

von Fragender (Gast)


Lesenswert?

Stefanus F. schrieb:
> Fragender schrieb:
> Ich stelle ein neues CUBEMX file her mit externem Quarz 8MHz und bekomme
> dann einen Takt von 48 MHz.
> In meinem Programm aber nicht. Die Timerkonfiguration ist aber exakt
> gleich.
>
> Woran liegt das?
>
> Wenn du das *.ioc File oder wenigstens den versprochenen Screenshot
> zeugen würdest, könnten wir uns die vernünftig Sache anschauen.

Hallo Stefan

Ich stelle gerade fest, dass mein Ioc file nicht mehr aktuell ist, da 
ich dann später alles weitere von Hand geschrieben habe. Wenn ich doch 
versuche alles was nachtraeglich hinzugekommen nachzustellen und den 
Code erneut generiere. Kommen bei mir irgendwelche multiplied defined 
Fehler in Bibliotheken, die ich gar nicht erstellt habe.

Was nun? Ich nehme nicht an, dass du das ioc vom neuen cubemx file 
willst, weil das ja nichts aussagt über das Problem.

pegel schrieb:
> Fragender schrieb:
> htim3.Init.Period = 24000;
>
> Bei 48MHz müsste die Led dann 2kHz toggeln, also mit 1kHz blinken.
> Tut sie das?

Das werde ich morgen testen.
Aber was mir ja gerade einfällt so nebenbei bevor ich das teste morgen.
Ich habe ja 500us eingestellt und das mit Prescaler 0 und Periode 24000 
augerechnet ausgehend von 48MHz.
Also stimmt das ja, wenn ich das mit dem Oszi messe.
Dann frage ich mich aber warum die HAL_GetHCLKFreq etc bei mir 24MHz 
liefert und beim neuen file 48MHz. Den Beep Ton führt das Programm mit 
dem ext Quarz auch schneller aus mit angeblichen 24 MHz als der interne 
CLK mit 48MHz.
Der Beep Ton mit gleich eingestellter PWM 2.4kHz klingt aber gleich und 
bleibt unverändert.

Ich kapiers nicht...

von Stefan F. (Gast)


Lesenswert?

Fragender schrieb:
> Ich nehme nicht an, dass du das ioc vom neuen cubemx file
> willst, weil das ja nichts aussagt über das Problem.

Probiere das neue File aus. Ich wollte das funktionierende CubeMX 
Projekt mit dem nicht funktionierenden (ohne CubeMX) vergleichen.

von Fragender (Gast)


Lesenswert?

Fragender schrieb im Beitrag #57 *.ioc File oder wenigstens den 
versprochenen Screenshot
> zeugen würdest, könnten wir uns die vernünftig Sache anschauen.
>
> Hallo Stefan
>
> Ich stelle gerade fest, dass mein Ioc file nicht mehr aktuell ist, da
> ich dann später alles weitere von Hand geschrieben habe. Wenn ich doch
> versuche alles was nachtraeglich hinzugekommen nachzustellen und den
> Code erneut generiere. Kommen bei mir irgendwelche multiplied defined
> Fehler in Bibliotheken, die ich gar nicht erstellt habe.
>
> Was nun? Ich nehme nicht an, dass du das ioc vom neuen cubemx file
?
>
> Das werde ich morgen testen.
> Aber was mir ja gerade einfällt so nebenbei bevor ich das teste morgen.
> Ich habe ja 500us eingestellt und das mit Prescaler 0 und Periode 24000
> augerechnet ausgehend von 48MHz.
> Also stimmt das ja, wenn ich das mit dem Oszi messe.
> Dann frage ich mich aber warum die HAL_GetHCLKFreq etc bei mir 24MHz
> liefert und beim neuen file 48MHz. Den Beep Ton führt das Programm mit
> dem ext Quarz auch schneller aus mit angeblichen 24 MHz als der interne
> CLK mit 48MHz.
> Der Beep Ton mit gleich eingestellter PWM 2.4kHz klingt aber gleich und
> bleibt unverändert.
>
> Ich kapiers nicht...

Ich muss irgendwie herausfinden was der SysClk nun wirlich für einen 
Wert hat. In den HAL_GetHCLKFreg Funktionen werden ja nur irgendwie bits 
geschoben.
Gibt es nicht irgend ein Register wo das ausgelesen werden kann oder 
eine Möglichkeit das zu messen?

von Fragender (Gast)


Lesenswert?

Stefanus F. schrieb:
> Fragender schrieb:
> Ich nehme nicht an, dass du das ioc vom neuen cubemx file
> willst, weil das ja nichts aussagt über das Problem.
>
> Probiere das neue File aus. Ich wollte das funktionierende CubeMX
> Projekt mit dem nicht funktionierenden (ohne CubeMX) vergleichen.

Ok ich lasse es dir morgen zukommen.

von Stefan F. (Gast)


Lesenswert?

Fragender schrieb:
> Gibt es nicht irgend ein Register wo das ausgelesen werden kann

Nein. Die CMSIS definiert eine globale 64bit Integer Variable namens 
SystemCoreClock, welche zu jeder Zeit die richtige Frequenz in Hz 
angeben sollte. Aber letztendlich wird sie von der Software 
aktualisiert, kann also auch falsch sein.

> oder eine Möglichkeit das zu messen?

Sicher

a) Lass Dir den Takt auf den MCO Pin ausgeben und messe mit einem 
externen Gerät.

b) Rufe folgende Funktion als delay(1000) auf, das sollte bei 48MHz 
genau 1 Sekunde dauern.
1
void delay(uint32_t msec)
2
{
3
    for (uint32_t j=0; j<9000UL*msec; j++)
4
    {
5
        __NOP ();
6
    }
7
}

Der Optimizer muss dabei aktiviert sein (-O2, -O3, -Os oder -Og).

von Fragender (Gast)


Lesenswert?

Ich habe es raus.
Ich hatte bei meinem Programm zuerst 4MHz Quarz drin und hatte den Code 
auch so generiert und danach nicht mehr geändert.
Der Prozessor taktet mit 48MHz, die Software zeigt es aber falsch an, 
weil

in der stm32f0xx_hal_conf.h Datei 4MHz steht statt 8MHz
1
#if !defined  (HSE_VALUE) 
2
  #define HSE_VALUE    ((uint32_t)4000000) /*!< Value of the External oscillator in Hz */
3
#endif /* HSE_VALUE */

Ich habe es jetzt auf 8000000 geändert und wird nun richtig angezeigt.

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.