Forum: Mikrocontroller und Digitale Elektronik SYSCFG->EXTICR Fehler


von D. I. (Firma: Fa) (buell)


Lesenswert?

Hallo

Wenn ich

SYSCFG->EXTICR = SYSCFG_EXTICR4_EXTI12_PC;

setzen möchte, kommt die Meldung "array type volatile uint32_t [4] is 
not assignable.

Was ist damit gemeint?

von Dr. Sommer (Gast)


Lesenswert?

Dass du angeben musst, welches der EXTICR Register du meinst:
1
SYSCFG->EXTICR[3] = SYSCFG_EXTICR4_EXTI12_PC;
(Achtung Zählung beginnt da bei 0)

von D. I. (Firma: Fa) (buell)


Lesenswert?

Super danke für die schnelle Hilfe

Hat es einen Grund, warum das im Manual nicht gleich als 
SYSCFG_EXTICR[x] x...0-3 angegeben wird?
Ich wäre nie drauf gekommen, dass das ein Array sein soll.

von Dr. Sommer (Gast)


Lesenswert?

D. I. schrieb:
> Hat es einen Grund, warum das im Manual nicht gleich als
> SYSCFG_EXTICR[x] x...1-4 angegeben wird?

Naja das Manual beschreibt halt nur die Hardware, das hat nix mit 
irgendwelchen Programmiersprachen zu tun. Und da nennen sie das halt 
SYSCFG_EXTICR1...4 .
In der Header-Datei für C werden die 4 Register in einem Array 
zusammengefasst. Das könnte man aber auch problemlos auf 4 einzelne 
Register umbauen.

D. I. schrieb:
> Ich wäre nie drauf gekommen, dass das ein Array sein soll.
Die Fehlermeldung legt es nahe... Außerdem kannst du dir in der 
stm32fxxx.h die Definition anschauen.

von D. I. (Firma: Fa) (buell)


Lesenswert?

Vielen Dank, das hab ich jetzt mal angesehen.

Eine andere Frage:

Ich möchte, wenn auf PC12 ein high signal kommt, dass die LED2 auf 
meinem NUCLEO STM32l476RG eingeschaltet wird per Interrupt.

Das habe ich so gemacht, funktioniert aber nicht so ganz:

Meine Funktion EXTI:
1
void User_Init_EXTI(void)
2
{
3
   
4
  EXTI->IMR1 |= EXTI_IMR1_IM12;                             /* Enable the Interrupt request from EXTI_line_12 */
5
  EXTI->RTSR1 |= EXTI_RTSR1_RT12;                           /* Enable a rising trigger EXTI line 12 Interrupt */
6
   
7
  SYSCFG->EXTICR[3] = SYSCFG_EXTICR4_EXTI12_PC;             /* Mapping the EXTI line to Port C */
8
  
9
  /*Configure NVIC for EXTI15_10_IRQn */
10
  NVIC_EnableIRQ(EXTI15_10_IRQn); 
11
  NVIC_SetPriority(EXTI15_10_IRQn,0);
12
}






all diese Prototypen werden auch im main initialisiert
1
/* Private function prototypes -----------------------------------------------*/
2
void SystemClock_Config(void);
3
void Error_Handler(void);
4
static void MX_GPIO_Init(void);
5
static void MX_TIM1_Init(void);                                    
6
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
7
                                
8
9
/* USER CODE BEGIN PFP */
10
/* Private function prototypes -----------------------------------------------*/
11
void User_Init_Timer1(uint8_t Presc, uint8_t period, uint16_t PulseN);
12
void Enable_Counter_Timer1(void);
13
void User_Init_EXTI(void);
14
15
/* USER CODE END PFP */






Im stm32l4xx_it.c habe ich folgende Funktion drin:

1
/* USER CODE BEGIN 1 */
2
3
void EXTI_IRQHANDLER()
4
{
5
  void HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12); 
6
}
7
8
/* USER CODE END 1 */





Die Funktion void HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12); ist im gpio.c 
drin. Das sieht folgend aus und überprüft einfach das Pending bit, ob es 
gesetzt ist und löscht es dann auch.
1
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
2
{
3
  /* EXTI line interrupt detected */
4
  if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
5
  {
6
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
7
    HAL_GPIO_EXTI_Callback(GPIO_Pin);
8
    
9
  }
10
}





Was die Callback-Funktion macht, weiss ich nicht. Diese ist ebenfalls im 
gpio.c
1
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
2
{
3
  /* Prevent unused argument(s) compilation warning */
4
  UNUSED(GPIO_Pin);
5
      
6
  /* NOTE: This function should not be modified, when the callback is needed,
7
           the HAL_GPIO_EXTI_Callback could be implemented in the user file
8
   */
9
}


Wo setze ich nun, meine Funktion

HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5); hin und brauche ich das Callback?

von Dr. Sommer (Gast)


Lesenswert?

D. I. schrieb:
> Wo setze ich nun, meine Funktion
Weiß ich nicht, ich benutze die HAL nicht. Ich würde das so machen:
1
void EXTI4_IRQHandler (void) {
2
  if (EXTI->PR & EXTI_PR_PR12) {
3
    EXTI->PR = EXTI_PR_PR12;
4
    uint32_t ODR = GPIOA->ODR;
5
    GPIOA->BSRR = ((ODR & (1 << 5)) << 16) | ((~ODR) & (1 << 5));
6
  }
7
}
Ungetestet. Sieht mMn einfacher (und effizienter) als das ganze 
HAL-Getüddel aus. Der Funktionsname ist ggf. anders, abhängig vom 
Controller und Startup-Code.

D. I. schrieb:
> all diese Prototypen werden auch im main initialisiert
Deklariert, nicht initialisiert

von Dr. Sommer (Gast)


Lesenswert?

PS: Ich habe mir gerade mal die Definition von HAL_GPIO_TogglePin in der 
HAL angesehen:
1
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
2
{
3
  /* Check the parameters */
4
  assert_param(IS_GPIO_PIN(GPIO_Pin));
5
6
  GPIOx->ODR ^= GPIO_Pin;
7
}
Ist mal wieder ein typischer Fall von "ST kennt die eigene Hardware 
nicht". Weil hier ein Read-Modify-Write Cycle auf dem ODR gemacht wird, 
ist das nicht atomisch, d.h. wenn genau in der letzten Zeile ein 
weiterer Interrupt kommt der ODR anderweitig ändert, bekommt man eine 
Inkonsistenz auf den Pins.
Das wird bei meiner Methode vermieden, die nicht-genutzten Pins bleiben 
garantiert gleich. Probleme können nur beim tatsächlich beschriebenen 
Pin PA5 auftreten, aber man sollte natürlich nicht auf exakt die selben 
Ressourcen (Hier: PA5) aus verschachtelten Interrupts zugreifen.

von D. I. (Firma: Fa) (buell)


Lesenswert?

Hallo Vielen Dank für die Hilfe.
1
void EXTI4_IRQHandler (void) {
2
  if (EXTI->PR1 & EXTI_PR1_PIF12) {
3
    EXTI->PR1 = EXTI_PR1_PIF12;
4
    uint32_t ODR = GPIOA->ODR;
5
    GPIOA->BSRR = ((ODR & (1 << 5)) << 16) | ((~ODR) & (1 << 5));
6
  }
7
}

Was machst du da genau?

Du prüfst das Pending bit ob es gesetzt ist, sprich ob das bit 1 ist.
Dann setzt du das Pending bit auf 1 mittels EXTI->PR1 = EXTI_PR1_PIF12;
Warum setzt du nicht EXTI->PR1 = ~EXTI_PR1_PIF12; um es zu löschen?

dann verwendest du eine lokale variable und löscht das bit von PA5.
Aber wo hast du es gesetzt?

Könntest du die Zeilen kurz von deiner Seite erklären?

von Dr. Sommer (Gast)


Lesenswert?

D. I. schrieb:
> Dann setzt du das Pending bit auf 1 mittels EXTI->PR1 = EXTI_PR1_PIF12;
> Warum setzt du nicht EXTI->PR1 = ~EXTI_PR1_PIF12; um es zu löschen?
Weil bei diesem Register, laut Doku, Bits gelöscht werden indem man eine 
1 schreibt:
"Bits 22:0 PRx: Pending bit
0: No trigger request occurred
1: selected trigger request occurred
This bit is set when the selected edge event arrives on the external 
interrupt line.
This bit is cleared by programming it to '1'."

D. I. schrieb:
> dann verwendest du eine lokale variable und löscht das bit von PA5.
> Aber wo hast du es gesetzt?
Die lokale Variable wird als temporärer Speicher für ODR genutzt, denn 
wenn man 2x GPIOA->ODR schreiben würde in der nächsten Zeile, würde der 
Compiler da 2 Zugriffe daraus machen (weil das volatile ist), was a) 
ineffizient ist und b) Inkonsistenzen bewirken kann.
Das BSRR Register kann sowohl Port-Pins setzen (wenn man Bit 0-15 auf 1 
setzt) als auch löschen (wenn man Bit 15-31 auf 1 setzt). Daher 
beschreibe ich Bits 16-31 mit dem aktuellen Status von ODR, und 0-15 mit 
dem invertierten (~ Operator) Status. Um jedoch wirklich nur PA5 zu 
beeinflussen und die anderen Bits zu belassen, wird jeweils noch ein "& 
(1 << 5)" gemacht - mit 0 beschriebene Bits in BSRR bewirken keine 
Änderung der Port-Pins.
Effektiv bedeutet das: Wenn PA5 bereits auf 1 gesetzt ist, wird 0x200000 
auf GPIO->ODR geschrieben (PA5 wird auf 0 gesetzt), ansonsten 0x20 (PA5 
wird auf 1 gesetzt).
Diese etwas verdrehte Schreibweise (anstelle von if) funktioniert falls 
nötig auch mit mehreren Pins auf einmal, und vermeidet Branches (besser 
für Branch-Prediction, vermutlich effizienter).

von D. I. (Firma: Fa) (buell)


Lesenswert?

Ich habe mal den Debugger verwendet, das Problem warum es nicht 
funktioniert ist, dass das Programm nicht in den IRQ Handler springt, 
auch wenn ich ein Signal auf den Pin PC12 gebe.

Es müsste jetzt doch mit der Initialisierung in den IRQ Handler 
springen.

von Dr. Sommer (Gast)


Lesenswert?

D. I. schrieb:
> Es müsste jetzt doch mit der Initialisierung in den IRQ Handler
> springen.
Zeig doch mal den ganzen Code wie er jetzt aussieht.

D. I. schrieb:
> void EXTI_IRQHANDLER()
> {
>   void HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
> }
Das hier ist auch noch falsch, wie kompiliert das überhaupt...

von D. I. (Firma: Fa) (buell)


Lesenswert?

Das main
1
/**
2
  ******************************************************************************
3
  * File Name          : main.c
4
  * Description        : Main program body
5
  ******************************************************************************
6
  *
7
  * COPYRIGHT(c) 2017 STMicroelectronics
8
  *
9
  * Redistribution and use in source and binary forms, with or without modification,
10
  * are permitted provided that the following conditions are met:
11
  *   1. Redistributions of source code must retain the above copyright notice,
12
  *      this list of conditions and the following disclaimer.
13
  *   2. Redistributions in binary form must reproduce the above copyright notice,
14
  *      this list of conditions and the following disclaimer in the documentation
15
  *      and/or other materials provided with the distribution.
16
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
17
  *      may be used to endorse or promote products derived from this software
18
  *      without specific prior written permission.
19
  *
20
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
  *
31
  ******************************************************************************
32
  */
33
/* Includes ------------------------------------------------------------------*/
34
#include "main.h"
35
#include "stm32l4xx_hal.h"
36
37
/* USER CODE BEGIN Includes */
38
39
40
/* USER CODE END Includes */
41
42
/* Private variables ---------------------------------------------------------*/
43
TIM_HandleTypeDef htim1;
44
45
/* USER CODE BEGIN PV */
46
/* Private variables ---------------------------------------------------------*/
47
48
/* USER CODE END PV */
49
50
/* Private function prototypes -----------------------------------------------*/
51
void SystemClock_Config(void);
52
void Error_Handler(void);
53
static void MX_GPIO_Init(void);
54
static void MX_TIM1_Init(void);                                    
55
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
56
                                
57
58
/* USER CODE BEGIN PFP */
59
/* Private function prototypes -----------------------------------------------*/
60
61
void User_Init_EXTI(void);
62
63
/* USER CODE END PFP */
64
65
/* USER CODE BEGIN 0 */
66
67
68
void User_Init_EXTI(void)
69
{
70
   
71
  EXTI->IMR1 = EXTI_IMR1_IM12;                             /* Enable the Interrupt request from EXTI_line_12 */
72
  EXTI->RTSR1 = EXTI_RTSR1_RT12;                           /* Enable a rising trigger EXTI line 12 Interrupt */
73
   
74
  SYSCFG->EXTICR[3] = SYSCFG_EXTICR4_EXTI12_PC;             /* Mapping the EXTI line to Port C */
75
  
76
  /*Configure NVIC for EXTI15_10_IRQn */
77
  NVIC_EnableIRQ(EXTI15_10_IRQn); 
78
  NVIC_SetPriority(EXTI15_10_IRQn,0);
79
}
80
81
/* USER CODE END 0 */
82
83
int main(void)
84
{
85
86
  /* USER CODE BEGIN 1 */
87
88
  /* USER CODE END 1 */
89
90
  /* MCU Configuration----------------------------------------------------------*/
91
92
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
93
  HAL_Init();
94
95
  /* Configure the system clock */
96
  SystemClock_Config();
97
98
  /* Initialize all configured peripherals */
99
  MX_GPIO_Init();
100
  MX_TIM1_Init();
101
102
  /* USER CODE BEGIN 2 */
103
 
104
   User_Init_EXTI();
105
   
106
  /* USER CODE END 2 */
107
108
  /* Infinite loop */
109
  /* USER CODE BEGIN WHILE */
110
  while (1)
111
  {
112
 
113
      
114
     
115
  /* USER CODE END WHILE */
116
117
  /* USER CODE BEGIN 3 */
118
119
  }
120
  /* USER CODE END 3 */
121
122
}
123
124
/** System Clock Configuration
125
*/
126
void SystemClock_Config(void)
127
{
128
129
  RCC_OscInitTypeDef RCC_OscInitStruct;
130
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
131
132
    /**Initializes the CPU, AHB and APB busses clocks 
133
    */
134
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
135
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
136
  RCC_OscInitStruct.HSICalibrationValue = 16;
137
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
138
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
139
  RCC_OscInitStruct.PLL.PLLM = 1;
140
  RCC_OscInitStruct.PLL.PLLN = 10;
141
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
142
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
143
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
144
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
145
  {
146
    Error_Handler();
147
  }
148
149
    /**Initializes the CPU, AHB and APB busses clocks 
150
    */
151
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
152
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
153
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
154
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
155
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
156
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
157
158
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
159
  {
160
    Error_Handler();
161
  }
162
163
    /**Configure the main internal regulator output voltage 
164
    */
165
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
166
  {
167
    Error_Handler();
168
  }
169
170
    /**Configure the Systick interrupt time 
171
    */
172
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
173
174
    /**Configure the Systick 
175
    */
176
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
177
178
  /* SysTick_IRQn interrupt configuration */
179
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
180
}
181
182
/* TIM1 init function */
183
static void MX_TIM1_Init(void)
184
{
185
186
  TIM_SlaveConfigTypeDef sSlaveConfig;
187
  TIM_MasterConfigTypeDef sMasterConfig;
188
  TIM_OC_InitTypeDef sConfigOC;
189
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;
190
191
  htim1.Instance = TIM1;
192
  htim1.Init.Prescaler = 1;
193
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
194
  htim1.Init.Period = 8;
195
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
196
  htim1.Init.RepetitionCounter = 255;
197
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
198
  {
199
    Error_Handler();
200
  }
201
202
  if (HAL_TIM_OC_Init(&htim1) != HAL_OK)
203
  {
204
    Error_Handler();
205
  }
206
207
  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_TRIGGER;
208
  sSlaveConfig.InputTrigger = TIM_TS_ETRF;
209
  sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_NONINVERTED;
210
  sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1;
211
  sSlaveConfig.TriggerFilter = 0;
212
  if (HAL_TIM_SlaveConfigSynchronization(&htim1, &sSlaveConfig) != HAL_OK)
213
  {
214
    Error_Handler();
215
  }
216
217
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
218
  sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
219
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
220
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
221
  {
222
    Error_Handler();
223
  }
224
225
  sConfigOC.OCMode = TIM_OCMODE_TIMING;
226
  sConfigOC.Pulse = 0;
227
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
228
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
229
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
230
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
231
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
232
  if (HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
233
  {
234
    Error_Handler();
235
  }
236
237
  if (HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
238
  {
239
    Error_Handler();
240
  }
241
242
  if (HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
243
  {
244
    Error_Handler();
245
  }
246
247
  if (HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
248
  {
249
    Error_Handler();
250
  }
251
252
  sConfigOC.Pulse = 8;
253
  if (HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_5) != HAL_OK)
254
  {
255
    Error_Handler();
256
  }
257
258
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
259
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
260
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
261
  sBreakDeadTimeConfig.DeadTime = 0;
262
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
263
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
264
  sBreakDeadTimeConfig.BreakFilter = 0;
265
  sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
266
  sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
267
  sBreakDeadTimeConfig.Break2Filter = 0;
268
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
269
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
270
  {
271
    Error_Handler();
272
  }
273
274
  HAL_TIM_MspPostInit(&htim1);
275
276
}
277
278
/** Configure pins as 
279
        * Analog 
280
        * Input 
281
        * Output
282
        * EVENT_OUT
283
        * EXTI
284
*/
285
static void MX_GPIO_Init(void)
286
{
287
288
  GPIO_InitTypeDef GPIO_InitStruct;
289
290
  /* GPIO Ports Clock Enable */
291
  __HAL_RCC_GPIOC_CLK_ENABLE();
292
  __HAL_RCC_GPIOA_CLK_ENABLE();
293
294
  /*Configure GPIO pin Output Level */
295
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0|GPIO_PIN_5, GPIO_PIN_RESET);
296
297
  /*Configure GPIO pin : PC13 */
298
  GPIO_InitStruct.Pin = GPIO_PIN_13;
299
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
300
  GPIO_InitStruct.Pull = GPIO_NOPULL;
301
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
302
303
  /*Configure GPIO pins : PA0 PA5 */
304
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_5;
305
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
306
  GPIO_InitStruct.Pull = GPIO_NOPULL;
307
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
308
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
309
310
  /*Configure GPIO pin : PC12 */
311
  GPIO_InitStruct.Pin = GPIO_PIN_12;
312
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
313
  GPIO_InitStruct.Pull = GPIO_NOPULL;
314
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
315
316
}
317
318
/* USER CODE BEGIN 4 */
319
320
/* USER CODE END 4 */
321
322
/**
323
  * @brief  This function is executed in case of error occurrence.
324
  * @param  None
325
  * @retval None
326
  */
327
void Error_Handler(void)
328
{
329
  /* USER CODE BEGIN Error_Handler */
330
  /* User can add his own implementation to report the HAL error return state */
331
  while(1) 
332
  {
333
  }
334
  /* USER CODE END Error_Handler */ 
335
}
336
337
#ifdef USE_FULL_ASSERT
338
339
/**
340
   * @brief Reports the name of the source file and the source line number
341
   * where the assert_param error has occurred.
342
   * @param file: pointer to the source file name
343
   * @param line: assert_param error line source number
344
   * @retval None
345
   */
346
void assert_failed(uint8_t* file, uint32_t line)
347
{
348
  /* USER CODE BEGIN 6 */
349
  /* User can add his own implementation to report the file name and line number,
350
    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
351
  /* USER CODE END 6 */
352
353
}
354
355
#endif
356
357
/**
358
  * @}
359
  */ 
360
361
/**
362
  * @}
363
*/ 
364
365
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/





Der xxxit.c für den Interrupt sieht so aus

1
/**
2
  ******************************************************************************
3
  * @file    stm32l4xx_it.c
4
  * @brief   Interrupt Service Routines.
5
  ******************************************************************************
6
  *
7
  * COPYRIGHT(c) 2017 STMicroelectronics
8
  *
9
  * Redistribution and use in source and binary forms, with or without modification,
10
  * are permitted provided that the following conditions are met:
11
  *   1. Redistributions of source code must retain the above copyright notice,
12
  *      this list of conditions and the following disclaimer.
13
  *   2. Redistributions in binary form must reproduce the above copyright notice,
14
  *      this list of conditions and the following disclaimer in the documentation
15
  *      and/or other materials provided with the distribution.
16
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
17
  *      may be used to endorse or promote products derived from this software
18
  *      without specific prior written permission.
19
  *
20
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
  *
31
  ******************************************************************************
32
  */
33
/* Includes ------------------------------------------------------------------*/
34
#include "stm32l4xx_hal.h"
35
#include "stm32l4xx.h"
36
#include "stm32l4xx_it.h"
37
38
/* USER CODE BEGIN 0 */
39
40
/* USER CODE END 0 */
41
42
/* External variables --------------------------------------------------------*/
43
44
/******************************************************************************/
45
/*            Cortex-M4 Processor Interruption and Exception Handlers         */ 
46
/******************************************************************************/
47
48
/**
49
* @brief This function handles Non maskable interrupt.
50
*/
51
void NMI_Handler(void)
52
{
53
  /* USER CODE BEGIN NonMaskableInt_IRQn 0 */
54
55
  /* USER CODE END NonMaskableInt_IRQn 0 */
56
  /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
57
58
  /* USER CODE END NonMaskableInt_IRQn 1 */
59
}
60
61
/**
62
* @brief This function handles Hard fault interrupt.
63
*/
64
void HardFault_Handler(void)
65
{
66
  /* USER CODE BEGIN HardFault_IRQn 0 */
67
68
  /* USER CODE END HardFault_IRQn 0 */
69
  while (1)
70
  {
71
  }
72
  /* USER CODE BEGIN HardFault_IRQn 1 */
73
74
  /* USER CODE END HardFault_IRQn 1 */
75
}
76
77
/**
78
* @brief This function handles Memory management fault.
79
*/
80
void MemManage_Handler(void)
81
{
82
  /* USER CODE BEGIN MemoryManagement_IRQn 0 */
83
84
  /* USER CODE END MemoryManagement_IRQn 0 */
85
  while (1)
86
  {
87
  }
88
  /* USER CODE BEGIN MemoryManagement_IRQn 1 */
89
90
  /* USER CODE END MemoryManagement_IRQn 1 */
91
}
92
93
/**
94
* @brief This function handles Prefetch fault, memory access fault.
95
*/
96
void BusFault_Handler(void)
97
{
98
  /* USER CODE BEGIN BusFault_IRQn 0 */
99
100
  /* USER CODE END BusFault_IRQn 0 */
101
  while (1)
102
  {
103
  }
104
  /* USER CODE BEGIN BusFault_IRQn 1 */
105
106
  /* USER CODE END BusFault_IRQn 1 */
107
}
108
109
/**
110
* @brief This function handles Undefined instruction or illegal state.
111
*/
112
void UsageFault_Handler(void)
113
{
114
  /* USER CODE BEGIN UsageFault_IRQn 0 */
115
116
  /* USER CODE END UsageFault_IRQn 0 */
117
  while (1)
118
  {
119
  }
120
  /* USER CODE BEGIN UsageFault_IRQn 1 */
121
122
  /* USER CODE END UsageFault_IRQn 1 */
123
}
124
125
/**
126
* @brief This function handles System service call via SWI instruction.
127
*/
128
void SVC_Handler(void)
129
{
130
  /* USER CODE BEGIN SVCall_IRQn 0 */
131
132
  /* USER CODE END SVCall_IRQn 0 */
133
  /* USER CODE BEGIN SVCall_IRQn 1 */
134
135
  /* USER CODE END SVCall_IRQn 1 */
136
}
137
138
/**
139
* @brief This function handles Debug monitor.
140
*/
141
void DebugMon_Handler(void)
142
{
143
  /* USER CODE BEGIN DebugMonitor_IRQn 0 */
144
145
  /* USER CODE END DebugMonitor_IRQn 0 */
146
  /* USER CODE BEGIN DebugMonitor_IRQn 1 */
147
148
  /* USER CODE END DebugMonitor_IRQn 1 */
149
}
150
151
/**
152
* @brief This function handles Pendable request for system service.
153
*/
154
void PendSV_Handler(void)
155
{
156
  /* USER CODE BEGIN PendSV_IRQn 0 */
157
158
  /* USER CODE END PendSV_IRQn 0 */
159
  /* USER CODE BEGIN PendSV_IRQn 1 */
160
161
  /* USER CODE END PendSV_IRQn 1 */
162
}
163
164
/**
165
* @brief This function handles System tick timer.
166
*/
167
void SysTick_Handler(void)
168
{
169
  /* USER CODE BEGIN SysTick_IRQn 0 */
170
171
  /* USER CODE END SysTick_IRQn 0 */
172
  HAL_IncTick();
173
  HAL_SYSTICK_IRQHandler();
174
  /* USER CODE BEGIN SysTick_IRQn 1 */
175
176
  /* USER CODE END SysTick_IRQn 1 */
177
}
178
179
/******************************************************************************/
180
/* STM32L4xx Peripheral Interrupt Handlers                                    */
181
/* Add here the Interrupt Handlers for the used peripherals.                  */
182
/* For the available peripheral interrupt handler names,                      */
183
/* please refer to the startup file (startup_stm32l4xx.s).                    */
184
/******************************************************************************/
185
186
/* USER CODE BEGIN 1 */
187
188
void EXTI4_IRQHandler (void) {
189
  if (EXTI->PR1 & EXTI_PR1_PIF12) {
190
    EXTI->PR1 = EXTI_PR1_PIF12;
191
    uint32_t ODR = GPIOA->ODR;
192
    GPIOA->BSRR = ((ODR & (1 << 5)) << 16) | ((~ODR) & (1 << 5));
193
  }
194
}
195
196
/* USER CODE END 1 */
197
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

das xxx_it.h
1
/**
2
  ******************************************************************************
3
  * @file    stm32l4xx_it.h
4
  * @brief   This file contains the headers of the interrupt handlers.
5
  ******************************************************************************
6
  *
7
  * COPYRIGHT(c) 2017 STMicroelectronics
8
  *
9
  * Redistribution and use in source and binary forms, with or without modification,
10
  * are permitted provided that the following conditions are met:
11
  *   1. Redistributions of source code must retain the above copyright notice,
12
  *      this list of conditions and the following disclaimer.
13
  *   2. Redistributions in binary form must reproduce the above copyright notice,
14
  *      this list of conditions and the following disclaimer in the documentation
15
  *      and/or other materials provided with the distribution.
16
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
17
  *      may be used to endorse or promote products derived from this software
18
  *      without specific prior written permission.
19
  *
20
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
  *
31
  ******************************************************************************
32
  */
33
34
/* Define to prevent recursive inclusion -------------------------------------*/
35
#ifndef __STM32L4xx_IT_H
36
#define __STM32L4xx_IT_H
37
38
#ifdef __cplusplus
39
 extern "C" {
40
#endif 
41
42
/* Includes ------------------------------------------------------------------*/
43
/* Exported types ------------------------------------------------------------*/
44
/* Exported constants --------------------------------------------------------*/
45
/* Exported macro ------------------------------------------------------------*/
46
/* Exported functions ------------------------------------------------------- */
47
48
void NMI_Handler(void);
49
void HardFault_Handler(void);
50
void MemManage_Handler(void);
51
void BusFault_Handler(void);
52
void UsageFault_Handler(void);
53
void SVC_Handler(void);
54
void DebugMon_Handler(void);
55
void PendSV_Handler(void);
56
void SysTick_Handler(void);
57
void EXTI4_IRQHandler(void);
58
59
#ifdef __cplusplus
60
}
61
#endif
62
63
#endif /* __STM32L4xx_IT_H */
64
65
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

von Dr. Sommer (Gast)


Lesenswert?

Man kann lange Codes hier auch als Datei anhängen... Zeige mal den 
genutzten Startup-Code, ich vermute der Name der ISR für den EXTI ist 
falsch.

von D. I. (Firma: Fa) (buell)


Angehängte Dateien:

Lesenswert?

Dr. Sommer schrieb:
> Man kann lange Codes hier auch als Datei anhängen... Zeige mal den
> genutzten Startup-Code, ich vermute der Name der ISR für den EXTI ist
> falsch.

hab die datei angehängt

von Dr. Sommer (Gast)


Lesenswert?

Ja, die Funktion sollte wohl EXTI15_10_IRQHandler heißen, und nicht 
EXTI4_IRQHandler. Das macht auch überhaupt keinen Sinn fällt mir gerade 
auf ;-)

von D. I. (Firma: Fa) (buell)


Lesenswert?

Ok, was ich nicht verstehe ist, wieso ich dort als User neue Handler 
definieren kann und diese dann eben in der startup datei nicht 
drinstehen?
Bzw. in kann die startup datei ja nicht einfach so modifizieren oder??

von Dr. Sommer (Gast)


Lesenswert?

D. I. schrieb:
> Ok, was ich nicht verstehe ist, wieso ich dort als User neue Handler
> definieren kann und diese dann eben in der startup datei nicht
> drinstehen?
Wenn du einen "Handler" definierst, ist das erstmal nur eine olle 
Funktion die zufällig "_Handler" im Namen hat. Die wird erst dadurch zum 
Interrupt Handler, dass im Startup-Code, genauer im ISR-Vektor, die 
Funktion an der richtigen(!) Stelle mit genau (!) dem Namen aufgelistet 
ist. Dadurch wird ihre Adresse an die richtige Stelle am Anfang des 
Flash eingetragen, sodass der Prozessor sie aufrufen kann.

D. I. schrieb:
> Bzw. in kann die startup datei ja nicht einfach so modifizieren oder??
Du kannst die Funktionen dort umbenennen und dann im Code den Namen 
ebenfalls anpassen, aber das ist wenig sinnvoll. Alles andere (insb. die 
Reihenfolge der Funktionen!) in der Datei ist von der Hardware & 
C-Library vorgegeben und darf nicht geändert werden, bzw. dazu besteht 
auch normalerweise keine Notwendigkeit.

von D. I. (Firma: Fa) (buell)


Lesenswert?

Ok, es funktioniert jetzt. Vielen Dank für deine Hilfe.
Die LED toggelt jetzt, aaaaaber? Sind da Geister am Werk??

Ich bin etwas verwirrt, nämlich die LED toggelt obwohl ich ohne einem 
Signal von aussen mit einem metallischen Kabel dran gehe. Ich meine mit 
dem Kabel floating an den Pin PC12..

Am Oszilloskop sehe ich auch einen peak 3.36V.
Hääää?

von Dr. Sommer (Gast)


Lesenswert?

D. I. schrieb:
> Ich bin etwas verwirrt, nämlich die LED toggelt obwohl ich ohne einem
> Signal von aussen mit einem metallischen Kabel dran gehe.

Willkommen im Land von EMI/EMV... Die offenen (unbeschalteten) Pins sind 
sehr hochohmig, dein Kabel wirkt als Antenne und fängt irgendwelche 
Wellen ein, die vom Controller als Pegelwechsel erkannt werden. Umso 
stärker, wenn du das Kabel anfasst. Pullup/Down-Widerstände helfen u.U.

von D. I. (Firma: Fa) (buell)


Lesenswert?

Dr. Sommer schrieb:
> D. I. schrieb:
>> Ich bin etwas verwirrt, nämlich die LED toggelt obwohl ich ohne einem
>> Signal von aussen mit einem metallischen Kabel dran gehe.
>
> Willkommen im Land von EMI/EMV... Die offenen (unbeschalteten) Pins sind
> sehr hochohmig, dein Kabel wirkt als Antenne und fängt irgendwelche
> Wellen ein, die vom Controller als Pegelwechsel erkannt werden. Umso
> stärker, wenn du das Kabel anfasst. Pullup/Down-Widerstände helfen u.U.

Ahhh ok, aber hat nicht jeder Pin einen internen Pullup drin?
kann ich diesen nicht direkt verwenden??

Ich habe bei PC12 als mode

GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
drin.

Was ist eigentlich das NO_PULL genau.
Das habe ich auch mit Manual nicht verstanden!

von Dr. Sommer (Gast)


Lesenswert?

D. I. schrieb:
> Ahhh ok, aber hat nicht jeder Pin einen internen Pullup drin?
Ja, aber der ist standardmäßig aus. Die STM32 haben sowohl Pullup als 
auch Pulldowns.

D. I. schrieb:
> kann ich diesen nicht direkt verwenden??
Ja sollte.

D. I. schrieb:
> Was ist eigentlich das NO_PULL genau.
Na dass eben keine Pull-Up/Down Widerstände aktiv sind.

Mach z.B.:
1
GPIO_InitStruct.Pull = GPIO_PULLUP;
oder
1
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
je nachdem ob du mit dem Draht gegen - oder + kontaktieren willst.

von D. I. (Firma: Fa) (buell)


Lesenswert?

Dr. Sommer schrieb:
> D. I. schrieb:
>> Ahhh ok, aber hat nicht jeder Pin einen internen Pullup drin?
> Ja, aber der ist standardmäßig aus. Die STM32 haben sowohl Pullup als
> auch Pulldowns.
>
> D. I. schrieb:
>> kann ich diesen nicht direkt verwenden??
> Ja sollte.
>
> D. I. schrieb:
>> Was ist eigentlich das NO_PULL genau.
> Na dass eben keine Pull-Up/Down Widerstände aktiv sind.
>
> Mach z.B.:
>
1
GPIO_InitStruct.Pull = GPIO_PULLUP;
> oder
>
1
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
> je nachdem ob du mit dem Draht gegen - oder + kontaktieren willst.

Ok, ich hab PULLDOWN gewählt, weil neben dem Pin gleich ein VDD anliegt.
So brauch ich nicht mal ein Kabel.
Das funktioniert super so ;P.


Noch eine letzte Frage:

ich möchte jetzt zB eine Funktion void Enable_Counter_Timer1(void);, die 
im main deklariert ist im Interrupt Handler verwenden bzw. einfügen.
Dazu muss ich aber im main.h, den Prototyp erstellen und main.h auch im 
xxx_it.c (Interrupt file) einbinden.

DAs habe ich so gemacht, aber wenn ich zB im CUBEMX etwas anpasse, 
überschreibt es mir das doch dauernd, oder?
Wie kann man das optimal machen?

1
  ******************************************************************************
2
  * @file    stm32l4xx_it.c
3
  * @brief   Interrupt Service Routines.
4
  ******************************************************************************
5
 
6
******************************************************************************
7
  */
8
/* Includes ------------------------------------------------------------------*/
9
#include "stm32l4xx_hal.h"
10
#include "stm32l4xx.h"
11
#include "stm32l4xx_it.h"
12
#include "main.h"
13
14
/* USER CODE BEGIN 0 */
15
16
/* USER CODE END 0 */
17
18
/* External variables --------------------------------------------------------*/
19
20
/******************************************************************************/
21
/*            Cortex-M4 Processor Interruption and Exception Handlers         */ 
22
/******************************************************************************/






1
und im main.h
2
3
/**
4
  ******************************************************************************
5
  * File Name          : main.h
6
  * Description        : This file contains the common defines of the application
7
  ******************************************************************************
8
  *
9
  ******************************************************************************
10
  */
11
/* Define to prevent recursive inclusion -------------------------------------*/
12
#ifndef __MAIN_H
13
#define __MAIN_H
14
  /* Includes ------------------------------------------------------------------*/
15
16
/* USER CODE BEGIN Includes */
17
18
/* USER CODE END Includes */
19
20
/* Private define ------------------------------------------------------------*/
21
22
/* USER CODE BEGIN Private defines */
23
24
/* USER CODE END Private defines */
25
26
void Enable_Counter_Timer1(void);
27
/**
28
  * @}
29
  */ 
30
31
/**
32
  * @}
33
*/ 
34
35
#endif /* __MAIN_H */
36
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

von Dr. Sommer (Gast)


Lesenswert?

D. I. schrieb:
> DAs habe ich so gemacht, aber wenn ich zB im CUBEMX etwas anpasse,
> überschreibt es mir das doch dauernd, oder?
Keine Ahnung was CubeMX macht. Probiers einfach aus. Warum sollte CubeMX 
ständig die Liste der Interrupt Handler ändern?

Du kannst den ganzen Interrupt Handler auch in die main.c packen und die 
andere Datei weglassen...

von D. I. (Firma: Fa) (buell)


Lesenswert?

Dr. Sommer schrieb:
> D. I. schrieb:
>> DAs habe ich so gemacht, aber wenn ich zB im CUBEMX etwas anpasse,
>> überschreibt es mir das doch dauernd, oder?
> Keine Ahnung was CubeMX macht. Probiers einfach aus. Warum sollte CubeMX
> ständig die Liste der Interrupt Handler ändern?
>
> Du kannst den ganzen Interrupt Handler auch in die main.c packen und die
> andere Datei weglassen...


Ok, nochmals vielen Dank für deine Zeit Dr. Sommer.
Hoffe ich habe dich nicht zu lange aufgehalten.
Wünsch dir noch einen schönen Sonntag Abend.

von Dr. Sommer (Gast)


Lesenswert?

D. I. schrieb:
> Ok, nochmals vielen Dank für deine Zeit Dr. Sommer.
> Hoffe ich habe dich nicht zu lange aufgehalten.
> Wünsch dir noch einen schönen Sonntag Abend.
Na immer doch, mir war eh langweilig ;-) Dir noch viel Erfolg!

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.