Forum: Mikrocontroller und Digitale Elektronik STM32 Timer Interrupt unterbricht USART2 beim Senden


von Fun R. (funnyrice)


Lesenswert?

Hallo,

ich mache gerade meine ersten (bis hundertsten) Gehversuche mit dem 
STM32F103VET6 im Primer2. Als IDE benutze ich Ride7.

Unter Verwendung der mitgelieferten Beispielprogramme habe ich bis jetzt 
einen String über USART2 gesendet und eine Timebase über Timer2 
Interrupt am laufen. Nun ja, die ersten Schritte halt.

Beim Versuch USART2 und TimerBase zu kombinieren habe ich festgestellt, 
daß die Timerinterrupts TIM_IT_CC2 bis TIM_IT_CC4 den USART2 beim Senden 
stoppen.

Wenn ich also statt
1
 TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);

einfach
1
 TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);

schreibe, dann werden meine 45 Zeichen gesendet.

Ich kann mir nicht erklären warum das so ist.
Hat jemand einen Tipp?

Hab den Code mal angehangen.


Gruß, Fun Rice


 Interrupt Handler
1
void TIM2_IRQHandler(void)
2
{
3
//GPIO_ResetBits(GPIOA, GPIO_Pin_4); // Achtung Test
4
5
  if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
6
  {
7
  
8
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
9
10
    /* Pin PB.06 toggling with frequency = 73.24 Hz */
11
    GPIO_WriteBit(GPIOB, GPIO_Pin_6, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_6)));
12
    capture = TIM_GetCapture1(TIM2);
13
    TIM_SetCompare1(TIM2, capture + CCR1_Val);
14
  }
15
}

main
1
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
2
* File Name          : main.c
3
* Author             : MCD Application Team
4
* Version            : V2.0.3
5
* Date               : 09/22/2008
6
* Description        : Main program body
7
********************************************************************************
8
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
9
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
10
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
11
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
12
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
13
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
14
*******************************************************************************/
15
16
/* Includes ------------------------------------------------------------------*/
17
#include "stm32f10x_lib.h"
18
#include "stm32f10x_it.h"
19
/* Private typedef -----------------------------------------------------------*/
20
typedef enum { FAILED = 0, PASSED = !FAILED} TestStatus;
21
22
/* Private define ------------------------------------------------------------*/
23
//#define OLD_STM32LIB_USED
24
#define TxBufferSize   (countof(TxBuffer))
25
26
/* Private macro -------------------------------------------------------------*/
27
#define countof(a)   (sizeof(a) / sizeof(*(a)))
28
29
/* Private variables ---------------------------------------------------------*/
30
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
31
TIM_OCInitTypeDef  TIM_OCInitStructure;
32
33
USART_InitTypeDef USART_InitStructure;
34
u8 TxBuffer[] = "Buffer Send from USART2 to USART1 using Flags";
35
u8 RxBuffer[TxBufferSize];
36
u8 TxCounter = 0, RxCounter = 0;  
37
TestStatus TransferStatus = FAILED;  
38
ErrorStatus HSEStartUpStatus;
39
40
//vu16 CCR1_Val = 49152;
41
vu16 CCR1_Val = 480;
42
vu16 CCR2_Val = 32768;
43
vu16 CCR3_Val = 16384;
44
vu16 CCR4_Val = 8192; 
45
46
/* Private function prototypes -----------------------------------------------*/
47
void RCC_Configuration(void);
48
void GPIO_Configuration(void);
49
void NVIC_Configuration(void);
50
void USART_Configuration(void);
51
void TIM2_Configuration(void);
52
TestStatus Buffercmp(u8* pBuffer1, u8* pBuffer2, u16 BufferLength);
53
//u8 index = 0;
54
 
55
56
/* Private functions ---------------------------------------------------------*/
57
58
/*******************************************************************************
59
* Function Name  : main
60
* Description    : Main program
61
* Input          : None
62
* Output         : None
63
* Return         : None
64
*******************************************************************************/
65
int main(void)
66
{
67
#ifdef DEBUG
68
  debug();
69
#endif
70
71
  /* System Clocks Configuration */
72
  RCC_Configuration();
73
       
74
  /* NVIC configuration */
75
  NVIC_Configuration();
76
77
  /* Configure the GPIO ports */
78
  GPIO_Configuration();
79
80
  USART_Configuration();
81
82
  TIM2_Configuration();
83
84
85
  while(TxCounter <= 45)
86
  {   
87
    /* Send one byte from USART1 to USART2 */
88
     USART_SendData(USART2, TxBuffer[TxCounter++]);
89
90
    
91
    /* Loop until USART2 DR register is empty */ 
92
    while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
93
    {
94
    }
95
     
96
  } 
97
98
99
  while (1)
100
  {
101
  }
102
}
103
void TIM2_Configuration(void)
104
{
105
/* ---------------------------------------------------------------
106
    TIM2 Configuration: Output Compare Timing Mode:
107
    TIM2CLK = 36 MHz, Prescaler = 4, TIM2 counter clock = 7.2 MHz
108
    CC1 update rate = TIM2 counter clock / CCR1_Val = 146.48 Hz
109
    CC2 update rate = TIM2 counter clock / CCR2_Val = 219.7 Hz
110
    CC3 update rate = TIM2 counter clock / CCR3_Val = 439.4 Hz
111
    CC4 update rate = TIM2 counter clock / CCR4_Val =  878.9 Hz
112
  --------------------------------------------------------------- */
113
114
  /* Time base configuration */
115
  TIM_TimeBaseStructure.TIM_Period = 65535;
116
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
117
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
118
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
119
120
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
121
122
  /* Prescaler configuration */
123
  TIM_PrescalerConfig(TIM2, 4, TIM_PSCReloadMode_Immediate);
124
125
  /* Output Compare Timing Mode configuration: Channel1 */
126
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
127
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
128
  TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
129
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 
130
131
  TIM_OC1Init(TIM2, &TIM_OCInitStructure);
132
  TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable);
133
  
134
  /* Output Compare Timing Mode configuration: Channel2 */
135
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
136
  TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
137
138
  TIM_OC2Init(TIM2, &TIM_OCInitStructure);
139
140
  TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable);
141
142
  /* Output Compare Timing Mode configuration: Channel3 */
143
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
144
  TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
145
146
  TIM_OC3Init(TIM2, &TIM_OCInitStructure);
147
148
  TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable);
149
150
  /* Output Compare Timing Mode configuration: Channel4 */
151
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
152
  TIM_OCInitStructure.TIM_Pulse = CCR4_Val;
153
154
  TIM_OC4Init(TIM2, &TIM_OCInitStructure);
155
156
  TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Disable);
157
158
  /* TIM IT enable */
159
  TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);
160
161
  /* TIM2 enable counter */
162
  TIM_Cmd(TIM2, ENABLE);
163
164
}
165
/*******************************************************************************
166
* Function Name  : RCC_Configuration
167
* Description    : Configures the different system clocks.
168
* Input          : None
169
* Output         : None
170
* Return         : None
171
*******************************************************************************/
172
void RCC_Configuration(void)
173
{
174
  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration -----------------------------*/   
175
  /* RCC system reset(for debug purpose) */
176
  RCC_DeInit();
177
178
  /* Enable HSE */
179
  RCC_HSEConfig(RCC_HSE_ON);
180
181
  /* Wait till HSE is ready */
182
  HSEStartUpStatus = RCC_WaitForHSEStartUp();
183
184
  if (HSEStartUpStatus == SUCCESS)
185
  {
186
    /* Enable Prefetch Buffer */
187
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
188
189
    /* Flash 2 wait state */
190
    FLASH_SetLatency(FLASH_Latency_2);
191
 
192
    /* HCLK = SYSCLK */
193
    RCC_HCLKConfig(RCC_SYSCLK_Div1); 
194
  
195
    /* PCLK2 = HCLK */
196
    RCC_PCLK2Config(RCC_HCLK_Div1); 
197
198
    /* PCLK1 = HCLK/2 */
199
    RCC_PCLK1Config(RCC_HCLK_Div2);
200
201
    /* PLLCLK = 12MHz * 6 = 72 MHz */
202
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_6);
203
204
    /* Enable PLL */ 
205
    RCC_PLLCmd(ENABLE);
206
207
    /* Wait till PLL is ready */
208
    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
209
    {
210
    }
211
212
    /* Select PLL as system clock source */
213
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
214
215
    /* Wait till PLL is used as system clock source */
216
    while(RCC_GetSYSCLKSource() != 0x08)
217
    {
218
    }
219
  }
220
  else
221
  { /* If HSE fails to start-up, the application will have wrong clock configuration.
222
       User can add here some code to deal with this error */    
223
224
    /* Go to infinite loop */
225
    while (1)
226
    {
227
    }
228
229
230
231
  }
232
233
  /* TIM2 clock enable */
234
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
235
236
  /* GPIOC clock enable */
237
//  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);    
238
239
  /* Enable USART1, GPIOA, GPIOD and AFIO clocks */
240
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 |
241
                         RCC_APB2Periph_GPIOA |
242
                         RCC_APB2Periph_GPIOB |
243
                         RCC_APB2Periph_AFIO, ENABLE);
244
  /* Enable USART2 clock */
245
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
246
}
247
248
/*******************************************************************************
249
* Function Name  : GPIO_Configuration
250
* Description    : Configures the different GPIO ports.
251
* Input          : None
252
* Output         : None
253
* Return         : None
254
*******************************************************************************/
255
void GPIO_Configuration(void)
256
{
257
  GPIO_InitTypeDef GPIO_InitStructure;
258
259
//#ifdef USE_STM3210B_EVAL
260
  /* Enable the USART2 Pins Software Remapping */
261
//  GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
262
//#endif
263
264
  /* Configure USART1 Tx (PA.09) as alternate function push-pull */
265
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
266
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
267
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
268
  GPIO_Init(GPIOA, &GPIO_InitStructure);
269
270
  /* Configure USART2 Tx as alternate function push-pull */
271
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
272
  GPIO_Init(GPIOA, &GPIO_InitStructure);
273
274
  /* Configure USART1 Rx (PA.10) as input floating */
275
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
276
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
277
 // PullUp GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
278
  GPIO_Init(GPIOA, &GPIO_InitStructure);
279
280
  /* Configure USART2 Rx as input floating */
281
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
282
  GPIO_Init(GPIOA, &GPIO_InitStructure);
283
  
284
  
285
  /* Configure (PB.06) as output push-pull */
286
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
287
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
288
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
289
  GPIO_Init(GPIOB, &GPIO_InitStructure);  
290
}
291
292
void USART_Configuration(void)
293
{
294
/* USART1 and USART2 configuration ------------------------------------------------------*/
295
  /* USART and USART2 configured as follow:
296
        - BaudRate = 230400 baud  
297
        - Word Length = 8 Bits
298
        - One Stop Bit
299
        - Even parity
300
        - Hardware flow control disabled (RTS and CTS signals)
301
        - Receive and transmit enabled
302
  */
303
  USART_InitStructure.USART_BaudRate = 9600;
304
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
305
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
306
  USART_InitStructure.USART_Parity = USART_Parity_No;
307
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
308
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
309
  
310
  /* Configure USART1 */
311
  USART_Init(USART1, &USART_InitStructure);
312
  /* Configure USART2 */
313
  USART_Init(USART2, &USART_InitStructure);
314
  
315
  /* Enable the USART1 */
316
  USART_Cmd(USART1, ENABLE);
317
318
  /* Enable the USART2 */
319
  USART_Cmd(USART2, ENABLE);
320
  }
321
322
/*******************************************************************************
323
* Function Name  : NVIC_Configuration
324
* Description    : Configures Vector Table base location.
325
* Input          : None
326
* Output         : None
327
* Return         : None
328
*******************************************************************************/
329
void NVIC_Configuration(void)
330
{  
331
 NVIC_InitTypeDef NVIC_InitStructure;
332
333
#ifdef  VECT_TAB_RAM  
334
  /* Set the Vector Table base location at 0x20000000 */ 
335
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); 
336
#else  /* VECT_TAB_FLASH  */
337
  /* Set the Vector Table base location at 0x08000000 */ 
338
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   
339
#endif
340
341
342
  /* Enable the TIM2 gloabal Interrupt */
343
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;
344
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
345
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
346
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
347
348
  NVIC_Init(&NVIC_InitStructure); 
349
}
350
351
/*******************************************************************************
352
* Function Name  : Buffercmp
353
* Description    : Compares two buffers.
354
* Input          : - pBuffer1, pBuffer2: buffers to be compared.
355
*                : - BufferLength: buffer's length
356
* Output         : None
357
* Return         : PASSED: pBuffer1 identical to pBuffer2
358
*                  FAILED: pBuffer1 differs from pBuffer2
359
*******************************************************************************/
360
TestStatus Buffercmp(u8* pBuffer1, u8* pBuffer2, u16 BufferLength)
361
{
362
  while(BufferLength--)
363
  {
364
    if(*pBuffer1 != *pBuffer2)
365
    {
366
      return FAILED;
367
    }
368
    
369
    pBuffer1++;
370
    pBuffer2++;
371
  }
372
373
  return PASSED;  
374
}
375
376
#ifdef  DEBUG
377
/*******************************************************************************
378
* Function Name  : assert_failed
379
* Description    : Reports the name of the source file and the source line number
380
*                  where the assert_param error has occurred.
381
* Input          : - file: pointer to the source file name
382
*                  - line: assert_param error line source number
383
* Output         : None
384
* Return         : None
385
*******************************************************************************/
386
void assert_failed(u8* file, u32 line)
387
{ 
388
  /* User can add his own implementation to report the file name and line number,
389
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
390
391
  /* Infinite loop */
392
  while (1)
393
  {
394
  }
395
}
396
#endif
397
398
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

von Plan (Gast)


Lesenswert?

In der Interrupt Routine wird auch nur das Bit
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
gelöscht.

Wenn ein anderes Bit den Interrupt auslöst und dieses Bit nicht gelöscht 
wird, so wird automatisch der Interrupt so oft ausgelöst bis das Bit 
gelöscht ist.

Da Du das nicht machst hats Du eine Interrupt-Endlosschleife generiert. 
Mit dem Nebeneffekt dass die Main while Schleife nicht mehr bearbeitet 
wird.

von Fun R. (funnyrice)


Lesenswert?

Hallo Plan,

danke für die schnelle Antwort!

Hört sich sehr plausibel an. Hab´s gleich getestet und jetzt 
funktioniert´s.
Vielen Dank nochmal!

Gruß, Fun Rice

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.