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?
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)
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.
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.
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?
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
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.
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?
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).
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.
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...
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****/
|
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.
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
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 ;-)
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??
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.
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ääää?
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.
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!
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.
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****/
|
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...
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.