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


von Vincent (Gast)


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


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)


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


Lesenswert?

Dann stimmt da irgendwas grundlegendes nicht.

Was macht die Funktion UART_SendData?

von Vincent (Gast)


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)


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)


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)


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)


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)


Lesenswert?

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

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.