Forum: Mikrocontroller und Digitale Elektronik STM32F4 Timer Synchronisation


von Leon L. (leonelf)


Lesenswert?

Hi!
Ichz versuche momentan, mit einem STM32F4Discovery Board (STM32F407VGT) 
einen TLC5940 anzusteuern. Der IC benötigt für PWM einen referenztakt 
und der counter muss alle 4096 Takte genullt werden. Dazu möchte ich 
TIM1 im PWM Mode nutzen (50% duty), um das Taktsignal zu geben und als 
Master für den als Slave konfigurierten TIM2, der alle 4096 Takte einen 
Interrupt auslöst, den "blank" pin (resettet counter) high und low legt 
und neue daten reinschaufelt.

Das problem ist, dass der TIM2 interrupt ganz am anfang einmal 
aufgerufen wird und danach nie wieder.

Mein code für die Timer Konfiguration:
1
RCC->APB1ENR |= RCC_APB1Periph_TIM2;
2
RCC->APB2ENR |= RCC_APB2Periph_TIM1;
3
4
TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
5
TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Reset);
6
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_External1);
7
TIM_SelectInputTrigger(TIM2, TIM_TS_ITR0);
8
9
TIM_TimeBaseInitTypeDef timerInitStructure;
10
timerInitStructure.TIM_Prescaler = 2 - 1;
11
timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
12
timerInitStructure.TIM_Period = 4 - 1;
13
timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
14
timerInitStructure.TIM_RepetitionCounter = 0;
15
TIM_TimeBaseInit(TIM1, &timerInitStructure);
16
17
timerInitStructure.TIM_Prescaler = 2 - 1;
18
timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
19
timerInitStructure.TIM_Period = 2048 - 1;
20
timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
21
timerInitStructure.TIM_RepetitionCounter = 0;
22
TIM_TimeBaseInit(TIM2, &timerInitStructure);
23
24
NVIC_InitTypeDef nvicStructure;
25
nvicStructure.NVIC_IRQChannel = TIM2_IRQn;
26
nvicStructure.NVIC_IRQChannelPreemptionPriority = 0;
27
nvicStructure.NVIC_IRQChannelSubPriority = 1;
28
nvicStructure.NVIC_IRQChannelCmd = ENABLE;
29
NVIC_Init(&nvicStructure);
30
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
31
32
TIM_OCInitTypeDef ocInitStruct;
33
ocInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
34
ocInitStruct.TIM_OutputState = TIM_OutputState_Enable;
35
ocInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low;
36
ocInitStruct.TIM_Pulse = 2;
37
TIM_OC1Init(TIM1, &ocInitStruct);
38
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
39
40
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1);
41
TIM_Cmd(TIM1, ENABLE);
42
TIM_Cmd(TIM2, ENABLE);

Was habe ich hier falsch gemacht?
Der Internal Trigger 0 wird benutzt, weil ich den in einer der ITR 
tabellen im referenzblatt gefunden habe (also mit TIM1 als Master und 2 
als Slave)

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Leon Loeser schrieb:
> Was habe ich hier falsch gemacht?

Du hast den ISR Code nicht gepostet. Wenn der Interrupt nur einmal 
zündet und dann nie wieder, liegt das oft am nicht-löschen des 
anfordernden IT Flags.

von Leon L. (leonelf)


Lesenswert?

1
void TIM2_IRQHandler()
2
{
3
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
4
    {
5
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
6
    GPIO_SetBits(BLANK_Port, BLANK_Pin);
7
    GPIO_ResetBits(BLANK_Port, BLANK_Pin);
8
    }
9
}

EDIT:
Durch analyse mit breakpoints hat sich übrigends gezeigt, dass der 
Interrupt einmalig ausgeführt wird, bevor die Timer überhaupt 
initialisiert wurden (und dann nie wieder).

: Bearbeitet durch User
von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Läuft denn die PWM von TIM1? Solange das nicht klappt, brauchst du ja 
mit dem Slave gar nicht anfangen. Mir fehlt noch die Peripheral Clock 
Freigabe für PortA, aber es kann sein, das du die in einem anderen 
Programmteil hast.

Offensichtliche Fehler finde ich nicht, du hast allerdings eine hohe 
Priorität für den TIM2 Kanal, mit der ich nicht so glücklich wäre. 
Sollte aber je nach SysTick Konf kein Problem sein.

von Leon L. (leonelf)


Lesenswert?

PWM kam auch nicht raus.
Jetzt habe ich mit
1
TIM_CtrlPWMOutputs(TIM1, ENABLE);
das output aktivieren können (wusste garnicht, dass man das extra machen 
muss...), habe also 21MHz auf A8, aber der interrupt wird laut 
breakpoint trotzdem nicht aufgerufen...

: Bearbeitet durch User
von Leon L. (leonelf)


Lesenswert?

ok, ich habe jetzt die master outputsource durch "update" ersetzt und 
nun wird tim2 auch getriggert. Ich werde mal nachsehn, wie sich der 
timer mit update verhält (bei jedem tim1 tick? oder auch bei overflow?), 
aber das mach ich sobald mein oszilloskop ankommt^^

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.