Forum: Mikrocontroller und Digitale Elektronik Systick 1ms Problem mit ARM ASF


von Elektrotiger (Gast)


Lesenswert?

Bin gerade dabei ein AVR Programm auf ARM zu übertragen.

Dabei habe ich schon ein Problem bei dem Systick festgestellt.
Dazu habe ich den Systick so eingestellt, dass jede ms Systick/Globaler 
Interrupt ausgelöst wird. Nach jeweils 500ms wird eine LED getoggelt.
So sehe ich, dass 14 Sekunden lang meine LED brav im Sekunden Takt 
aufleuchtet, aber dann plötzlich kurz unterbricht und wieder von vorne 
beginnt :(.
Dabei verstehe ich leider nicht wieso. Den Überlauf des Systick 
Registers habe ich noch nicht abgefangen, allerdings passiert dies mit 
24 Bit erst seeeeeeehr viel später als 14 Sekunden :D...
Ich benutze den Sam4e16e ARM Mikrocontroller mittels ASF von Atmel.
1
#include <asf.h>
2
#define LED0          IOPORT_CREATE_PIN(PIOA, 25)
3
4
5
uint16_t milliseconds =0;
6
7
/* ISR */
8
void SysTick_Handler(void)
9
{
10
  milliseconds++;
11
  if(milliseconds%500==0)ioport_toggle_pin_level(LED0);
12
  //if(milliseconds==100)milliseconds=0;
13
}
14
15
int main (void)
16
{
17
  ioport_init();
18
  sysclk_init();
19
  ioport_set_pin_dir(LED0, IOPORT_DIR_OUTPUT);
20
21
        SysTick_Config(SystemCoreClock/1000); // every ms
22
        while(1)
23
        {
24
25
        }
26
}

1
#ifndef CONF_CLOCK_H_INCLUDED
2
#define CONF_CLOCK_H_INCLUDED
3
4
// ===== System Clock (MCK) Source Options
5
//#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_SLCK_RC
6
//#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_SLCK_XTAL
7
//#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_SLCK_BYPASS
8
//#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_MAINCK_4M_RC
9
//#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_MAINCK_8M_RC
10
//#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_MAINCK_12M_RC
11
//#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_MAINCK_XTAL
12
//#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_MAINCK_BYPASS
13
#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_PLLACK
14
15
// ===== System Clock (MCK) Prescaler Options   (Fmck = Fsys / (SYSCLK_PRES))
16
//#define CONFIG_SYSCLK_PRES          SYSCLK_PRES_1
17
#define CONFIG_SYSCLK_PRES          SYSCLK_PRES_2
18
//#define CONFIG_SYSCLK_PRES          SYSCLK_PRES_4
19
//#define CONFIG_SYSCLK_PRES          SYSCLK_PRES_8
20
//#define CONFIG_SYSCLK_PRES          SYSCLK_PRES_16
21
//#define CONFIG_SYSCLK_PRES          SYSCLK_PRES_32
22
//#define CONFIG_SYSCLK_PRES          SYSCLK_PRES_64
23
//#define CONFIG_SYSCLK_PRES          SYSCLK_PRES_3
24
25
// ===== PLL0 (A) Options   (Fpll = (Fclk * PLL_mul) / PLL_div)
26
// Use mul and div effective values here.
27
#define CONFIG_PLL0_SOURCE          PLL_SRC_MAINCK_XTAL
28
#define CONFIG_PLL0_MUL             16
29
//#define CONFIG_PLL0_MUL        (120000000UL / BOARD_FREQ_MAINCK_XTAL)
30
#define CONFIG_PLL0_DIV             1
31
32
// Fbus = Fsys / BUS_div
33
//#define CONFIG_SYSCLK_PRES      SYSCLK_PRES_1
34
35
36
// ===== USB Clock Source Options   (Fusb = FpllX / USB_div)
37
// Use div effective value here.
38
#define CONFIG_USBCLK_SOURCE        USBCLK_SRC_PLL0
39
#define CONFIG_USBCLK_DIV           2
40
41
// ===== Target frequency (System clock)
42
// - XTAL frequency: 12MHz
43
// - System clock source: PLLA
44
// - System clock prescaler: 2 (divided by 2)
45
// - PLLA source: XTAL
46
// - PLLA output: XTAL * 16 / 1
47
// - System clock: 12 * 16 / 1 / 2 = 96MHz
48
// ===== Target frequency (USB Clock)
49
// - USB clock source: PLLA
50
// - USB clock divider: 2 (divided by 2)
51
// - PLLA output: XTAL * 16 / 2
52
// - USB clock: 12 * 16 / 2 / 2 = 48MHz
53
54
55
#endif /* CONF_CLOCK_H_INCLUDED */

von Ingo L. (corrtexx)


Lesenswert?

Elektrotiger schrieb:
> Dabei verstehe ich leider nicht wieso
Deine Zählvariable läuft halt über. Besser so machen:
1
/* ISR */
2
void SysTick_Handler(void)
3
{
4
  milliseconds++;
5
  if(milliseconds==500){
6
    ioport_toggle_pin_level(LED0);
7
    milliseconds = 0;
8
  }
9
}

von Elektrotiger (Gast)


Lesenswert?

Stimmt. Damit ist der Fehler auch weg.
Allerdings hatte ich vorher dies soeingestellt:
1
uint milliseconds =0;
2
/* ISR */
3
void SysTick_Handler(void)
4
{
5
  milliseconds++;
6
  if(milliseconds%500==0) ioport_toggle_pin_level(LED0);
7
        
8
        if(milliseconds==1000) milliseconds=0;
9
}
und da hatte es leider immer noch nicht funktioniert :/ ?

von Ingo L. (corrtexx)


Lesenswert?

Elektrotiger schrieb:
> und da hatte es leider immer noch nicht funktioniert :/ ?
Und so wie ich das sehe hast du nicht 1000 sondern 100 genommen. Das 
kann nicht gehen.
1
 if(milliseconds%500==0)ioport_toggle_pin_level(LED0);
2
  //if(milliseconds==100)milliseconds=0;

: Bearbeitet durch User
von Elektrotiger (Gast)


Lesenswert?

Ingo L. schrieb:
> Und so wie ich das sehe hast du nicht 1000 sondern 100 genommen. Das
> kann nicht gehen.

Sollte allerdings bei 16 Bit Integer niemals so schnell passieren ;).

von Elektrotiger (Gast)


Lesenswert?

Das Problem bleibt leider weiterhin bestehen ...
Habe nun zum Testen eine kleine LED Kette beschaltet.
Läuft einige Sekunden einwandfrei der Reihe nach aus und an, dann 
plötzlich komplett alle LEDs aus, so als würde der Mikrocontroller 
neustarten.

Gerate ich irgendwo in eine Endlosschleife? Oder übersehe ich für 
Systick etwas?
Mir ist bewusst, dass ich in Systick später nichts drin stehen haben 
sollte, außer um andere Interupts zu koordinieren. Hier mein 
Testprogramm:
1
#include <asf.h>
2
3
4
5
#define LED0          IOPORT_CREATE_PIN(PIOA, 25)
6
#define LED_RED1        IOPORT_CREATE_PIN(PIOD, 17)
7
#define LED_RED2        IOPORT_CREATE_PIN(PIOD, 28)
8
#define LED_YELLOW1        IOPORT_CREATE_PIN(PIOD, 20)
9
#define LED_YELLOW2        IOPORT_CREATE_PIN(PIOE, 1)
10
#define LED_YELLOW3        IOPORT_CREATE_PIN(PIOA, 3)
11
#define LED_GREEN1        IOPORT_CREATE_PIN(PIOA, 5)
12
#define LED_GREEN2        IOPORT_CREATE_PIN(PIOD, 30)
13
#define LED_GREEN3        IOPORT_CREATE_PIN(PIOA, 12)
14
15
uint16_t milliseconds =0;
16
uint8_t ampel=0;
17
18
/* ISR */
19
void SysTick_Handler(void)
20
{
21
  milliseconds++;
22
  if(milliseconds==250)
23
  {
24
    
25
    milliseconds=0;
26
    ampel++;
27
    if(ampel>8)ampel=1;
28
    switch (ampel)
29
    {
30
      case 1:
31
      {
32
        ioport_toggle_pin_level(LED_RED1);
33
      }  break;
34
      case 2:
35
      {
36
        ioport_toggle_pin_level(LED_RED2);        
37
      }  break;
38
      case 3:
39
      {
40
        ioport_toggle_pin_level(LED_YELLOW1);  
41
      }  break;
42
      case 4:
43
      {
44
        ioport_toggle_pin_level(LED_YELLOW2);
45
      }  break;
46
      case 5:
47
      {
48
        ioport_toggle_pin_level(LED_YELLOW3);
49
      }  break;
50
      case 6:
51
      {
52
        ioport_toggle_pin_level(LED_GREEN1);
53
      }  break;
54
      case 7:
55
      {
56
        ioport_toggle_pin_level(LED_GREEN2);
57
      }  break;
58
      case 8:
59
      {
60
        ioport_toggle_pin_level(LED_GREEN3);
61
      }  break;
62
    }
63
    
64
  }
65
}
66
67
68
69
int main (void)
70
{
71
  ioport_init();
72
  sysclk_init();
73
  ioport_set_pin_dir(LED0, IOPORT_DIR_OUTPUT);
74
  ioport_set_pin_dir(LED_RED1, IOPORT_DIR_OUTPUT);
75
  ioport_set_pin_dir(LED_RED2, IOPORT_DIR_OUTPUT);  
76
  ioport_set_pin_dir(LED_YELLOW1, IOPORT_DIR_OUTPUT);
77
  ioport_set_pin_dir(LED_YELLOW2, IOPORT_DIR_OUTPUT);
78
  ioport_set_pin_dir(LED_YELLOW3, IOPORT_DIR_OUTPUT);
79
  ioport_set_pin_dir(LED_GREEN1, IOPORT_DIR_OUTPUT);
80
  ioport_set_pin_dir(LED_GREEN2, IOPORT_DIR_OUTPUT);
81
  ioport_set_pin_dir(LED_GREEN3, IOPORT_DIR_OUTPUT);
82
83
        SysTick_Config(SystemCoreClock/1000); // every ms
84
  
85
        while(1){}
86
}

von Elektrotiger (Gast)


Lesenswert?

Push:
Hat niemand vll eine Idee?

von Elektrotiger (Gast)


Lesenswert?

Hier aus der ASF vom Systickconf
1
#if (__Vendor_SysTickConfig == 0)
2
3
/** \brief  System Tick Configuration
4
5
    The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
6
    Counter is in free running mode to generate periodic interrupts.   
7
8
    \param [in]  ticks  Number of ticks between two interrupts.
9
    
10
    \return          0  Function succeeded.
11
    \return          1  Function failed.
12
    
13
    \note     When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the 
14
    function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b> 
15
    must contain a vendor-specific implementation of this function.
16
17
 */
18
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
19
{
20
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */
21
22
  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */
23
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Systick Interrupt */
24
  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
25
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
26
                   SysTick_CTRL_TICKINT_Msk   |
27
                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
28
  return (0);                                                  /* Function successful */
29
}
30
31
#endif

von Elektrotiger (Gast)


Lesenswert?

Mir ist aufgefallen, dass ich das Problem nicht habe wenn ich im 
Debugger modus bin und es einfach frei laufen lasse?
Ansonsten bricht er nach 14 Sekunden kurz ab und startet vom neuen.
Bin ratlos...

von Elektrotiger (Gast)


Lesenswert?

Ich verwende das Sam4e Xpro Xplained Evulationboard und Atmel Studio.

von Lothar (Gast)


Lesenswert?

Elektrotiger schrieb:
> dass ich das Problem nicht habe wenn ich im
> Debugger modus bin

Watchdog?

von Elektrotiger (Gast)


Lesenswert?

Jau war Watchdog, Danke.

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.