Forum: Mikrocontroller und Digitale Elektronik STM32F4 UART Rx Interrupt deaktivierte Quellen


von K. K. (caga001)


Lesenswert?

Hallo zusammen,

ich verwende ein STM3240-EVAL mit der System Workbench for STM32 IDE.
Ich möchte über UART4 Zeichen senden und per Interrupt empfangen und 
verarbeiten.


Ich habe dazu folgenden Code erarbeitet:

Die SystemClock und für die Peripherie wird beim Startup eingestellt: 
SYSCLK auf 168 MHz abgeleitet von HSI mit 16 MHz über PLL_M 16 PLL_N 336 
PLL_P 2 PLL_Q 7 (berechnet mit der Excel-datei von STM)
1
void UART4_Config( void )
2
{
3
  /**
4
   * UART 4 HW- Initialisieren
5
   * RX an PC11
6
   * TX an PC 10
7
   */
8
9
  GPIO_InitTypeDef GPIO_InitDef;  // Initialisiserungsstruktur
10
11
12
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);  // Enable clock for GPIOC
13
14
15
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_UART4); // Alternating function UART4 to PC11 (RX)
16
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_UART4); // Alternating function UART4 to PC10 (TX)
17
18
  // Initialize pins as alternating function
19
  GPIO_InitDef.GPIO_Pin = GPIO_Pin_10 |GPIO_Pin_11;
20
  GPIO_InitDef.GPIO_Mode = GPIO_Mode_AF;
21
  GPIO_InitDef.GPIO_OType = GPIO_OType_PP;
22
  GPIO_InitDef.GPIO_PuPd =  GPIO_PuPd_NOPULL;
23
  GPIO_InitDef.GPIO_Speed = GPIO_Speed_50MHz;        // Wichtig, da max. 42 MHz für UART
24
25
  GPIO_Init(GPIOC, &GPIO_InitDef);  // Initalsierung der HW
26
27
    /**
28
     * UART4 Initialisierung
29
     * Baudrate: 38400
30
     * Hardware Flow control: Disable
31
     * Mode:  RX
32
     * Parity bit: Even
33
     * Stop bit: 1
34
     * Data bits: 8
35
     */
36
37
  USART_InitTypeDef UART4_InitStruct;  // Initialisiserungsstruktur
38
39
40
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); // Enable clock for UART4
41
42
    UART4_InitStruct.USART_BaudRate = 38400;
43
    UART4_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
44
    UART4_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
45
    UART4_InitStruct.USART_Parity = USART_Parity_Even;
46
    UART4_InitStruct.USART_StopBits = USART_StopBits_1;
47
    UART4_InitStruct.USART_WordLength = USART_WordLength_8b;
48
49
    USART_Init(UART4, &UART4_InitStruct);  // Initalsierung UART
50
51
    USART_Cmd(UART4, ENABLE);  // UART freischalten
52
}
53
54
void NVIC_UART4_Config( void )
55
{
56
  /**
57
  * Initialize NVIC (Nested Vector Interrupt Controller)
58
  * für UART RXNE Flag
59
  * Höchste Priorität
60
  */
61
  NVIC_InitTypeDef NVIC_InitStruct;
62
63
  NVIC_InitStruct.NVIC_IRQChannel = UART4_IRQn;
64
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
65
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
66
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
67
    NVIC_Init(&NVIC_InitStruct);
68
69
    USART_ITConfig(UART4, USART_IT_LBD | USART_IT_TXE | USART_IT_TC | USART_IT_RXNE |
70
              USART_IT_IDLE |USART_IT_PE |USART_IT_ERR, DISABLE );  // Alle Quellen deaktiveren
71
72
    USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);  // Interrupt für RXNE aktiveren
73
}
74
75
void UART4_IRQHandler( void )
76
{
77
  // Check Rx Interrupt
78
  if(USART_GetITStatus(UART4, USART_IT_RXNE) == SET)
79
  {
80
     /* Read one byte from the receive data register */
81
      RxBuffer[count++] = USART_ReceiveData(UART4);
82
      countAll++;
83
84
      if (count > 100) {count = 0;}
85
  }
86
87
88
  else
89
  {
90
    // Sollte nie angesprungen werden, da alle anderen Interruptquellen für
91
    // UART4 deaktivert sind
92
    status = UART4 ->SR;
93
94
  }
95
}
96
97
int main(void)
98
{
99
  UART4_Config();     // Init HW und SW für UART4
100
101
  NVIC_UART4_Config();  // Init NVIC für UART4 RX
102
103
  uint16_t txBuffer[] = {0x00FF, 0x00AA, 0x00CC};
104
  uint8_t i = 0;
105
106
    while (1)
107
    {
108
      
109
      USART_SendData(UART4, txBuffer[i++]);
110
111
      if (i >2)
112
      {
113
        i = 0;
114
      }
115
116
      while((USART_GetFlagStatus(UART4, USART_FLAG_TC)) == RESET) {}
117
118
     }
119
}

Wenn ich den Code ohne Breakpoints im Debugger laufen lasse funktioniert 
alles, beim Anhalten kann ich mir den gefüllten RxBuffer angucken.

Unerklärlich wird es für mich, wenn ich Breakpoints in die 
UART4_IRQHandler setzte.

Bei einem Breakpoint an
1
 if(USART_GetITStatus(UART4, USART_IT_RXNE) == SET)
 wird die isr auch aufgerufen obwohl RXNE nicht gesetzt ist, somit wird 
die else Anweisung ausgeführt.
Dieses dürfte jedoch nie passieren, weil ich alle anderen Quellen vorher 
deaktiviert habe.

Bei nur einer aktivierten Quelle für die Isr, sollte theoretisch die 
If-Anweisung auch überflüssig sein oder?

Sind euch Probleme mit dem Debugger bekannt oder ist es ein Denk-/ 
Programmierfehler?

Danke für die Hilfe!

von Jim M. (turboj)


Lesenswert?

Lass Dir mal das (Dis)Assembler anzeigen.

Bei den kurzen IT Blöcken kann der Debugger anhalten, obwohl die 
Bedinung der Instruktion nicht erfüllt ist. Ein Spezialfall bei Cortex 
M.

von K. K. (caga001)


Lesenswert?

Werde ich ausprobieren.

Woher kennt man diese Spezialfälle? Gibt es da was zum Nachlesen? Kann 
man das umgehen? Ist ja zum Debuggen nicht gerade hilfreich.

Ich habe auch  beim Debuggen im Einzelschritt festgestellt, dass die 
Anweisungen nicht immer nach der Reihe abgearbeitet werden, sondern der 
Debugger seltsam hin- und herspringt. Gehört das auch zu diesen 
Spezialfällen?

von Jim M. (turboj)


Lesenswert?

Carsten G. schrieb:
> Ich habe auch  beim Debuggen im Einzelschritt festgestellt, dass die
> Anweisungen nicht immer nach der Reihe abgearbeitet werden, sondern der
> Debugger seltsam hin- und herspringt. Gehört das auch zu diesen
> Spezialfällen?

Nö. Das ist der Optimizer im C Compiler.
Den kann man auch mal abschalten zum Debuggen, das maskiert aber einige 
Fehlertypen.

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.