SysTick-Genauigkeit in STM32

Ich habe eine einfache Timing-Prüfung für mein STM32F4-Discovery-Board codiert.

#define IT_PER_SEC 100

int main(void)
{
   if (SysTick_Config(SystemCoreClock / IT_PER_SEC)) 
   {          
      while (1){}; // error
   }

   initGPIO();

   for(;;)
   {
   }

   return 0;
}

void SysTick_Handler(void)
{
   static uint32_t csec  = 0;
   static uint32_t ctime = 0;

   ++csec;
   if(csec == IT_PER_SEC) // every second
   {
      // every second
      GPIO_ToggleBits(GPIOD, GPIO_Pin_12);
      csec = 0;

      // clock
      ++ctime;

      if((ctime % 10) == 0) // every 10 seconds
      {
         GPIO_ToggleBits(GPIOD, GPIO_Pin_13);
      }

      if((ctime % 60) == 0)     // every minute
      {
         GPIO_ToggleBits(GPIOD, GPIO_Pin_14);
      }

      if(ctime == 3600)         // every hour
      {
         GPIO_ToggleBits(GPIOD, GPIO_Pin_15);
         ctime = 0;
      }
   }
}

Dies scheint gut zu funktionieren. Ich habe es mit der Stoppuhr-App auf meinem Android-Handy überprüft. Aber nach einer Stunde und etwas bemerkte ich, dass das LED-Timing etwa eine Sekunde im Voraus war und nach zweieinhalb Stunden bin ich fast bei zwei Sekunden.

Ich schätze, meine App ist hier nicht schuld, oder doch? Der SysTick sollte auch in Ordnung sein, nehme ich an. Also muss es mein Code sein...

Die Schaltpläne sind die Standardschaltpläne des STM32F4 Discovery Boards. Sie sind im Benutzerhandbuch auf Seite 32 zu finden. Dort findet man einen 8-MHz-Quarz zusammen mit den beiden üblichen 20-pF-Kondensatoren.

Könnten Sie den Teil des Schaltplans hochladen oder beschreiben, der den Oszillator (Kristall, Keramikresonator, RC) zeigt, und sicherstellen, für welche Art von Oszillator Ihr Chip konfiguriert ist? Es gibt bereits gute Antworten, die auf dieses Problem hinweisen ...
Die Schaltpläne sind die Standardschaltpläne des STM32F4 Discovery Boards. Sie finden sie im Benutzerhandbuch auf Seite 32:
Gehen Sie nicht davon aus, dass die Uhr auf Ihrem Android-Telefon zuverlässig ist oder dass eine zufällige App eine zuverlässige Uhrquelle im Telefon verwendet. Zum Beispiel sollte eine Uhr, die vom Netzwerk korrigiert wird, nicht für relatives Timing verwendet werden, und in einigen älteren Android-Versionen erhielten sogar Uhren, die nicht korrigiert werden sollten, Korrekturanpassungen. Zurück zur STM-Platine, zusätzlich zu den erwähnten Taktquellenfehlern, ziehen Sie die Möglichkeit verpasster Interrupts in Betracht.

Antworten (5)

Kristalle sind normalerweise viel besser als eine Genauigkeit von 50 ppm ... ABER ... Kristalle haben zwei Resonanzmodi - Serienresonanz und Parallelresonanz (bei einem Impedanzdiagramm sehen Sie, wie die Impedanz bei Parallelresonanz gegen unendlich steigt und bei Serienresonanz gegen Null fällt ).

Wichtig ist nun, dass die beiden Resonanzmoden normalerweise einige hundert PPM voneinander entfernt sind und nur einer von ihnen die markierte Frequenz hat!

Wenn Sie einfach einen "8-MHz"-Quarz kaufen, ohne auf das Kleingedruckte zu achten, erhalten Sie möglicherweise einen Schnitt auf 8 MHz im falschen Modus. und Ihr Oszillator wird mehrere hundert PPM verstimmt sein.

(Die Parallelresonanz ist auch über 50 ppm oder mehr abstimmbar, daher wird sie normalerweise bei einer bestimmten Lastkapazität angegeben).

Man könnte meinen, die meisten professionellen Designer würden mehr Aufmerksamkeit schenken und den richtigen Kristall auswählen – und Sie würden normalerweise Recht haben – aber ich habe sogar einige hochpreisige digitale Audiogeräte gesehen, bei denen dieser Fehler gemacht wurde!

Oder vielleicht hat der Komponenteneinkauf ein "gutes Geschäft" gefunden oder es wurde einfach entschieden, dass für ein Budget-Evaluierungsboard der Preis wichtiger ist als die Genauigkeit des Timings ...

Aber ich vermute trotzdem, dass der Kristall im falschen Modus arbeitet, um einen Frequenzfehler von 300 ppm zu erzeugen.

+1 Für eine gute Vermutung des Problems kann ich mein Discovery-Board später ausgraben und einige Tests am Kristall durchführen. Es ist in der Tat üblich, dass Designer einfach irgendeinen alten Kristall einbauen, ohne Rücksicht auf Antriebspegel, Belastung, Temperatur usw.
Ich bin mir nicht ganz sicher, was ich jetzt prüfen/tun soll
Irgendwie reparieren. Möglicherweise: (1) Verwenden Sie einen externen 8-MHz-Oszillator, (2) finden Sie einen Quarzschnitt, der zum Oszillator passt (da er zu schnell läuft, vermute ich, dass Sie einen auf Serienresonanz abgestimmten benötigen) (3) Verwenden Sie den aktuellen Quarz in der richtigen Resonatortopologie (meine Vermutung ist Parallelresonanz, dh mit dem Kristall als vertikales Element in einem "T"-Netzwerk) oder (4) eine Softwarekorrektur anwenden, dh das Teilungsverhältnis verändern. In etwa aufsteigender Reihenfolge des Schwierigkeitsgrades...
Alternative; Es scheinen 2 Quarzoszillatoren auf der Platine zu sein, und Anweisungen in der Bedienungsanleitung zur Auswahl von einem (oder dem 32768-Hz-Oszillator). Vielleicht ist einer der anderen Oszillatoren gestimmt?

Systick leitet sich vom Prozessortakt ab, der wiederum vermutlich von einem xtal (oder vom internen RC-Oszillator?) stammt.

1 Sekunde Fehler in 1 Stunde ist 1 : 3600 oder 277 ppm. Ein 08/15 xtal ist garantiert auf 50 ppm genau, daher ist es unwahrscheinlich, dass dies nur durch die xtal-Ungenauigkeit verursacht wird.

Sind Sie sicher, dass Ihr Chip auf dem xtal läuft? Die mir bekannten LPC-Chips laufen standardmäßig auf ihrem internen RC-Oszillator, der weitaus ungenauer ist als ein xtal.

Ein weiterer Schuldiger könnte eine falsche Initialisierung sein, sind Sie sicher, dass das richtig gemacht wird?

Nebenbemerkung: Für eine genaue Zeitmessung scheinen 32-kHz-Quarze beliebter zu sein, aber ich sehe keinen auf einem Foto eines STM32F4-Discovery-Boards. Es gibt einen leeren Platz, der mit X3 gekennzeichnet ist, vielleicht ist das für so ein xtal gedacht.

1:86400 wäre 1 Sekunde an einem ganzen Tag. Für eine Stunde würde dies 278 ppm zählen.
Verdammt, Rechenfehler. Ich werde meine Antwort aktualisieren!
Ich verstehe dein Argument. Obwohl ich nicht weiß, was da schief laufen könnte. Die Initialisierung erfolgt automatisch (system_stm32f4xx.c) und dort scheint alles in Ordnung zu sein (HSE-Frequenz (Hz) 8000000, SYSCLK (Hz) 168000000).
Nur nebenbei, ich glaube nicht, dass 32-kHz-Kristalle unbedingt genauer sind, aber Echtzeituhren, die mit dieser niedrigen Frequenz laufen, verbrauchen viel weniger Strom und können mit Knopfzellen betrieben werden.
Abgesehen davon war einer der größten technologischen Fortschritte des 18. Jahrhunderts die Erfindung einer Uhr, die die Zeit über einen Zeitraum von Wochen bei unterschiedlichen Temperaturbedingungen mit einer Genauigkeit anzeigen konnte, die mit einem modernen nicht temperaturkompensierten Kristall vergleichbar war. Elektronik ist für eine gute Zeitmessung nicht erforderlich (obwohl sie eine relativ gute Zeitmessung kostengünstig macht!)

Im Datenblatt des STM32F4 habe ich das gefunden, vielleicht ist es Ihre Antwort:

SysTick-Kalibrierwertregister

Der SysTick-Kalibrierwert ist auf 18750 festgelegt, was eine Referenzzeitbasis von 1 ms ergibt, wenn der SysTick-Takt auf 18,75 MHz eingestellt ist (HCLK/8, wobei HCLK auf 150 MHz eingestellt ist).

Ich glaube, ich sehe nicht, wie dies die Frage beantwortet - wie erklärt dies den offensichtlichen Fehler?

Es hört sich so an, als ob Ihr uC vom HSI-Oszillator läuft - ich habe einen Discovery F4 und ich erinnere mich, dass ich anfangs ein wenig Schwierigkeiten hatte, ihn vom externen Oszillator zum Laufen zu bringen.

Eine einfache Möglichkeit zum Testen besteht darin, den Ausgangspin des externen Oszillators zu prüfen, um festzustellen, ob er läuft.

Wenn Sie einen Blick in die Dokumentation Ihrer Peripheriebibliothek werfen, werden Sie unter CMSIS die Funktionen SystemInitund sehen. SetSysClockIIRC, beim Zurücksetzen besteht das normale Verhalten darin, das HSI zu verwenden, sofern nicht anders definiert. Stellen Sie sicher, dass STD_PERIPH_DRIVER definiert ist, und überprüfen Sie Ihre Datei system_stm32f4xx.c, um sicherzustellen, dass der richtige Oszillator ausgewählt ist. Stellen Sie sicher, dass Ihr HSE_VALUE auch definiert (und auf den richtigen Wert gesetzt) ​​ist.

Stöbern Sie im Grunde in den Setup-Dateien des CMSIS-Systems und in der Dokumentation in der Bibliothek - ich vergesse spontan, was Sie genau einstellen müssen (ich schlafe hier halb und werde sehr bald die andere Hälfte sein ... .), aber es ist alles irgendwo drin (die Codekommentare zeigen Ihnen, wie Sie den richtigen Oszillator einstellen), zum Beispiel haben Sie in der Datei system_stm32f4xx diesen Kommentar ganz oben:

* 5. This file configures the system clock as follows:
  *=============================================================================
  *=============================================================================
  *        Supported STM32F4xx device revision    | Rev A
  *-----------------------------------------------------------------------------
  *        System Clock source                    | PLL (HSE)
  *-----------------------------------------------------------------------------
  *        SYSCLK(Hz)                             | 168000000
  *-----------------------------------------------------------------------------
  *        HCLK(Hz)                               | 168000000
  *-----------------------------------------------------------------------------
  *        AHB Prescaler                          | 1
  *-----------------------------------------------------------------------------
  *        APB1 Prescaler                         | 4
  *-----------------------------------------------------------------------------
  *        APB2 Prescaler                         | 2
  *-----------------------------------------------------------------------------
  *        HSE Frequency(Hz)                      | 25000000
  *-----------------------------------------------------------------------------
  *        PLL_M                                  | 25
  *-----------------------------------------------------------------------------
  *        PLL_N                                  | 336
  *-----------------------------------------------------------------------------
  *        PLL_P                                  | 2
  *-----------------------------------------------------------------------------
  *        PLL_Q                                  | 7
  *-----------------------------------------------------------------------------
  *        PLLI2S_N                               | NA
  *-----------------------------------------------------------------------------
  *        PLLI2S_R                               | NA
  *-----------------------------------------------------------------------------
  *        I2S input clock                        | NA
  *-----------------------------------------------------------------------------
  *        VDD(V)                                 | 3.3
  *-----------------------------------------------------------------------------
  *        High Performance mode                  | Enabled
  *-----------------------------------------------------------------------------
  *        Flash Latency(WS)                      | 5
  *-----------------------------------------------------------------------------
  *        Prefetch Buffer                        | OFF
  *-----------------------------------------------------------------------------
  *        Instruction cache                      | ON
  *-----------------------------------------------------------------------------
  *        Data cache                             | ON
  *-----------------------------------------------------------------------------
  *        Require 48MHz for USB OTG FS,          | Enabled
  *        SDIO and RNG clock                     |
  *----------------------------------------------------------------------------- 
Die ersten sieben Werte sind identisch mit meinen. Meine HSE-Frequenz ist auf 8000000 eingestellt, was für das Discovery-Board in Ordnung sein sollte, denke ich. Andererseits bin ich in dieser Hinsicht kein Experte..

Es gibt ein paar Möglichkeiten, die HSI-Uhr realistischer zu kalibrieren, indem Sie 50 Hz oder RTC verwenden. Die ST-Appnote ist hier .

Zählen Sie grundsätzlich sowohl mit Systick als auch mit RTC auf eine Sekunde und teilen Sie die Hardware mit den HSITRIM-Bits auf.