Forum: Mikrocontroller und Digitale Elektronik STM32F1 printf auf non blocking konfigurieren?


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 Vincent (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich programmiere einen STM32F1 µController. Fürs printf benutze ich das 
https://github.com/cjlano/tinyprintf Bibliothek .

Ich habe den tinyprintf folgendermaßen konfiguriert.
1
init_printf(NULL, myputc);
2
3
void myputc(void* p, char c) {
4
  UNUSED(p);
5
  while ((USART3->SR & USART_FLAG_TC) == (uint16_t) RESET) {
6
  }
7
  USART_SendData(USART3, c);
8
}

Es funktioniert zwar wunderbar. Aber, wenn eine zeitkritische Aufgabe in 
ISR mit hohem Takt ca. 10kHz erledigt werden soll, wobei zeitgleich 
printf in der Mainschleife aufgerufen wird, wird diese ISR Funktion 
durch printf gestört. Ab und zu blockiert der printf die ISR Funktionen.

Weiß jemand zufällig wie man das lösen kann.

Viele Grüße aus Emmen.

von Rufus Τ. F. (rufus) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Vincent schrieb:
> wird diese ISR Funktion durch printf gestört.

Was soll da der Wirkmechanismus sein?

Wird in der ISR auch auf UART3 zugegriffen?

von Vincent (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Rufus Τ. F. schrieb:
> Vincent schrieb:
>> wird diese ISR Funktion durch printf gestört.
>
> Was soll da der Wirkmechanismus sein?
>
> Wird in der ISR auch auf UART3 zugegriffen?

Ne, In der ISR werden Hallsensor-Zustände eines BLDC Motors und 
Strommessung sowie einen Drehzahl-Regelkreis betrieben. Wenn der printf 
in der Mainschleife aufgerufen wird, wird der Regelkreis-Taktzyklus 
unterbrochen.

von Rufus Τ. F. (rufus) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Dann stimmt da irgendwas grundlegendes nicht.

Was macht die Funktion UART_SendData?

von Vincent (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Rufus Τ. F. schrieb:
> Dann stimmt da irgendwas grundlegendes nicht.
>
> Was macht die Funktion UART_SendData?

der macht:
1
/**
2
  * @brief  Transmits single data through the USARTx peripheral.
3
  * @param  USARTx: Select the USART or the UART peripheral. 
4
  *   This parameter can be one of the following values:
5
  *   USART1, USART2, USART3, UART4 or UART5.
6
  * @param  Data: the data to transmit.
7
  * @retval None
8
  */
9
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
10
{
11
  /* Check the parameters */
12
  assert_param(IS_USART_ALL_PERIPH(USARTx));
13
  assert_param(IS_USART_DATA(Data)); 
14
    
15
  /* Transmit Data */
16
  USARTx->DR = (Data & (uint16_t)0x01FF);
17
}

von Nop (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Also so, wie das hier gemacht ist, blockiert das printf keine 
Interrupts. Man müßte sich jetzt aber auch nochmal die Initialisierung 
des USART angucken, nicht daß da noch irgendwo irrtümlich ein Interrupt 
z.B. für "TX done" eingerichtet wurde. Oder für den RX-Zweig ein 
Interrupt. Also, gehen würde es dann immer noch, aber man müßte die 
Interruptprios dann schon richtig setzen.

Kannst ja mal spaßeshalber den Aufruf der send-usart-Routine 
auskommentieren und gucken, ob es dann geht.

Und was findet denn außer printf noch so in der Mainschleife statt?

von Vincent (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Nop schrieb:
> Also so, wie das hier gemacht ist, blockiert das printf keine
> Interrupts. Man müßte sich jetzt aber auch nochmal die Initialisierung
> des USART angucken, nicht daß da noch irgendwo irrtümlich ein Interrupt
> z.B. für "TX done" eingerichtet wurde. Oder für den RX-Zweig ein
> Interrupt. Also, gehen würde es dann immer noch, aber man müßte die
> Interruptprios dann schon richtig setzen.
>
> Kannst ja mal spaßeshalber den Aufruf der send-usart-Routine
> auskommentieren und gucken, ob es dann geht.
auskommentiert, es läuft.

> Und was findet denn außer printf noch so in der Mainschleife statt?
Led togglen und noch Delay(100ms)

Ich hab die ISR Prioritäten alles auf 0 gesetzt, keine Verbesserung.
die UART NVIC Initialisierung:
1
void USART_Configuration(void) {
2
  USART_InitTypeDef USART_InitStructure;
3
4
  USART_InitStructure.USART_BaudRate = 115200;
5
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
6
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
7
  USART_InitStructure.USART_Parity = USART_Parity_No;
8
  USART_InitStructure.USART_HardwareFlowControl =
9
  USART_HardwareFlowControl_None;
10
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
11
12
  /* Configure USART3 */
13
  USART_Init(USART3, &USART_InitStructure);
14
  USART_Cmd(USART3, ENABLE);
15
}
16
17
void NVIC_Configuration(void) {
18
  NVIC_InitTypeDef NVIC_InitStructure;
19
20
  NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
21
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
22
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
23
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
24
  NVIC_Init(&NVIC_InitStructure);
25
26
  /* Configure and enable ADC interrupt */
27
  NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
28
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
29
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
30
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
31
  NVIC_Init(&NVIC_InitStructure);
32
}
33
34
void EXTI15_10_IRQHandler(void) {
35
  if (EXTI_GetITStatus(EXTI_Line10) != RESET) {
36
    /* Clear interrupt flag */
37
    EXTI_ClearITPendingBit(EXTI_Line10);
38
39
    HallIRQ_L();
40
  }
41
  if (EXTI_GetITStatus(EXTI_Line11) != RESET) {
42
    /* Clear interrupt flag */
43
    EXTI_ClearITPendingBit(EXTI_Line11);
44
45
    HallIRQ_L();
46
  }
47
  if (EXTI_GetITStatus(EXTI_Line12) != RESET) {
48
    /* Clear interrupt flag */
49
    EXTI_ClearITPendingBit(EXTI_Line12);
50
51
    HallIRQ_L();
52
  }
53
54
}
55
56
void ADC1_2_IRQHandler(void) {
57
  GPIOA->ODR ^= GPIO_Pin_2;
58
  /* Clear ADC1 JEOC pending interrupt bit */
59
  ADC_ClearITPendingBit(ADC1, ADC_IT_JEOC);
60
61
  ControlLoop();
62
63
  GPIOA->ODR ^= GPIO_Pin_2;
64
65
}

von pegel (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Vincent schrieb:
> wenn eine zeitkritische Aufgabe in
> ISR mit hohem Takt ca. 10kHz

Meinst du den ADC?
Setz doch dessen Priorität mal höher.

von Vincent (Gast)


Bewertung
0 lesenswert
nicht lesenswert
pegel schrieb:
> Vincent schrieb:
>> wenn eine zeitkritische Aufgabe in
>> ISR mit hohem Takt ca. 10kHz
>
> Meinst du den ADC?
Ja,
> Setz doch dessen Priorität mal höher.

ich habe die beiden (Preemption, Sub) Prioritäten auf 0x01. Keine 
Änderung.

von pegel (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hast du auch den Takt auf max. gesetzt?
Nicht das er es einfach nicht schafft.

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]
  • [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.