Ich versuche, einen Interrupt zu schreiben, um die Grundzeit in Ticks auf einem STM32F407VGT (Discovery Board) zu messen.
Mein Interrupt scheint einmal zu laufen (obwohl ich nicht sicher sein kann), aber dann stürzt es ab / blockiert den Prozessor vollständig. Alle UART-Ausgaben werden gestoppt ...
Der Code ist im Wesentlichen derselbe wie in „The Definitive Guide to the ARM Cortex-M3, 2nd ed“. (Joseph Yiu, Newnes.) Könnte die Tatsache, dass der STM32F4xx ein ARM Cortex-M4 ist, ein Problem sein? Wenn ja, wie behebe ich das? Ich habe anfangs versucht, TMR2 mit ähnlichen Problemen zu verwenden, was mich denken lässt, dass es etwas ist, das mir fehlt. Ich habe auch versucht, SysTickConfig zu verwenden, mit den gleichen Problemen.
uint32_t ticks;
void SysTickAlarm(void)
{
SysTick->CTRL = 0;
SCB->ICSR = SCB->ICSR & 0xFDFFFFFF;
ticks++;
return;
}
/*
* Initialise system timer
*/
void tick_init(void)
{
ticks = 0;
*((volatile unsigned int*)(SCB->VTOR + (15 << 2))) = (unsigned int) SysTickAlarm;
SysTick->CTRL = 0; // Disable SysTick
SysTick->LOAD = TICK_DELAY; // Delay for 10 ms
SysTick->VAL = 0; // Clear current value to 0
SysTick->CTRL = 0x7; // Enable SysTick+exception and use processor clock
}
/*
* get_ticks: Get the number of ticks since processor initialisation.
*/
uint32_t get_ticks()
{
return ticks;
}
printf("ticks=%d\n", get_ticks());
main() ruft tick_init() auf und beginnt dann in einer Schleife auszuspucken . Aber es stoppt ziemlich schnell, ich bekomme ungefähr 10 Zeilen, bevor es abstürzt.
Ich bin sehr neu bei ARM-Prozessoren, also ist es wahrscheinlich etwas sehr Einfaches, aber ich kann es nicht sehen.
Sie haben sich selbst ein ziemliches Problem geschaffen, indem Sie die Standard-Peripheriebibliothek (SPL) aufgegeben haben. Dieser Mikrocontroller ist schwer genug, damit zu lernen, geschweige denn ohne. Die Bibliothek mag schrecklich gestaltet sein, aber sie hat den Vorteil, dass sie tatsächlich funktioniert. Ich schlage vor, dass Sie zuerst ein einfaches Testprogramm mit SPL zum Laufen bringen und dann seine Funktionalität schrittweise neu implementieren, wenn Sie es wirklich nicht verwenden können (ich sehe jedoch noch keinen technischen Grund dafür).
Um einen Interrupt in einem Cortex-M3/M4 zu verwenden, benötigen Sie Folgendes:
SCB->VTOR
Register. Standardmäßig ist es 0, was (wiederum standardmäßig) der Beginn des Flashs ist. Wenn Ihre Kombination aus Startcode und Linker-Skript die Vektortabelle korrekt einrichtet, großartig. Das macht die SPL. Sie scheinen es nicht zu tun (es sei denn, es steht in dem Code, den Sie nicht gepostet haben). Sehen Sie sich an, wie es in der Standard-Peripheriebibliothek ( startup_stm32f4xx.s
und dem entsprechenden Linker-Skript für eine gcc-basierte Toolchain) gemacht wird.NVIC->ISER[x]
und NVIC->IPR[x]
registriert. Siehe Implementierung von NVIC_Init()
in SPL und PM00214 , Abschnitt 4.3.Wenn Sie alles überprüft haben und es immer noch nicht zum Laufen bringen können, ist es am besten, ein vollständiges (aber minimales) Projekt zur Analyse zu veröffentlichen.
rmw_mask32(&GPIOB->MODER, 3, 1);
von meiner rmw_mask32
Routine auszuführen GPIOB->MODER = (GPIOB->MODER & ~3) | 1
, aber LDREX/STREX zu verwenden, um Interrupt-sicher zu sein). Gibt es eine nette, leicht durchsuchbare Dokumentation, die sagt, wie man die SPL für einen solchen Zweck verwendet?
Al Bennett
Thomas o
Dorn
Thomas o
*((volatile unsigned int*)(SCB->VTOR + (15 << 2))) = (unsigned int) SysTickAlarm;
dafür ist der da, bin mir aber nicht sicher.Dorn
Thomas o