STM32F1 hat Probleme mit einem Timer

Ich habe einige Probleme beim Einrichten eines 1-Sekunden-Timers auf der STM32F103-MCU.

Ich habe Timer 2 auf einen Prescaler von 1099 und eine Periode von 65514 eingestellt, also erwarte ich eine Interrupt-Rate von 1 Sekunde: 72MHz/1099/65514 = 1Hz.

In Wirklichkeit bekomme ich jedoch den ersten Interrupt, bevor ich die Timer-Konfigurationsroutine abgeschlossen habe (im Moment keine große Sorge), der nächste Interrupt tritt wie erwartet nach 1000 ms auf, der nächste Interrupt tritt nach 322 ms auf und der nächste nach 32 ms und der nächste nach 590ms. (Diese wurden gemäß dem Systick-Timer gemessen, den ich mit 1 ms laufen lasse).

Es scheint ziemlich willkürlich, was ist los?

Hier ist ein Teil des relevanten Codes:

void RCC_Configuration() {
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA |
                        RCC_APB2Periph_GPIOB |
                        RCC_APB2Periph_AFIO  |
                        RCC_APB2Periph_USART1, ENABLE);

RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3 |
                        RCC_APB1Periph_TIM2, ENABLE);
}

void Timer2_4_5_Configuration() {
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Prescaler = (1099-1);
TIM_TimeBaseStructure.TIM_Period = (65514-1);


TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

TIM_Cmd(TIM2, ENABLE);
}

void NVIC_Configuration () {
NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);
}

void TIM2_IRQHandler() {
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
GPIOA->ODR ^= GPIO_Pin_2;
}

BEARBEITEN: Ich habe es geschafft, dies zum Laufen zu bringen, ich habe im Rest meines Codes einen dummen Fehler gemacht. Ich habe den gleichen Pin für etwas anderes verwendet und vergessen, die Zeile zu kommentieren, oops.

Die LED an Pin 2 schaltet wie beabsichtigt mit 1 Hz um, aber es stellt sich eine neue Frage:

Ich habe einen Haltepunkt an der Pin-Toggle-Leitung im TIM-Interrupt-Handler gesetzt und es scheint, dass er wie oben angegeben zu zufälligen Zeiten ausgelöst wird. Aber wenn ich den Haltepunkt entferne, schaltet die LED wie beabsichtigt um.

Was ist los ?

PS - Ich verwende CooCox IDE.

Ist Ihre PLL betriebsbereit, bevor Sie mit der Konfiguration des Timers beginnen? Haben Sie gültige Teiler für AHB-, APB- und Flash-Uhren? Abgesehen davon würde ich die ARR- und PSC-Register überprüfen, ob sie nicht versehentlich überschrieben sind.
Ich bin mir ziemlich sicher, dass der Startcode das abgedeckt hat. Ich habe die ARR- und PSC-Register überprüft und sie haben den erforderlichen Wert.
Funktioniert Ihr Code im Simulator?
Ich verwende Coocox IDE, es hat keinen eingebauten Simulator. Hast du eine Empfehlung für einen?
@Mike - hattest du jemals einen Timer, der an diesem Board gearbeitet hat?
Ja, ich habe Timer 3, der etwas PWM mit 3 Kanälen macht. Ich glaube, ich habe das Problem gefunden, aber das führt mich zu einer neuen Frage. Ich werde die Fragen bearbeiten.
Möglicherweise möchten Sie den Timer bei CPU-Halt stoppen, er wird in DBG->DBGMCU_CR festgelegt.
Das war es @venny ! Danke ! Vielleicht möchten Sie das in einer Antwort formulieren.

Antworten (1)

Wenn ein Debugger die Programmausführung manuell oder durch Erreichen eines Haltepunkts stoppt, friert er den Cortex-M-Kern (einschließlich des System-Tick-Zählers) ein, während der Rest des Systems weiterläuft.

Peripheriegeräte zählen weiter, lesen und schreiben in Speicher und IOs und setzen Interrupt-Flags. Die Flags sammeln sich an und sobald der Prozessor wieder aufgenommen wird, beginnt er, sie zu bedienen.

Die meisten Peripheriegeräte können so eingestellt werden, dass sie ausgesetzt werden, wenn die CPU ausgesetzt wird. Dies ist nützlich, wenn ein Programmeingriff erforderlich ist, um die korrekte Funktion aufrechtzuerhalten. Standardmäßig werden sie vom Debugger normalerweise nicht beeinflusst, obwohl es Ausnahmen gibt (Freescale FTM-Timer, der standardmäßig stoppt).

STM32F1-MCUs haben ein dediziertes Register zum Einstellen des Debug-Verhaltens von Peripheriegeräten, DBG->DBGMCU_CR.