STM32 SPI im IRQ

Gast #4925986
Lesenswert?

Es war soweit, ich wollte auch mmal mit einem LED-Cube spielen. Also 
gegriffen was noch rumlag, 512LEDs, 5 MCP23S17, ein STM32F303 und ne 
Handvoll Hühnerfutter. Nach 'nem Wochenende Löten ging es an die 
Programmierung.

Die Ansteuerung der LEDs funktioniert, ein kompletter Durchlauf braucht 
650µs.

Um ein stabiles Bild zu haben, wollte ich den Anzeige in einen 
Timerinterrupt legen und da häge ich jetzt.
Der Interrupt funktioniert, zum Testen alle 10ms
1
void Timer3_Config(void)
2
{
3
    TIM_TimeBaseInitTypeDef TIM_TimeBase_InitStructure;
4
    NVIC_InitTypeDef NVIC_InitStructure;
5

6
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
7

8
    TIM_TimeBase_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
9
    TIM_TimeBase_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
10
    TIM_TimeBase_InitStructure.TIM_Period = 100;
11
    TIM_TimeBase_InitStructure.TIM_Prescaler = 6400;
12
    TIM_TimeBaseInit(TIM3, &TIM_TimeBase_InitStructure);
13

14
    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
15

16
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
17
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
18
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
19
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
20
    NVIC_Init(&NVIC_InitStructure);
21

22
    TIM_Cmd(TIM3, ENABLE);
23
}
24

25
void TIM3_IRQHandler(void)
26
{
27
  TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
28

29
GPIOB->ODR  ^= GPIO_Pin_3;  // PB3 togglen
30

31

32
}

Sobald ich jetzt im IRQ den SPI-Bus ansprechen will, bleibt jede Abfrage
1
  while (!(SPI1->SR & SPI_SR_TXE)); // Wait while transmit buffer is not empty
oder
1
  while ((SPI1->SR & SPI_SR_BSY)); // Wait while busy
hängen.

Wenn ich das ganze in den Systick verlagere funktioniert es, sobald ich 
länger als 22ms zwischen den Aufrufen warte.
Auch wenn ich den Bildaufbau spaltenweise mache (Dauer etwa 85µs) geht 
es nicht schneller.

Da mich der F3 schon bei ILI9341-Displays geärgert hat, hab ich den mal 
durch einen F103 ersetzt. Hat aber am Verhalten nichts geändert.

Kann mir jemand sagen, was ich übersehe?
Gast #4926371
Lesenswert?

Michael schrieb:
> Da mich der F3 schon bei ILI9341-Displays geärgert hat, hab ich den mal
> durch einen F103 ersetzt. Hat aber am Verhalten nichts geändert.
>
> Kann mir jemand sagen, was ich übersehe?

Häng mal den ganzen Code dran.

Versuche deine Strategie zu überdenken und benutze DMA.
#4927451
Lesenswert?

Michael schrieb:
> Sobald ich jetzt im IRQ den SPI-Bus ansprechen will, bleibt jede Abfrage
> while (!(SPI1->SR & SPI_SR_TXE)); // Wait while transmit buffer is not
> empty
> oder  while ((SPI1->SR & SPI_SR_BSY)); // Wait while busy
> hängen.

Relativ blöde Idee im Interrupt zu warten, auch auf 'nem STM32. Im SPI 
Interrupt ist das Peripherial in einem bekannten Zustand - da brauchts 
keine Wartezeiten.

Schnelles SPI für'n Cube würde ich lieber mit DMA machen.
Gast #4927535
Lesenswert?

Patrick J. schrieb:
> Benötige SPI Interrupts?
Nein, die Daten werden ins Register geschoben, den Rest macht die 
Hardware.

Jim M. schrieb:
> Relativ blöde Idee im Interrupt zu warten, auch auf 'nem STM32. Im SPI
> Interrupt ist das Peripherial in einem bekannten Zustand - da brauchts
> keine Wartezeiten.
Naja, ich kann schlecht neue Daten nachschieben, bevor die alten raus 
sind.
Außerdem liegen die Abstände der IRQ deulich über der Laufzeit, selbst 
mit den Warterunden.

Ich hab jetzt auf DMA umgestellt, ich dachte das sei für die paar Bytes 
alle paar ms nicht nötig.
Mich hätte nur interessiert, warum es im Timer 3 nicht klappt und im 
Systick nur mit langen Pausen.
Aber egal, jetzt geht es an die Effekte.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren