Forum: Mikrocontroller und Digitale Elektronik STM32 SPI im IRQ


von Michael (Gast)


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?

von aSma>> (Gast)


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.

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

Hi

Benötige SPI Interrupts?
Dann könnte hier der Fall sein, da Du bereits in einer ISR bist, daß 
keine weiteren Interrupts gerade zugelassen sind und Dein Kommando 
wartet (vergeblich) auf die Interrupt-Antwort der ISP-Routine.

Reiner Hüftschuß

MfG

von Jim M. (turboj)


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.

von Michael (Gast)


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.

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.