Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

SysTick STM32

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[1] SysTick STM32

Messaggioda Foto Utentesilvio93 » 8 mag 2013, 17:09

Ciao a tutti,
avrei qualche perplessità riguardo il funzionamento del systick, la scheda che uso è la stm32 dyscovery con il micro STM32F100RB.

Codice: Seleziona tutto
#include <stm32f10x.h>

void Delay(uint32_t nTime);

int main (){

// Configure SysTick Timer
   if (SysTick_Config(SystemCoreClock / 1000))
   while (1);   


}


// Timer code

   static __IO uint32_t TimingDelay;

   void Delay(uint32_t nTime){
   TimingDelay = nTime;
   while(TimingDelay != 0);
   }
   
   void SysTick_Handler(void){
   if (TimingDelay != 0x00)
   TimingDelay --;
   }
   


Questo estratto di codice dovrebbe far si che la funzione Delay(1) generi un tempo di 1 ms.

In particolare vorrei sapere cosa fa questo: (ad es. chi è SysTick_Config e da dove viene)
Codice: Seleziona tutto
// Configure SysTick Timer
   if (SysTick_Config(SystemCoreClock / 1000))
   while (1);   


Mentre questo dovrebbe aspettare semplicemente che la variabile TimingDelay arrivi a 0
Codice: Seleziona tutto
void Delay(uint32_t nTime){
   TimingDelay = nTime;
   while(TimingDelay != 0);
   }



Invece questa dovrebbe essere l'interruzione chiamata dal systick che ad ogni giro decrementa la varibile di prima (TimingDelay)
Codice: Seleziona tutto
void SysTick_Handler(void){
   if (TimingDelay != 0x00)
   TimingDelay --;
   }


Attendo delucidazioni sulla questione, grazie in anticipo.
Avatar utente
Foto Utentesilvio93
405 2 7
 
Messaggi: 26
Iscritto il: 21 apr 2013, 17:06

0
voti

[2] Re: SysTick STM32

Messaggioda Foto UtenteAjKDAP » 8 mag 2013, 20:33

Non ho mai utilizzato questo micro ma da quanto leggo in rete la funzione SysTick_Config() serve a impostare il valore di "reload" del timer.

Nel tuo spezzone di codice viene usata la macro SystemCoreClock per ricavare la frequenza di clock del micro e viene divisa per 1000 per ottenere il valore da caricare nel timer SysTick ad ogni overflow per generare un interrupt di 1ms:

Codice: Seleziona tutto
SysTick interrupt period = the Reload Value register divided by clock frequency
                               = (SystemCoreClock/1000)/SystemCoreClock = 1/1000 = 1ms


Evidentemente se la funzione viene eseguita correttamente viene ritornato un valore TRUE che fa entrare il programma nel ciclo while.

Il resto delle funzioni che hai elencato sono coerenti con la tua descrizione :ok:

Per fare qualche prova potresti provare ad accendere qualche LED modificando il main così:

Codice: Seleziona tutto
int main (){

   if (SysTick_Config(SystemCoreClock / 1000))
   while (1)
  {
       Delay(500);
       //LED=0;
       Delay(1000);
       //LED=1;
  }

  return 0;
}
'˙˙˙·٠•● Alberto ●•٠·˙˙˙'
________________________
http://www.ajk.altervista.org
Avatar utente
Foto UtenteAjKDAP
1.250 2 6 9
Expert EY
Expert EY
 
Messaggi: 797
Iscritto il: 17 mag 2006, 0:13
Località: nella coda dei pronti

0
voti

[3] Re: SysTick STM32

Messaggioda Foto Utentesilvio93 » 8 mag 2013, 21:32

Ok... chiaro. Però guardando degli esempi relativi al SysTick nelle librerie CMSIS del micro ho notato che la funzione:
Codice: Seleziona tutto
void SysTick_Handler(void){
   if (TimingDelay != 0x00)
   TimingDelay --;
   }


viene scritta diversamente:
Codice: Seleziona tutto
void TimingDelay_Decrement(void)
{
  if (TimingDelay != 0x00)
  {
    TimingDelay--;
  }
}


Ma, in teoria, l'interruzione non dovrebbe avere un nome specifico?

Poi un'altra cosa stupida, quando scrivo, ad esempio if(variabile) è come se scrivessi if(variabile==0)?
Avatar utente
Foto Utentesilvio93
405 2 7
 
Messaggi: 26
Iscritto il: 21 apr 2013, 17:06

0
voti

[4] Re: SysTick STM32

Messaggioda Foto UtenteAjKDAP » 8 mag 2013, 22:11

Puoi postare l'intero esempio? Molto probabilmente se scrivono la funzione esterna TimingDelay_Decrement(void) poi la richiameranno all'interno del gestore di interrupt penso :-)

Per quanto riguarda l'if, dovresti leggerti qualche guida sul C.

La scelta migliore secondo me è esplicitare tutto quando possibile, quindi:

Codice: Seleziona tutto
variabile==0


restituisce TRUE solamente se variabile è uguale a zero, FALSE altrimenti.

se usi solo variabile dentro l'IF come unica condizione, generalmente il compilatore controlla il tipo della variabile, se booleana è perfetto, se invece ad esempio è una variabile intera INT allora viene eseguita una conversione di tipo implicita per poter "trasformare" il valore intero in valore booleano (unico tipo accettato dalla clausola IF ! )

Generalmente quindi if(variabile==1) puoi "vederlo" come if(variabile) mentre if(variabile==0) come if(!variabile)

Ti ho consigliato di leggerti una guida sul C proprio perché è un discorso leggermente più complesso ed ora ho scritto in modo molto superficiale, giusto per darti un'idea. :ok:
'˙˙˙·٠•● Alberto ●•٠·˙˙˙'
________________________
http://www.ajk.altervista.org
Avatar utente
Foto UtenteAjKDAP
1.250 2 6 9
Expert EY
Expert EY
 
Messaggi: 797
Iscritto il: 17 mag 2006, 0:13
Località: nella coda dei pronti

0
voti

[5] Re: SysTick STM32

Messaggioda Foto Utentesilvio93 » 8 mag 2013, 22:39

Grazie per tutto.
Questo è il codice completo
Codice: Seleziona tutto
/**
  ******************************************************************************
  * @file    SysTick/TimeBase/main.c
  * @author  MCD Application Team
  * @version V3.5.0
  * @date    08-April-2011
  * @brief   Main program body.
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/** @addtogroup STM32F10x_StdPeriph_Examples
  * @{
  */

/** @addtogroup SysTick_TimeBase
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static __IO uint32_t TimingDelay;

/* Private function prototypes -----------------------------------------------*/
void Delay(__IO uint32_t nTime);

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
int main(void)
{
  /*!< At this stage the microcontroller clock setting is already configured,
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f10x_xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f10x.c file
     */     

  /* Initialize Leds mounted on STM3210X-EVAL board */
  STM_EVAL_LEDInit(LED1);
  STM_EVAL_LEDInit(LED2);
  STM_EVAL_LEDInit(LED3);
  STM_EVAL_LEDInit(LED4);

  /* Turn on LED1 and LED3 */
  STM_EVAL_LEDOn(LED1);
  STM_EVAL_LEDOn(LED3);

  /* Setup SysTick Timer for 1 msec interrupts.
     ------------------------------------------
    1. The SysTick_Config() function is a CMSIS function which configure:
       - The SysTick Reload register with value passed as function parameter.
       - Configure the SysTick IRQ priority to the lowest value (0x0F).
       - Reset the SysTick Counter register.
       - Configure the SysTick Counter clock source to be Core Clock Source (HCLK).
       - Enable the SysTick Interrupt.
       - Start the SysTick Counter.
   
    2. You can change the SysTick Clock source to be HCLK_Div8 by calling the
       SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8) just after the
       SysTick_Config() function call. The SysTick_CLKSourceConfig() is defined
       inside the misc.c file.

    3. You can change the SysTick IRQ priority by calling the
       NVIC_SetPriority(SysTick_IRQn,...) just after the SysTick_Config() function
       call. The NVIC_SetPriority() is defined inside the core_cm3.h file.

    4. To adjust the SysTick time base, use the following formula:
                           
         Reload Value = SysTick Counter Clock (Hz) x  Desired Time base (s)
   
       - Reload Value is the parameter to be passed for SysTick_Config() function
       - Reload Value should not exceed 0xFFFFFF
   */
  if (SysTick_Config(SystemCoreClock / 1000))
  {
    /* Capture error */
    while (1);
  }

  while (1)
  {
    /* Toggle LED2 and LED4 */
    STM_EVAL_LEDToggle(LED2);
    STM_EVAL_LEDToggle(LED4);

    /* Insert 50 ms delay */
    Delay(50);

    /* Toggle LED1 and LED3 */
    STM_EVAL_LEDToggle(LED1);
    STM_EVAL_LEDToggle(LED3);

    /* Insert 100 ms delay */
    Delay(100);
  }
}

/**
  * @brief  Inserts a delay time.
  * @param  nTime: specifies the delay time length, in milliseconds.
  * @retval None
  */
void Delay(__IO uint32_t nTime)
{
  TimingDelay = nTime;

  while(TimingDelay != 0);
}

/**
  * @brief  Decrements the TimingDelay variable.
  * @param  None
  * @retval None
  */
void TimingDelay_Decrement(void)
{
  if (TimingDelay != 0x00)
  {
    TimingDelay--;
  }
}

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}

#endif

/**
  * @}
  */

/**
  * @}
  */

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
Avatar utente
Foto Utentesilvio93
405 2 7
 
Messaggi: 26
Iscritto il: 21 apr 2013, 17:06


Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 3 ospiti