STM32 Systicktimer wert in ms

Gast #2815329
Lesenswert?

Hallo,

ich würde gerne eine Variable mit dem aktuellen Systicktimer Wert 
versehen, welchen ich über die UART versenden mag.

Irgendwie so:
1
int Ticker =0;
2
Ticker = SysTick;
3

4

5
printf("Laufzeit: %i", Ticker);

Sinn und Zweck, ich moechte gerne ueber die UART die Laufzeit des uC 
versenden, zu einem Sensormesswert.

am ende schaut das so aus:

Sample, Sampletime, Messwert1, Messwert2  ..

Habt ihr eine Idee?

Gruss
Marcel
Gast #2815462
Lesenswert?

Marcel schrieb:
> Und was gibts da fuer moeglichkeiten, diesen vor einem ueberlauf zu
> schuetzen ?
Du könntest dir einen eigenen Zähler bauen, der zaehlt wie oft der 
Systick übergelaufen ist. Du musst dann nur innerhalb von 50 Tagen 
zweimal den Systick abrufen.
Gast #2815473
Lesenswert?

>> Und was gibts da fuer moeglichkeiten, diesen vor einem ueberlauf zu
>> schuetzen ?
>Du könntest dir einen eigenen Zähler bauen, der zaehlt wie oft der
>Systick übergelaufen ist. Du musst dann nur innerhalb von 50 Tagen
>zweimal den Systick abrufen.

Falsch. Der Systick selber hat nur 24Bit. Der wird benutzt
um einen 1ms Interrupt zu erzeugen. Dort zählst du eine
Variable im 1ms Takt hoch. Wenn 50 Tage zu wenig sind
zählt man halt wenn diese Variable 1000 erreicht hat eine
zweite Variable hoch und setzt die erste auf Null.
Gast #2815496
Lesenswert?

ich hab jetzt folgendes gemacht.

in main eine

volatile int32_t mtime=0;

erstellt und im stm32f10x_it.c im Systick_handler eine funktion erstellt 
die mein mtime hochzaehlt :
1
void SysTick_Handler(void)
2
{
3
  TimValAdd();  
4
}
5

6

7
void TimValAdd(){
8
  
9
  mtime++;
10
  
11
  }

Nur wann passiert der Interrupt denn immer? bzw ist mtime in ms oder us 
?

Ich hab folgendes konfiguriert:
1
  /* Configure HCLK clock as SysTick clock source. */
2
  SysTick_CLKSourceConfig( SysTick_CLKSource_HCLK );
3

4
  /* set SysTick */
5
  SystemCoreClockUpdate();
6
  
7
  SysTick_Config(SystemCoreClock / 100);     /* Generate interrupt each 10 ms */


und meine Delay funktion:

1
 void Delay_us(uint32_t time_us) //Delay in usec
2
{
3
  SysTick->LOAD  = 72 * time_us-1;
4
  /* Load the SysTick Counter Value */
5
  SysTick->VAL   = 0;          
6
  /* Enable SysTick Timer */  
7
  SysTick->CTRL  |= SysTick_CTRL_ENABLE_Msk;                   
8

9
  do
10
  {
11
  } while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG)==0);
12
  /* Disable SysTick Timer */
13
  SysTick->CTRL  &= ~SysTick_CTRL_ENABLE_Msk;                  
14
  /* Load the SysTick Counter Value */
15
  SysTick->VAL   = 0;                                          
16
}
17

18

19
void Delay(uint16_t time_ms) //Delay in msec
20
{
21
  while (time_ms>0)
22
  {
23
    Delay_us(1000);
24
    time_ms--;
25
  }
26
}
Gast #2815544
Lesenswert?

ok ich hab das jetzt mal nach dem template example von der std. lib 
gemacht
1
void SysTick_Handler(void)
2
{
3
  TimValAdd();
4
  TimingDelay_Decrement();
5
  
6
}


und

in main
1
void Delay(__IO uint32_t nTime)
2
{ 
3
  TimingDelay = nTime;
4

5
  while(TimingDelay != 0);
6
}
7

8
/**
9
  * @brief  Decrements the TimingDelay variable.
10
  * @param  None
11
  * @retval None
12
  */
13
void TimingDelay_Decrement(void)
14
{
15
  if (TimingDelay != 0x00)
16
  { 
17
    TimingDelay--;
18
  }
19
}


dann hab ich ja Delay(wertinMs)

und meine Variable mtime die sich hochzaehlt alle 10msec
Gast #2815547
Lesenswert?

>Meinst du etwa, das ich in den handler geschrieben hab ?

Du bastelst am Systick rum. Dann kommt der Interrupt
nicht mehr alle 10ms weil du den Systick manipulierst.

Und wieso ist mtime int? Können Zeiten negativ werden?
volatile int32_t mtime=0;

Was willst du eigentlich machen?
Gast #2815564
Lesenswert?

ok, dann uint32_t sorry.

Aber im Example wurde doch auch eine Funktion in den Handler geschrieben 
(systick example fuer Delay funktionen)

Ich wollte urspruenglich einfach nur einen Wert in millisekunden 
ausgeben.

also

uint32_t timer =0;

while(1)
{

//printf ist Ausgabe per USART2
printf("Timer in MSec %i", timer);

}


wie bekomme ich dann >timer< alle 1msec oder 10msec  um eins erhoeht?

VG
Marcel
Gast #2815602
Lesenswert?

Angenommen dein mtime hat eine Auflösung von 1ms, dann wäre die 
einfachste Lösung für einen delay:
1
void SysTick_Handler(void){
2
  TimValAdd();
3
}
4

5
void delayMs(uint32_t delay){
6
  uint32_t end = mtime+delay;
7
  while(mtime < end){
8
    // do nothing
9
  }
10
  return;
11
}

bzw. etwas modularer gehalten
1
void SysTick_Handler(void){
2
  TimValAdd();
3
}
4

5
uint32_t getMs(void){
6
  return mtime;
7
}
8

9

10
void delayMs(uint32_t delay){
11
  uint32_t end = getMs()+delay;
12
  while(getMs() < end){
13
    // do nothing
14
  }
15
  return;
16
}

Das ganze hat noch 2 Probleme:
- Ein Überlauf des Systick timers wird nicht beachtet, falls (mtime + 
end) > 2^32 ist hört die Funktion sofort auf
- Die Funktion ist nur auf 1mS genau. Ein delay(2) kann zwischen 1ms und 
2ms dauern.


Und um die Zeit ab einen beliebigen Start zu messen:
1
uint32_t start = getMs();
2

3
while(1){
4
  //printf ist Ausgabe per USART2
5
  printf("Timer in MSec %i", (getMs() - start));
6
}
Gast #2815618
Lesenswert?

>Ich wollte urspruenglich einfach nur einen Wert in millisekunden
>ausgeben.

Dann stell den Systick auf 1ms.

>wie bekomme ich dann >timer< alle 1msec oder 10msec  um eins erhoeht?

Entscheide dich mal. Alle 1ms oder alle 10ms?
Du zählst im Systick Interrupt eine Variable hoch.
Deren Wert holst du dir dann in deinem Programm. Fertig.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren