Forum: Mikrocontroller und Digitale Elektronik STM32 PWM Spannung nur 1,06 V


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von katilinchen (Gast)


Lesenswert?

Hallo,

Ich bin langsam schon etwas am verzweifeln. Ich schreibe Momentan an 
meiner Bachelorarbeit und ich möchte gerne mit einem STM32F103RB eine 
H-Brücke (DRV8873) per PWM (mit disable und nSleep Pin) Ansteuern.

Ich verwende der Bequemlichkeit halber den CUBEMX um mir die HAL 
erstellen zu lassen. Meinen Prescaler hab ich auf 87 (Testweise) 
eingestellt und meinen counter auf 4096. um eben z.B. 200 Hz zu PWM 
Frequenz zu erzeugen.

Mein Problem ist nun, dass das erzeugt PWM-Signal lediglich eine max. 
Amplitude von ca. 1,06V hat und ich mir nicht erklären kann warum! Lass 
ich einen PIN als GPIO Output Toggeln, dann hab ich die vollen 3,3V. 
Hatte jemand evtl. schonmal das Problem oder hätte eine Idee an was 
dieser Spannungsabfall liegen kann? Vll. seh oder versteh ich das auch 
Falsch aber die Frequenz hat doch nichts mit dem Spannungsausgang zu tun 
oder etwas doch? gibt es eine Einstellmöglichkeit die ich vll. übersehen 
hab wo eben genau die 3,3V eingestellt werden müssen.

Ich hänge mal meinen Code an, vll. hat sich dort ja der Fehler 
versteckt. (nicht wundern, das Heizen und Kühlen kommt daher, dass 
anstatt dem Motor irgendwann ein Peltiermodul angehängt werden soll.

Wäre über jede Idee sehr dankbar :) vll. kann man sich auch per mail 
Austauschen wenn wirklich
1
/* USER CODE BEGIN Header */
2
/**
3
  ******************************************************************************
4
  * @file           : main.c
5
  * @brief          : Main program body
6
  ******************************************************************************
7
  * @attention
8
  *
9
  * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
10
  * All rights reserved.</center></h2>
11
  *
12
  * This software component is licensed by ST under BSD 3-Clause license,
13
  * the "License"; You may not use this file except in compliance with the
14
  * License. You may obtain a copy of the License at:
15
  *                        opensource.org/licenses/BSD-3-Clause
16
  *
17
  ******************************************************************************
18
  */
19
/* USER CODE END Header */
20
21
/* Includes ------------------------------------------------------------------*/
22
#include "main.h"
23
24
/* Private includes ----------------------------------------------------------*/
25
/* USER CODE BEGIN Includes */
26
27
/* USER CODE END Includes */
28
29
/* Private typedef -----------------------------------------------------------*/
30
/* USER CODE BEGIN PTD */
31
32
/* USER CODE END PTD */
33
34
/* Private define ------------------------------------------------------------*/
35
/* USER CODE BEGIN PD */
36
37
/* USER CODE END PD */
38
39
/* Private macro -------------------------------------------------------------*/
40
/* USER CODE BEGIN PM */
41
42
/* USER CODE END PM */
43
44
/* Private variables ---------------------------------------------------------*/
45
TIM_HandleTypeDef htim2;
46
47
/* USER CODE BEGIN PV */
48
uint8_t ui8TimPulse = 50; //Set duty cycle to 50 %
49
50
/* USER CODE END PV */
51
52
/* Private function prototypes -----------------------------------------------*/
53
void SystemClock_Config(void);
54
static void MX_GPIO_Init(void);
55
static void MX_TIM2_Init(void);
56
/* USER CODE BEGIN PFP */
57
58
/* USER CODE END PFP */
59
60
/* Private user code ---------------------------------------------------------*/
61
/* USER CODE BEGIN 0 */
62
63
64
65
void heizen(uint16_t value){
66
67
  HAL_GPIO_WritePin(nSLEEP_GPIO_Port,nSLEEP_Pin, 1);
68
  HAL_GPIO_WritePin(DISABLE_GPIO_Port,DISABLE_Pin, 0);
69
70
  TIM_OC_InitTypeDef sConfigOC = {0};
71
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
72
73
  sConfigOC.Pulse = value;
74
75
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
76
77
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
78
    if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
79
    {
80
      Error_Handler();
81
    }
82
    sConfigOC.Pulse = 101;
83
    sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
84
    if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
85
    {
86
      Error_Handler();
87
    }
88
89
90
      HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
91
      HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
92
93
94
95
96
}
97
98
99
100
      HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
101
      HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
102
}
103
104
//value=PWM Value
105
void peltier(int16_t value ){
106
  if (value>0){
107
    heizen(value);
108
  }
109
  if (value <0){
110
    cooling( (uint16_t)(value*-1) );
111
  }
112
  if (value ==0){
113
    HAL_GPIO_WritePin(nSLEEP_GPIO_Port,nSLEEP_Pin, 0);
114
  }
115
116
}
117
/* USER CODE END 0 */
118
119
/**
120
  * @brief  The application entry point.
121
  * @retval int
122
  */
123
int main(void)
124
{
125
  /* USER CODE BEGIN 1 */
126
127
  /* USER CODE END 1 */
128
  
129
130
  /* MCU Configuration--------------------------------------------------------*/
131
132
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
133
  HAL_Init();
134
135
  /* USER CODE BEGIN Init */
136
137
  /* USER CODE END Init */
138
139
  /* Configure the system clock */
140
  SystemClock_Config();
141
142
  /* USER CODE BEGIN SysInit */
143
144
  /* USER CODE END SysInit */
145
146
  /* Initialize all configured peripherals */
147
  MX_GPIO_Init();
148
  MX_TIM2_Init();
149
  /* USER CODE BEGIN 2 */
150
151
  HAL_TIM_Base_Start_IT(&htim2);//Startet Zeitbasis des TIMERS
152
153
  /* USER CODE END 2 */
154
155
  /* Infinite loop */
156
  /* USER CODE BEGIN WHILE */
157
  while (1)
158
  {
159
    /* USER CODE END WHILE */
160
    peltier(50);
161
    HAL_Delay(5000);
162
163
164
    /* USER CODE BEGIN 3 */
165
  }
166
  /* USER CODE END 3 */
167
}
168
169
/**
170
  * @brief System Clock Configuration
171
  * @retval None
172
  */
173
void SystemClock_Config(void)
174
{
175
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
176
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
177
178
  /** Initializes the CPU, AHB and APB busses clocks 
179
  */
180
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
181
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
182
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
183
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
184
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
185
  {
186
    Error_Handler();
187
  }
188
  /** Initializes the CPU, AHB and APB busses clocks 
189
  */
190
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
191
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
192
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
193
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
194
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
195
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
196
197
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
198
  {
199
    Error_Handler();
200
  }
201
}
202
203
/**
204
  * @brief TIM2 Initialization Function
205
  * @param None
206
  * @retval None
207
  */
208
static void MX_TIM2_Init(void)
209
{
210
211
  /* USER CODE BEGIN TIM2_Init 0 */
212
213
  /* USER CODE END TIM2_Init 0 */
214
215
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
216
  TIM_MasterConfigTypeDef sMasterConfig = {0};
217
  TIM_OC_InitTypeDef sConfigOC = {0};
218
219
  /* USER CODE BEGIN TIM2_Init 1 */
220
221
  /* USER CODE END TIM2_Init 1 */
222
  htim2.Instance = TIM2;
223
  htim2.Init.Prescaler = 4;
224
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
225
  htim2.Init.Period = 100;
226
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
227
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
228
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
229
  {
230
    Error_Handler();
231
  }
232
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
233
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
234
  {
235
    Error_Handler();
236
  }
237
  if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
238
  {
239
    Error_Handler();
240
  }
241
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
242
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
243
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
244
  {
245
    Error_Handler();
246
  }
247
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
248
  sConfigOC.Pulse = 0;
249
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
250
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
251
  if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
252
  {
253
    Error_Handler();
254
  }
255
  sConfigOC.Pulse = 50;
256
  sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
257
  if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
258
  {
259
    Error_Handler();
260
  }
261
  /* USER CODE BEGIN TIM2_Init 2 */
262
263
  /* USER CODE END TIM2_Init 2 */
264
  HAL_TIM_MspPostInit(&htim2);
265
266
}
267
268
/**
269
  * @brief GPIO Initialization Function
270
  * @param None
271
  * @retval None
272
  */
273
static void MX_GPIO_Init(void)
274
{
275
  GPIO_InitTypeDef GPIO_InitStruct = {0};
276
277
  /* GPIO Ports Clock Enable */
278
  __HAL_RCC_GPIOA_CLK_ENABLE();
279
  __HAL_RCC_GPIOC_CLK_ENABLE();
280
  __HAL_RCC_GPIOD_CLK_ENABLE();
281
  __HAL_RCC_GPIOB_CLK_ENABLE();
282
283
  /*Configure GPIO pin Output Level */
284
  HAL_GPIO_WritePin(DISABLE_GPIO_Port, DISABLE_Pin, GPIO_PIN_RESET);
285
286
  /*Configure GPIO pin Output Level */
287
  HAL_GPIO_WritePin(nSLEEP_GPIO_Port, nSLEEP_Pin, GPIO_PIN_RESET);
288
289
  /*Configure GPIO pin : DISABLE_Pin */
290
  GPIO_InitStruct.Pin = DISABLE_Pin;
291
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
292
  GPIO_InitStruct.Pull = GPIO_NOPULL;
293
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
294
  HAL_GPIO_Init(DISABLE_GPIO_Port, &GPIO_InitStruct);
295
296
  /*Configure GPIO pin : nSLEEP_Pin */
297
  GPIO_InitStruct.Pin = nSLEEP_Pin;
298
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
299
  GPIO_InitStruct.Pull = GPIO_NOPULL;
300
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
301
  HAL_GPIO_Init(nSLEEP_GPIO_Port, &GPIO_InitStruct);
302
303
}
304
305
/* USER CODE BEGIN 4 */
306
307
/* USER CODE END 4 */
308
309
/**
310
  * @brief  This function is executed in case of error occurrence.
311
  * @retval None
312
  */
313
void Error_Handler(void)
314
{
315
  /* USER CODE BEGIN Error_Handler_Debug */
316
  /* User can add his own implementation to report the HAL error return state */
317
318
  /* USER CODE END Error_Handler_Debug */
319
}
320
321
#ifdef  USE_FULL_ASSERT
322
/**
323
  * @brief  Reports the name of the source file and the source line number
324
  *         where the assert_param error has occurred.
325
  * @param  file: pointer to the source file name
326
  * @param  line: assert_param error line source number
327
  * @retval None
328
  */
329
void assert_failed(uint8_t *file, uint32_t line)
330
{ 
331
  /* USER CODE BEGIN 6 */
332
  /* User can add his own implementation to report the file name and line number,
333
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
334
  /* USER CODE END 6 */
335
}
336
#endif /* USE_FULL_ASSERT */
337
338
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

: Bearbeitet durch Moderator
von Stefan ⛄ F. (stefanus)


Lesenswert?

In der Funktion "heizen" setzt du sConfigOC.Pulse = 101. Das ist wohl 
nicht der maximal möglich Wert, also kommt da auch nicht die maximal 
mögliche Spannung (im Mittel) heraus.

Die Funktion "cooling" hast du uns verheimlicht. Ein Vollständiges 
compilierbares Projekt wäre schon notwendig, um alles zu überprüfen.

von pegel (Gast)


Lesenswert?

katilinchen schrieb:
> GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

Versuch doch mal bei beiden mehr Speed.
Wenn eine Last dran ist, kann das einen Unterschied ausmachen.

von Stefan ⛄ F. (stefanus)


Lesenswert?

pegel schrieb:
> Versuch doch mal bei beiden mehr Speed.
> Wenn eine Last dran ist, kann das einen Unterschied ausmachen.

Doch nicht bei 200 Hz PWM Frequenz!

Laut HAL Doku: GPIO_SPEED_FREQ_LOW ist Low Speed
Laut Referenzhandbuch: Low Speed ist für bis zu 2 MHz vorgesehen

Schön, dass man diese Info nur zur Hälfte im HAL Handbuch zur zur 
anderen Hälfte im Referenzhandbuch findet. Was haben die bei ST 
geraucht?

von Guest (Gast)


Lesenswert?

pegel schrieb:
> katilinchen schrieb:
>> GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
>
> Versuch doch mal bei beiden mehr Speed.
> Wenn eine Last dran ist, kann das einen Unterschied ausmachen.

Das ist bei dieser Frequenz quatsch. 200Hz sind doch nichts....

Stefan ⛄ F. schrieb:
> In der Funktion "heizen" setzt du sConfigOC.Pulse = 101. Das ist wohl
> nicht der maximal möglich Wert, also kommt da auch nicht die maximal
> mögliche Spannung (im Mittel) heraus.

Das sehe ich auch so. Ich nehme mal an du hast mit einem Multimeter 
gemessen. An dieser Stelle wäre ein Oszilloskop sinnvoll.

Ich nehme an du willst ein Peltier-Element steuern? Wenn du eine große 
Temperaturdifferenz erreichen willst solltest du es überdenken das Ganze 
mit reinem PWM zu machen. Peltier-Elemente brauchen einen konstanten 
Stromfluss. Wenn du sie einfach an und ab schaltest fließt die Wärme auf 
die kalte Seite zurück. Ein Konstantsromtreiber bzw. eine einstellbare 
Spannungsquelle wären hier das richtige.

von katilinchen (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> In der Funktion "heizen" setzt du sConfigOC.Pulse = 101. Das ist wohl
> nicht der maximal möglich Wert, also kommt da auch nicht die maximal
> mögliche Spannung (im Mittel) heraus.
Die Frage ist nur was stell ich da ein ? ist das die Max. Counterperiod 
? ist die dann das doppelte? oder wie berechne ich die am Besten?
>
> Die Funktion "cooling" hast du uns verheimlicht. Ein Vollständiges
> compilierbares Projekt wäre schon notwendig, um alles zu überprüfen.

ist eigentlich dasselbe in grün aber hier:
1
/* USER CODE BEGIN Header */
2
/**
3
  ******************************************************************************
4
  * @file           : main.c
5
  * @brief          : Main program body
6
  ******************************************************************************
7
  * @attention
8
  *
9
  * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
10
  * All rights reserved.</center></h2>
11
  *
12
  * This software component is licensed by ST under BSD 3-Clause license,
13
  * the "License"; You may not use this file except in compliance with the
14
  * License. You may obtain a copy of the License at:
15
  *                        opensource.org/licenses/BSD-3-Clause
16
  *
17
  ******************************************************************************
18
  */
19
/* USER CODE END Header */
20
21
/* Includes ------------------------------------------------------------------*/
22
#include "main.h"
23
24
/* Private includes ----------------------------------------------------------*/
25
/* USER CODE BEGIN Includes */
26
27
/* USER CODE END Includes */
28
29
/* Private typedef -----------------------------------------------------------*/
30
/* USER CODE BEGIN PTD */
31
32
/* USER CODE END PTD */
33
34
/* Private define ------------------------------------------------------------*/
35
/* USER CODE BEGIN PD */
36
37
/* USER CODE END PD */
38
39
/* Private macro -------------------------------------------------------------*/
40
/* USER CODE BEGIN PM */
41
42
/* USER CODE END PM */
43
44
/* Private variables ---------------------------------------------------------*/
45
TIM_HandleTypeDef htim2;
46
47
/* USER CODE BEGIN PV */
48
uint8_t ui8TimPulse = 50; //Set duty cycle to 50 %
49
50
/* USER CODE END PV */
51
52
/* Private function prototypes -----------------------------------------------*/
53
void SystemClock_Config(void);
54
static void MX_GPIO_Init(void);
55
static void MX_TIM2_Init(void);
56
/* USER CODE BEGIN PFP */
57
58
/* USER CODE END PFP */
59
60
/* Private user code ---------------------------------------------------------*/
61
/* USER CODE BEGIN 0 */
62
63
64
65
void heizen(uint16_t value){
66
67
  HAL_GPIO_WritePin(nSLEEP_GPIO_Port,nSLEEP_Pin, 1);
68
  HAL_GPIO_WritePin(DISABLE_GPIO_Port,DISABLE_Pin, 0);
69
70
  TIM_OC_InitTypeDef sConfigOC = {0};
71
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
72
73
  sConfigOC.Pulse = value;
74
75
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
76
77
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
78
    if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
79
    {
80
      Error_Handler();
81
    }
82
    sConfigOC.Pulse = 101;
83
    sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
84
    if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
85
    {
86
      Error_Handler();
87
    }
88
89
90
      HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
91
      HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
92
93
94
95
96
}
97
98
void cooling(uint16_t value){
99
100
  HAL_GPIO_WritePin(nSLEEP_GPIO_Port,nSLEEP_Pin, 1);
101
  HAL_GPIO_WritePin(DISABLE_GPIO_Port,DISABLE_Pin, 0);
102
103
  TIM_OC_InitTypeDef sConfigOC = {0};
104
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
105
106
  sConfigOC.Pulse = 101;
107
108
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
109
110
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
111
    if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
112
    {
113
      Error_Handler();
114
    }
115
    sConfigOC.Pulse = value;
116
    sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
117
    if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
118
    {
119
      Error_Handler();
120
    }
121
122
123
      HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
124
      HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
125
}
126
127
//value=PWM Value
128
void peltier(int16_t value ){
129
  if (value>0){
130
    heizen(value);
131
  }
132
  if (value <0){
133
    cooling( (uint16_t)(value*-1) );
134
  }
135
  if (value ==0){
136
    HAL_GPIO_WritePin(nSLEEP_GPIO_Port,nSLEEP_Pin, 0);
137
  }
138
139
}
140
/* USER CODE END 0 */
141
142
/**
143
  * @brief  The application entry point.
144
  * @retval int
145
  */
146
int main(void)
147
{
148
  /* USER CODE BEGIN 1 */
149
150
  /* USER CODE END 1 */
151
  
152
153
  /* MCU Configuration--------------------------------------------------------*/
154
155
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
156
  HAL_Init();
157
158
  /* USER CODE BEGIN Init */
159
160
  /* USER CODE END Init */
161
162
  /* Configure the system clock */
163
  SystemClock_Config();
164
165
  /* USER CODE BEGIN SysInit */
166
167
  /* USER CODE END SysInit */
168
169
  /* Initialize all configured peripherals */
170
  MX_GPIO_Init();
171
  MX_TIM2_Init();
172
  /* USER CODE BEGIN 2 */
173
174
  HAL_TIM_Base_Start_IT(&htim2);//Startet Zeitbasis des TIMERS
175
176
  /* USER CODE END 2 */
177
178
  /* Infinite loop */
179
  /* USER CODE BEGIN WHILE */
180
  while (1)
181
  {
182
    /* USER CODE END WHILE */
183
    peltier(50);
184
    HAL_Delay(5000);
185
    peltier(-50);
186
    HAL_Delay(5000);
187
188
189
    /* USER CODE BEGIN 3 */
190
  }
191
  /* USER CODE END 3 */
192
}
193
194
/**
195
  * @brief System Clock Configuration
196
  * @retval None
197
  */
198
void SystemClock_Config(void)
199
{
200
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
201
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
202
203
  /** Initializes the CPU, AHB and APB busses clocks 
204
  */
205
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
206
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
207
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
208
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
209
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
210
  {
211
    Error_Handler();
212
  }
213
  /** Initializes the CPU, AHB and APB busses clocks 
214
  */
215
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
216
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
217
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
218
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
219
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
220
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
221
222
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
223
  {
224
    Error_Handler();
225
  }
226
}
227
228
/**
229
  * @brief TIM2 Initialization Function
230
  * @param None
231
  * @retval None
232
  */
233
static void MX_TIM2_Init(void)
234
{
235
236
  /* USER CODE BEGIN TIM2_Init 0 */
237
238
  /* USER CODE END TIM2_Init 0 */
239
240
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
241
  TIM_MasterConfigTypeDef sMasterConfig = {0};
242
  TIM_OC_InitTypeDef sConfigOC = {0};
243
244
  /* USER CODE BEGIN TIM2_Init 1 */
245
246
  /* USER CODE END TIM2_Init 1 */
247
  htim2.Instance = TIM2;
248
  htim2.Init.Prescaler = 4;
249
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
250
  htim2.Init.Period = 100;
251
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
252
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
253
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
254
  {
255
    Error_Handler();
256
  }
257
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
258
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
259
  {
260
    Error_Handler();
261
  }
262
  if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
263
  {
264
    Error_Handler();
265
  }
266
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
267
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
268
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
269
  {
270
    Error_Handler();
271
  }
272
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
273
  sConfigOC.Pulse = 0;
274
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
275
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
276
  if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
277
  {
278
    Error_Handler();
279
  }
280
  sConfigOC.Pulse = 50;
281
  sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
282
  if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
283
  {
284
    Error_Handler();
285
  }
286
  /* USER CODE BEGIN TIM2_Init 2 */
287
288
  /* USER CODE END TIM2_Init 2 */
289
  HAL_TIM_MspPostInit(&htim2);
290
291
}
292
293
/**
294
  * @brief GPIO Initialization Function
295
  * @param None
296
  * @retval None
297
  */
298
static void MX_GPIO_Init(void)
299
{
300
  GPIO_InitTypeDef GPIO_InitStruct = {0};
301
302
  /* GPIO Ports Clock Enable */
303
  __HAL_RCC_GPIOA_CLK_ENABLE();
304
  __HAL_RCC_GPIOC_CLK_ENABLE();
305
  __HAL_RCC_GPIOD_CLK_ENABLE();
306
  __HAL_RCC_GPIOB_CLK_ENABLE();
307
308
  /*Configure GPIO pin Output Level */
309
  HAL_GPIO_WritePin(DISABLE_GPIO_Port, DISABLE_Pin, GPIO_PIN_RESET);
310
311
  /*Configure GPIO pin Output Level */
312
  HAL_GPIO_WritePin(nSLEEP_GPIO_Port, nSLEEP_Pin, GPIO_PIN_RESET);
313
314
  /*Configure GPIO pin : DISABLE_Pin */
315
  GPIO_InitStruct.Pin = DISABLE_Pin;
316
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
317
  GPIO_InitStruct.Pull = GPIO_NOPULL;
318
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
319
  HAL_GPIO_Init(DISABLE_GPIO_Port, &GPIO_InitStruct);
320
321
  /*Configure GPIO pin : nSLEEP_Pin */
322
  GPIO_InitStruct.Pin = nSLEEP_Pin;
323
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
324
  GPIO_InitStruct.Pull = GPIO_NOPULL;
325
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
326
  HAL_GPIO_Init(nSLEEP_GPIO_Port, &GPIO_InitStruct);
327
328
}
329
330
/* USER CODE BEGIN 4 */
331
332
/* USER CODE END 4 */
333
334
/**
335
  * @brief  This function is executed in case of error occurrence.
336
  * @retval None
337
  */
338
void Error_Handler(void)
339
{
340
  /* USER CODE BEGIN Error_Handler_Debug */
341
  /* User can add his own implementation to report the HAL error return state */
342
343
  /* USER CODE END Error_Handler_Debug */
344
}
345
346
#ifdef  USE_FULL_ASSERT
347
/**
348
  * @brief  Reports the name of the source file and the source line number
349
  *         where the assert_param error has occurred.
350
  * @param  file: pointer to the source file name
351
  * @param  line: assert_param error line source number
352
  * @retval None
353
  */
354
void assert_failed(uint8_t *file, uint32_t line)
355
{ 
356
  /* USER CODE BEGIN 6 */
357
  /* User can add his own implementation to report the file name and line number,
358
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
359
  /* USER CODE END 6 */
360
}
361
#endif /* USE_FULL_ASSERT */
362
363
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

: Bearbeitet durch Moderator
von katilinchen (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Doch nicht bei 200 Hz PWM Frequenz!
>
> Laut HAL Doku: GPIO_SPEED_FREQ_LOW ist Low Speed
> Laut Referenzhandbuch: Low Speed ist für bis zu 2 MHz vorgesehen
>
> Schön, dass man diese Info nur zur Hälfte im HAL Handbuch zur zur
> anderen Hälfte im Referenzhandbuch findet. Was haben die bei ST
> geraucht?

Das Ding ist man findet oft so widersprüchliches zeug...und auch zu der 
IDE finde ich die Erklärungen zu den Einstellungen leider etwas 
verwirrend..vor allem dann, wenn es etwas Spezieller werden soll. die 
200Hz sind ja nur zu Testzwecken. Später hätte ich gerne eine 
Schaltfrequenz von ca. 100 kHz. aber dazu muss erstmal das umpolen mit 
der H-Brücke einwandfrei funktionieren.

von katilinchen (Gast)


Lesenswert?

Guest schrieb:
> pegel schrieb:
>> katilinchen schrieb:
>>> GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
>>
>> Versuch doch mal bei beiden mehr Speed.
>> Wenn eine Last dran ist, kann das einen Unterschied ausmachen.
>
> Das ist bei dieser Frequenz quatsch. 200Hz sind doch nichts....
>
> Stefan ⛄ F. schrieb:
>> In der Funktion "heizen" setzt du sConfigOC.Pulse = 101. Das ist wohl
>> nicht der maximal möglich Wert, also kommt da auch nicht die maximal
>> mögliche Spannung (im Mittel) heraus.
>
> Das sehe ich auch so. Ich nehme mal an du hast mit einem Multimeter
> gemessen. An dieser Stelle wäre ein Oszilloskop sinnvoll.

Leider beides Probiert zuerst Oszilloskop und danach mitm Multimeter 
nachgemessen -.- nur durch das Oszilloskopbild bin ich ja darauf 
gekommen mal nach zu messen..aber das könnte tatsächlich mal ein Ansatz 
sein den ich probieren könnte...nur die Frage ist wie berechne ich da 
nen Sinnvollen Wert?
>
> Ich nehme an du willst ein Peltier-Element steuern? Wenn du eine große
> Temperaturdifferenz erreichen willst solltest du es überdenken das Ganze
> mit reinem PWM zu machen. Peltier-Elemente brauchen einen konstanten
> Stromfluss. Wenn du sie einfach an und ab schaltest fließt die Wärme auf
> die kalte Seite zurück. Ein Konstantsromtreiber bzw. eine einstellbare
> Spannungsquelle wären hier das richtige.

PWM ist sogar sehr kontraproduktiv fürs Peltier, hab das schon 
nachgemessen und die Effizienz leidet enorm. Das PWM brauche ich 
lediglich zu Temperatursteuerung. Dem Peltier vorgeschalten wird ne 
Spule die den Strom dann glättet und eine H-Brücke die das Umpolen dann 
schön smooth ermöglicht. :)

von Guest (Gast)


Lesenswert?

katilinchen schrieb:
> dem Peltier vorgeschalten wird ne
> Spule die den Strom dann glättet

Ich hoffe du nimmst da mehr als 200Hz die Induktivität wird ja sonst 
riesig
Wir haben bei uns vor nicht allzu langer Zeit einen Konstantstromtreiber 
für Peltier Elemente gebaut der lief mit 2MHz.

katilinchen schrieb:
> nur durch das Oszilloskopbild bin ich ja darauf
> gekommen mal nach zu messen

Wie sah das denn aus?

Spontan fällt mir in deinem Code auf das dort die Pins für den Timer 
nicht Initialisiert werden. Vermutlich sind sie unkonfiguriert und somit 
High-Z dann sind diese 1,06V vermutlich irgendeine Ladung vom H-Treiber. 
Da sollte sowas stehen:
1
    __HAL_RCC_GPIOB_CLK_ENABLE();
2
    __HAL_RCC_GPIOA_CLK_ENABLE();
3
    /**TIM2 GPIO Configuration    
4
    PB3     ------> TIM2_CH2
5
    PA15     ------> TIM2_CH1 
6
    */
7
    GPIO_InitStruct.Pin = GPIO_PIN_3;
8
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
9
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
10
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
11
12
    GPIO_InitStruct.Pin = GPIO_PIN_15;
13
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
14
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
15
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

Außerdem genügt:
1
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
2
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
3
4
HAL_TIM_Base_Start_IT(&htim2); ist normal nicht notwendig.
Es ist ebenfalls nicht notwendig den Timer immer neu zu Konfigurieren. 
Du kannst die Werte für den DC auch direkt in das Register schreiben:
1
TIM2->CCR1 = x;
2
TIM2->CCR2 = y;
das geht ohne den Timer zu Stoppen. Außerdem verwirrt mich deine 
Ansteuerung etwas. Bei der H-Brücke wird das PWM ja normal so gemacht, 
dass bei 50% DC kein Strom fließt, wenn man dann mehr oder weniger macht 
hat man eben positiven oder negativen Strom.

von Vorname N. (mcu32)


Lesenswert?

Ohne mir den Codewirrwarr angesehen zu haben würde ich auf einen 
falschen bzw, zu geringen Duty-Cycle tippen. Das kann an den 
Timersettings, dem Timer generell oder einfach dem falschen DC im 
entsprechenden Register liegen.

von Stefan ⛄ F. (stefanus)


Lesenswert?

Tutorial für PWM mit HAL:
https://simonmartin.ch/resources/stm32/dl/STM32%20Tutorial%2002%20-%20PWM%20Generation%20using%20HAL%20(and%20FreeRTOS).pdf

Ich habe auch meine Schwierigkeiten mit der Dokumentation der HAL. Die 
setzen offenbar voraus, dass du mit dem I/O Einheiten des STM32 bereits 
vertraut bist. Deswegen: mache dich vertraut. Lese die relevanten 
Kapitel Referenzhandbuch und probiere es aus, indem du direkt auf die 
Register zugreifst.

Wenn du das bei wenigstens einem STM32 Modell gemacht und verstanden 
hast, wird Dir der Umgang mit der HAL sicher leichter fallen. Eventuell 
findest du auch (wie ich) heraus, dass die HAL für dich mehr Nachteile 
als Vorteile bringt. Das Hauptargument der HAL: Portabilität von Code 
aber beschränkt auf STM32 ist z.B. nicht für jeden von Interesse.

: Bearbeitet durch User
von Lothar M. (lkmiller) (Moderator) Benutzerseite


Lesenswert?

katilinchen schrieb:
> Ich hänge mal meinen Code an
Ja, mach das. Als C-Datei.
Oder pack den Code wenigstens zwischen die [c] Tags.

Also so, wie über jeder Texteingabebox unter "Antwort schreiben" 
beschrieben.

von pasi (Gast)


Lesenswert?

Die Frage nach der Messmethode bleibt ja immernoch.
Mit dem Multimeter kannst du bei der Frequenz keine sinnvolle Spannung 
messen. Das muss schon mit dem Oszi passieren. Wenn du nicht sicher bist 
was du da abliest kannst du das Bild gerne hier mal mit anhängen.

Gruß

von Tom (Gast)


Lesenswert?

Guest schrieb:
> Wir haben bei uns vor nicht allzu langer Zeit einen Konstantstromtreiber
> für Peltier Elemente gebaut der lief mit 2MHz.

2MHz? Na klar... und wie groß war der Kühlkörper für die MosFets? Bei 
der Frequenz hat man ja schon Probleme MosFets zu finden die das 
überhaupt mit machen geschweigedenn dabei nicht anfangen zu glühen.

von Guest (Gast)


Lesenswert?

Tom schrieb:
> und wie groß war der Kühlkörper für die MosFets?

Welcher Kühlkörper? Galliumnitrid regelt.....

Erst denken dann reden.

von pegel (Gast)


Lesenswert?

Wie war das jetzt eigentlich mit dem DISABLE_Pin und dem nSLEEP_Pin?

Das sind PWM Ausgänge und die werden auch mit HAL_GPIO_WritePin() 
geschaltet?

Klingt für mich, als müsste man dabei sehr genau aufpassen was man tut.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.