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


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


Bewertung
0 lesenswert
nicht 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)
void UART4_Config( void )
{
  /**
   * UART 4 HW- Initialisieren
   * RX an PC11
   * TX an PC 10
   */

  GPIO_InitTypeDef GPIO_InitDef;  // Initialisiserungsstruktur


  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);  // Enable clock for GPIOC


  GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_UART4); // Alternating function UART4 to PC11 (RX)
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_UART4); // Alternating function UART4 to PC10 (TX)

  // Initialize pins as alternating function
  GPIO_InitDef.GPIO_Pin = GPIO_Pin_10 |GPIO_Pin_11;
  GPIO_InitDef.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitDef.GPIO_OType = GPIO_OType_PP;
  GPIO_InitDef.GPIO_PuPd =  GPIO_PuPd_NOPULL;
  GPIO_InitDef.GPIO_Speed = GPIO_Speed_50MHz;        // Wichtig, da max. 42 MHz für UART

  GPIO_Init(GPIOC, &GPIO_InitDef);  // Initalsierung der HW

    /**
     * UART4 Initialisierung
     * Baudrate: 38400
     * Hardware Flow control: Disable
     * Mode:  RX
     * Parity bit: Even
     * Stop bit: 1
     * Data bits: 8
     */

  USART_InitTypeDef UART4_InitStruct;  // Initialisiserungsstruktur


  RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); // Enable clock for UART4

    UART4_InitStruct.USART_BaudRate = 38400;
    UART4_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    UART4_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
    UART4_InitStruct.USART_Parity = USART_Parity_Even;
    UART4_InitStruct.USART_StopBits = USART_StopBits_1;
    UART4_InitStruct.USART_WordLength = USART_WordLength_8b;

    USART_Init(UART4, &UART4_InitStruct);  // Initalsierung UART

    USART_Cmd(UART4, ENABLE);  // UART freischalten
}

void NVIC_UART4_Config( void )
{
  /**
  * Initialize NVIC (Nested Vector Interrupt Controller)
  * für UART RXNE Flag
  * Höchste Priorität
  */
  NVIC_InitTypeDef NVIC_InitStruct;

  NVIC_InitStruct.NVIC_IRQChannel = UART4_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
    NVIC_Init(&NVIC_InitStruct);

    USART_ITConfig(UART4, USART_IT_LBD | USART_IT_TXE | USART_IT_TC | USART_IT_RXNE |
              USART_IT_IDLE |USART_IT_PE |USART_IT_ERR, DISABLE );  // Alle Quellen deaktiveren

    USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);  // Interrupt für RXNE aktiveren
}

void UART4_IRQHandler( void )
{
  // Check Rx Interrupt
  if(USART_GetITStatus(UART4, USART_IT_RXNE) == SET)
  {
     /* Read one byte from the receive data register */
      RxBuffer[count++] = USART_ReceiveData(UART4);
      countAll++;

      if (count > 100) {count = 0;}
  }


  else
  {
    // Sollte nie angesprungen werden, da alle anderen Interruptquellen für
    // UART4 deaktivert sind
    status = UART4 ->SR;

  }
}

int main(void)
{
  UART4_Config();     // Init HW und SW für UART4

  NVIC_UART4_Config();  // Init NVIC für UART4 RX

  uint16_t txBuffer[] = {0x00FF, 0x00AA, 0x00CC};
  uint8_t i = 0;

    while (1)
    {
      
      USART_SendData(UART4, txBuffer[i++]);

      if (i >2)
      {
        i = 0;
      }

      while((USART_GetFlagStatus(UART4, USART_FLAG_TC)) == RESET) {}

     }
}

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
 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

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

Wichtige Regeln - erst lesen, dann posten!

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

Formatierung (mehr Informationen...)

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




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

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