Partage
  • Partager sur Facebook
  • Partager sur Twitter

STM32 Gestion des timers

Sujet résolu
    12 juillet 2018 à 10:08:31

    Bonjour,

    Pour mon projet j'ai besoin de realiser deux operations avec des timings differents.

    Je dois communiquer sur l'UART toutes les 60 secondes, et en parallele je dois communiquer en SPI toutes les 10 secondes.

    Voici un exemple de code que j'utilise pour communiquer via l'UART:

    /*Test function for Sigfox Module*/
    char str[11]; //Size of the string
    void sigfox_send_test(void){
    	sprintf(str,"AT$SF=4444\r"); //String composed of a 4-bytes message via AT Command
    	UART_puts(UART3_ID, (uint8_t*)str, sizeof(str));	//Send the message to UART3 (Sigfox module)
    	HAL_Delay(60000);	//60-seconds delay
    }


    Le probleme c'est que dans ma boucle infinie (while 1), j'appelle la fonction qui communique en SPI puis juste apres, celle qui ecrit sur l'UART:

    machine_SD_write(FALSE,mot_sd_2,nom_fichier);	//write the data into the SD Card //SPI
    sigfox_send_frame(lat_rmc,long_rmc,gps_datas.altitude,temp1);	//send data to Sigfox //UART


    Donc au final les deux fonctions sont apellees toutes les 60 secondes.

    Comment faire pour que la fonction communiquant sur l'UART ecrive bien toutes les 60 secondes mais qu'en meme temps je puisse comuniquer en SPI toutes les 10 secondes?

    Merci beaucoup.

    • Partager sur Facebook
    • Partager sur Twitter
      12 juillet 2018 à 11:03:49

      Salut, 

      Ton problème est due au fait que ta fonction contient un delay, 

      La solution serait d'enlever le delay de la fonction et de faire des interruption sur un Timer

      chaque 10 secondes et chaque 60 secondes une interruption différente est envoyé et ton programme exécute la fonction qui correspond 

      Il y a un cours sur Openclassrooms qui traite de ça (Développez en C pour l'embarqué) 

      • Partager sur Facebook
      • Partager sur Twitter
        12 juillet 2018 à 15:48:38

        Salut, merci pour ta reponse!

        J'ai passe quelques heures a lire et tester les parties qui m'interessent dans ce tuto mais j'ai quelques soucis.

        En effet, moi j'ai "sous traite" pas mal de choses, notamment au niveau des horloges, avec STM32CubeMX.

        Par exemple admettons que je souhaite realiser une interruption sur un UART, dans les exemples du tuto (Partie 3 Chap 5) il nous montre comment initialiser les GPIO d'une certaine maniere mais dans mon cas ils sont initialises comme cela:

        Exemple:

        __HAL_RCC_GPIOB_CLK_ENABLE();		//Horloge des broches a utiliser
        GPIO_InitStruct.Pin = GPIO_PIN_10;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_PULLUP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
        
        GPIO_InitStruct.Pin = GPIO_PIN_11;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_PULLUP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


        Je suppose que je dois choisir quelque chose parmi les "IT" plutot que "AF_PP" mais comment savoir lequel choisir?

        /** @defgroup GPIO_mode GPIO mode
          * @brief GPIO Configuration Mode 
          *        Elements values convention: 0xX0yz00YZ
          *           - X  : GPIO mode or EXTI Mode
          *           - y  : External IT or Event trigger detection 
          *           - z  : IO configuration on External IT or Event
          *           - Y  : Output type (Push Pull or Open Drain)
          *           - Z  : IO Direction mode (Input, Output, Alternate or Analog)
          * @{
          */ 
        #define  GPIO_MODE_INPUT                        (0x00000000U)   /*!< Input Floating Mode                   */
        #define  GPIO_MODE_OUTPUT_PP                    (0x00000001U)   /*!< Output Push Pull Mode                 */
        #define  GPIO_MODE_OUTPUT_OD                    (0x00000011U)   /*!< Output Open Drain Mode                */
        #define  GPIO_MODE_AF_PP                        (0x00000002U)   /*!< Alternate Function Push Pull Mode     */
        #define  GPIO_MODE_AF_OD                        (0x00000012U)   /*!< Alternate Function Open Drain Mode    */
        #define  GPIO_MODE_AF_INPUT                     GPIO_MODE_INPUT          /*!< Alternate Function Input Mode         */
        
        #define  GPIO_MODE_ANALOG                       (0x00000003U)   /*!< Analog Mode  */
            
        #define  GPIO_MODE_IT_RISING                    (0x10110000U)   /*!< External Interrupt Mode with Rising edge trigger detection          */
        #define  GPIO_MODE_IT_FALLING                   (0x10210000U)   /*!< External Interrupt Mode with Falling edge trigger detection         */
        #define  GPIO_MODE_IT_RISING_FALLING            (0x10310000U)   /*!< External Interrupt Mode with Rising/Falling edge trigger detection  */
        
        #define  GPIO_MODE_EVT_RISING                   (0x10120000U)   /*!< External Event Mode with Rising edge trigger detection               */
        #define  GPIO_MODE_EVT_FALLING                  (0x10220000U)   /*!< External Event Mode with Falling edge trigger detection              */
        #define  GPIO_MODE_EVT_RISING_FALLING           (0x10320000U)   /*!< External Event Mode with Rising/Falling edge trigger detection       */
        



        Merci.

        • Partager sur Facebook
        • Partager sur Twitter
          12 juillet 2018 à 18:43:27

          tengalice49 a écrit:

          Par exemple admettons que je souhaite realiser une interruption sur un UART,

          [...]

          Je suppose que je dois choisir quelque chose parmi les "IT" plutot que "AF_PP" mais comment savoir lequel choisir?

          Si tu veux savoir si un octet a été reçu, ce serait plutôt l'interruption liée à l'UART qu'il faut gérer plutôt que l'interruption liée au GPIO de l'UART, qui ne t'indiquerait que les changements d'état de la broche RX. 

          • Partager sur Facebook
          • Partager sur Twitter
            12 juillet 2018 à 20:50:53

            alexisdm a écrit:

            tengalice49 a écrit:

            Par exemple admettons que je souhaite realiser une interruption sur un UART,

            [...]

            Je suppose que je dois choisir quelque chose parmi les "IT" plutot que "AF_PP" mais comment savoir lequel choisir?

            Si tu veux savoir si un octet a été reçu


            Le truc c'est quoi moi je veux faire des interruptions pour envoyer des donnees, pas pour voir si elles sont recues.

            Par exemple je veux envoyer des donnees via l'uart toutes les 60 secondes et via le spi toutes les 10 secondes. 

            • Partager sur Facebook
            • Partager sur Twitter
              13 juillet 2018 à 1:57:56

              Donc ce sont les interruptions des timers que tu dois regarder, pas la configuration des broches de l'UART.

              Tu pourrais configurer les "TIM" dans STM32CubeMX, il suffit de choisir des valeurs de prescaler et de période de telle sorte d'avoir les temps souhaités, d'activer les interruptions correspondantes dans la page NVIC et ça générera le code pour toi.

              Mais le plus simple est peut-être d'utiliser le compteur système, HAL_GetTick(), qui compte le nombre de millisecondes écoulées depuis la mise sous tension:

              uint32_t tick = HAL_GetTick();
              
              uint32_t last_uart = tick - 60000;
              uint32_t last_spi = tick - 10000;
              
              while(1) {
                tick = HAL_GetTick();
                if(tick - last_spi >= 10000) {
                  machine_SD_write(FALSE,mot_sd_2,nom_fichier);   //write the data into the SD Card //SPI
                }
                if(tick - last_uart >= 60000) {
                  sigfox_send_frame(lat_rmc,long_rmc,gps_datas.altitude,temp1);   //send data to Sigfox //UART   
                  last_uart += 60000;
                }
               
              }
              Je ne sais pas s'il y a quelque chose à initialiser pour que SysTick / HAL_GetTick() fonctionne par contre.
              • Partager sur Facebook
              • Partager sur Twitter
                13 juillet 2018 à 9:20:06

                Salut, 

                En fait ma fonction HAL_Delay(temps en ms) utilise deja le HAL_GetTick();

                __weak void HAL_Delay(__IO uint32_t Delay)
                {
                  uint32_t tickstart = 0;
                  tickstart = HAL_GetTick();
                  while((HAL_GetTick() - tickstart) < Delay)
                  {
                  }
                }

                Le probleme c'est que quand je l'appelle ca me bloque tout le reste du programme donc je sais pas si ton algo pourrait fonctionner, j'essayerai en dernier recours mais du coup j'aimerais bien faire la methode des interruptions sur le timer.

                Sais-tu comment je devrais le configurer pour mon projet?



                • Partager sur Facebook
                • Partager sur Twitter
                  13 juillet 2018 à 13:08:24

                  HAL_GetTick ne bloque pas, contrairement à HAL_Delay, elle renvoie juste le nombre de millisecondes écoulées, c'est le while dans la fonction HAL_Delay qui bloque tant que le délai demandé n'est pas passé.

                  Dans Clock Source, tu mets "Internal Clock", ça devrait ajouter TIM2 dans l'onglet Configuration, où tu pourras régler le prescaler, le diviseur et le compteur en fonction de ta fréquence, et dans le NVIC (dans l'onglet au niveau de la configuration de TIM2), tu as une case à cocher pour activer l'interruption globale de TIM2.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    13 juillet 2018 à 13:30:32

                    J'ai suivi un tuto et je me retrouve avec le code suivant:

                    #include <stm32l1xx_gpio.h>
                    #include <stm32l1xx_tim.h>
                    #include <stm32l1xx_rcc.h>
                    #include <misc.h>
                    
                    void InitializeLEDs()
                    {
                    	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
                    
                        GPIO_InitTypeDef gpioStructure;
                        gpioStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;
                        gpioStructure.GPIO_Mode = GPIO_Mode_OUT;
                        gpioStructure.GPIO_Speed = GPIO_Speed_40MHz;
                        GPIO_Init(GPIOA, &gpioStructure);
                    
                        GPIO_WriteBit(GPIOA, GPIO_Pin_13 | GPIO_Pin_14	, Bit_RESET);
                    }
                    
                    void InitializeTimer2()
                    {
                        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
                    
                        TIM_TimeBaseInitTypeDef timerInitStructure;
                        timerInitStructure.TIM_Prescaler = 40000;
                        timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
                        timerInitStructure.TIM_Period = 500;
                        timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
                        TIM_TimeBaseInit(TIM2, &timerInitStructure);
                        TIM_Cmd(TIM2, ENABLE);
                        TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
                    }
                    
                    void InitializeTimer4()
                    {
                        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
                    
                        TIM_TimeBaseInitTypeDef timerInitStructure;
                        timerInitStructure.TIM_Prescaler = 50000;
                        timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
                        timerInitStructure.TIM_Period = 500;
                        timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
                        TIM_TimeBaseInit(TIM4, &timerInitStructure);
                        TIM_Cmd(TIM4, ENABLE);
                        TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
                    }
                    
                    void EnableTimerInterrupt2()
                    {
                    	NVIC_InitTypeDef nvicStructure;
                    	nvicStructure.NVIC_IRQChannel = TIM2_IRQn;
                    	nvicStructure.NVIC_IRQChannelPreemptionPriority = 0;
                    	nvicStructure.NVIC_IRQChannelSubPriority = 1;
                    	nvicStructure.NVIC_IRQChannelCmd = ENABLE;
                    	NVIC_Init(&nvicStructure);
                    }
                    
                    void EnableTimerInterrupt4()
                    {
                    	NVIC_InitTypeDef nvicStructure;
                    	nvicStructure.NVIC_IRQChannel = TIM4_IRQn;
                    	nvicStructure.NVIC_IRQChannelPreemptionPriority = 0;
                    	nvicStructure.NVIC_IRQChannelSubPriority = 1;
                    	nvicStructure.NVIC_IRQChannelCmd = ENABLE;
                    	NVIC_Init(&nvicStructure);
                    }
                    
                    
                    int main()
                    {
                        InitializeLEDs();
                        InitializeTimer2();
                        EnableTimerInterrupt2();
                        InitializeTimer4();
                        EnableTimerInterrupt4();
                    
                        while(1)
                        {
                    
                        }
                       /*for (int i=0; i<1000000; i++)
                    	   asm("nop");
                       GPIO_ToggleBits(GPIOA, GPIO_Pin_14);*/
                    }
                    
                    void TIM2_IRQHandler()
                    {
                    	if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
                    	{
                    		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
                    		GPIO_ToggleBits(GPIOA, GPIO_Pin_13);
                    	}
                    }
                    
                    void TIM4_IRQHandler()
                    {
                    	if(TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
                    	{
                    		TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
                    		GPIO_ToggleBits(GPIOA, GPIO_Pin_14);
                    	}
                    }
                    

                    J'ai bien deux LEDs qui clignotent a des frequences differentes donc les interruptions fonctionnent bien.

                    Cependant j'ai un probleme et une question.

                    Mon probleme: En mode Debug sur SW for STM32, le debuggeur s'arrete :

                    Open On-Chip Debugger 0.10.0-dev-00007-g58350bc-dirty (2018-01-08-12:20)
                    Licensed under GNU GPL v2
                    For bug reports, read
                    	http://openocd.org/doc/doxygen/bugs.html
                    srst_only separate srst_nogate srst_open_drain connect_assert_srst
                    Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
                    adapter_nsrst_delay: 100
                    adapter speed: 240 kHz
                    Info : tcl server disabled
                    Info : telnet server disabled
                    Info : clock speed 240 kHz
                    Error: libusb_open() failed with LIBUSB_ERROR_NOT_SUPPORTED
                    Info : STLINK v2.1 JTAG v28 API v2 M17 VID 0x0483 PID 0x374B
                    Info : using stlink api v2
                    Info : Target voltage: 3.250952
                    Info : Stlink adapter speed set to 240 kHz
                    Info : STM32L152RETx.cpu: hardware has 6 breakpoints, 4 watchpoints
                    Info : accepting 'gdb' connection on tcp/3333
                    Info : Stlink adapter speed set to 240 kHz
                    adapter speed: 240 kHz
                    target halted due to debug-request, current mode: Thread 
                    xPSR: 0x01000000 pc: 0x08000934 msp: 0x20014000
                    STM32L: Enabling HSI
                    Info : Stlink adapter speed set to 4000 kHz
                    adapter speed: 4000 kHz
                    Info : Device: STM32L1xx (Cat.5/Cat.6)
                    Info : STM32L flash has dual banks. Bank (0) size is 256kb, base address is 0x8000000
                    Info : Device: STM32L1xx (Cat.5/Cat.6)
                    Info : STM32L flash has dual banks. Bank (1) size is 256kb, base address is 0x8040000
                    Info : Stlink adapter speed set to 240 kHz
                    adapter speed: 240 kHz
                    target halted due to debug-request, current mode: Thread 
                    xPSR: 0x01000000 pc: 0x08000934 msp: 0x20014000
                    Info : Stlink adapter speed set to 240 kHz
                    adapter speed: 240 kHz
                    target halted due to debug-request, current mode: Thread 
                    xPSR: 0x01000000 pc: 0x08000934 msp: 0x20014000
                    STM32L: Enabling HSI
                    Info : Stlink adapter speed set to 4000 kHz
                    adapter speed: 4000 kHz
                    target halted due to breakpoint, current mode: Thread 
                    xPSR: 0x61000000 pc: 0x2000000e msp: 0x20014000
                    Info : Stlink adapter speed set to 240 kHz
                    adapter speed: 240 kHz
                    target halted due to debug-request, current mode: Thread 
                    xPSR: 0x01000000 pc: 0x08000934 msp: 0x20014000
                    Error: JTAG failure -4
                    Error: JTAG failure -4
                    Error: JTAG failure -4
                    Error: JTAG failure -4
                    Error: JTAG failure -4
                    Error: JTAG failure -4
                    Error: JTAG failure -4
                    Error: JTAG failure -4
                    Error: JTAG failure -4
                    Error: JTAG failure -4
                    Error: JTAG failure -4
                    Error: JTAG failure -4
                    Error: JTAG failure -4
                    Error: JTAG failure -4
                    Error: JTAG failure -4
                    Error: JTAG failure -4
                    Error: JTAG failure -4
                    Error: jtag status contains invalid mode value - communication failure
                    Polling target STM32L152RETx.cpu failed, trying to reexamine
                    Examination failed, GDB will be halted. Polling again in 100ms
                    Info : Previous state query failed, trying to reconnect
                    Error: jtag status contains invalid mode value - communication failure
                    Polling target STM32L152RETx.cpu failed, trying to reexamine
                    Examination failed, GDB will be halted. Polling again in 300ms
                    Info : Previous state query failed, trying to reconnect
                    Error: jtag status contains invalid mode value - communication failure
                    Polling target STM32L152RETx.cpu failed, trying to reexamine
                    Examination failed, GDB will be halted. Polling again in 700ms
                    Info : Previous state query failed, trying to reconnect
                    Error: jtag status contains invalid mode value - communication failure
                    Polling target STM32L152RETx.cpu failed, trying to reexamine
                    Examination failed, GDB will be halted. Polling again in 1500ms
                    Info : Previous state query failed, trying to reconnect
                    Error: jtag status contains invalid mode value - communication failure
                    Polling target STM32L152RETx.cpu failed, trying to reexamine
                    Examination failed, GDB will be halted. Polling again in 3100ms
                    Info : Previous state query failed, trying to reconnect
                    Error: jtag status contains invalid mode value - communication failure
                    Polling target STM32L152RETx.cpu failed, trying to reexamine
                    Examination failed, GDB will be halted. Polling again in 6300ms
                    Info : Previous state query failed, trying to reconnect
                    Error: jtag status contains invalid mode value - communication failure
                    Polling target STM32L152RETx.cpu failed, trying to reexamine
                    Examination failed, GDB will be halted. Polling again in 6300ms
                    Info : Previous state query failed, trying to reconnect

                    Sur le tuto il y a cette phrase qui: 

                    "Furthermore, unless you explicitly provide a method for a given interrupt handler, such as TIM2_IRQHandler(), GCC will automatically substitute it with DefaultHandler() that will halt your program."

                    Est ce que j'ai mal nomme ma fonction Handler?

                    Mon autre question: comment regler les parametres de prescaler et de timer pour arriver a des valeurs precises ? (10 et 60s dans mon cas).

                    Merci.

                    • Partager sur Facebook
                    • Partager sur Twitter
                      13 juillet 2018 à 15:29:48

                      D'après la doc, PA14 et PA15 sur laquelle les LEDs sont connectées, sont utilisées par les broches JTCLK/SWCLK et JTDI du debug, essaye de mettre tes LEDs sur d'autres broches.

                      tengalice49 a écrit:

                      Est ce que j'ai mal nomme ma fonction Handler?

                      Si tu les avais mal nommées, les fonctions ne s'exécuteraient pas du tout. Cette phrase veut juste dire que les handlers sont déjà tous prédéfinis et qu'en particulier pour les timers, la fonction prédéfinie bloque le programme si l'interruption est générée, ce qui permet de savoir, en debug, si on a oublier d'écrire la fonction ou qu'on a fait une erreur dans son nom.

                      Mon autre question: comment regler les parametres de prescaler et de timer pour arriver a des valeurs precises ? (10 et 60s dans mon cas).

                      D'après le code, le microcontrôleur tourne à 40MHz, avec un prescaler à 40000 et un compteur à 500, la fréquence est de 40000000 / 40000 soit 1000Hz, donc le compteur compte par incrément de 1ms, soit 501ms (comme le compteur part de 0 et arrive jusqu'à 500, il faut ajouter 1).

                      Ton microcontrôleur tourne à 32Mhz, donc si tu mets 32000 dans le prescaler et respectivement 9999 et 59999 dans le compteur, tu auras tes 10s et 60 secondes.  

                      • Partager sur Facebook
                      • Partager sur Twitter
                        13 juillet 2018 à 16:09:44

                        Ok tres bien merci beaucoup pour toutes tes explications.

                        Effectivement les borches etaient utilisees par le JTAG connector d'ou les erreurs au debug j'aurais du le remarquer...

                        Donc la j'ai quelque chose de plus en plus interessant, avec mon Timer2, la LED s'allume 10 secondes puis s'eteint 10 secondes, etc..

                        Avec le timer 4, c'est la meme chose toutes les 60 secondes.

                        Cependant, lorsque je vais appliquer mes timer a mon projet, j'aimerais que les infos soient envoyees toutes les 10 ou 60 secondes, j'ai peur que ce code fasse plutot quelque chose comme ca:

                        Rien n'est envoye pendant 10 secondes puis plein de donnees sont envoyees les 10 secondes suivantes, etc Pareil pour l'autre timer avec les 60 secondes.

                        Je sais pas si je suis tres clair :/ J'ai fais un petit schema pour illustrer ma question, moi j'aimerais avoir le comportement du schema en haut, et j'ai peur que le comportement actuel soit celui du schema du bas:

                        • Partager sur Facebook
                        • Partager sur Twitter
                          13 juillet 2018 à 16:20:16

                          La fonction qui est appelée dans les 2 timers est GPIO_ToggleBits, donc elle change l'état de la LED à chaque exécution, ce qui fait bien une exécution toutes les 10 ou 60 secondes.

                          Si tu remplaces cette fonction par tes 2 codes dans chacun des handlers, il n'y aura toujours qu'une seule exécution toutes les 10 et 60 secondes.

                          • Partager sur Facebook
                          • Partager sur Twitter
                            13 juillet 2018 à 16:30:46

                            Ok tres bien, ca parrait logique en effet. Je ferais l'implementation de mon code en debut de semaine prochaine, j'aurais surement d'autres questions..:)

                            Aussi, j'aimerais savoir est ce que la frequence a une importance sur la consommation? Par exemple est ce que si je consomme plus si le micro tourne a 32MHz que si il consommait a 16MHz? 

                            • Partager sur Facebook
                            • Partager sur Twitter
                              13 juillet 2018 à 18:22:29

                              La première page de la doc donne une estimation de consommation de 195µA/MHz.
                              • Partager sur Facebook
                              • Partager sur Twitter
                                14 juillet 2018 à 10:07:17

                                Ok, et est ce que c'est possible d'utiliser les timers sur des frequences plus faibles pour reduire la consommation? Et si c'est possible est ce que c'est utile ou negligeable?

                                L'objectif final de mon projet est de pouvoir faire tourner tout cela pendant au moins 4h avec une batterie la plus legere possible (quelque chose comme cela: https://www.mega-piles.com/pile-lithium-ls14250-3.6v-1200mah-1-2lr06-p-56).

                                Etant donne que mon micro va tourner quasiment 100% du temps je me dis que peut etre qu'en reduisant les frequences ca pourrait me faire economiser un peu de batterie?

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  14 juillet 2018 à 12:53:36

                                  Euh... 32MHz * 195µA/MHz => 6.2mA, ce qui fait qu'avec une batterie de 1200mAh, il pourrait tourner presque 200h s'il n'y avait que lui à alimenter.

                                  Mais oui, tu peux réduire la fréquence et ça n'aura aucune incidence sur les timers, tant que tu ajustes les valeurs de prescaler et de compteur en fonction de cette fréquence.

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    16 juillet 2018 à 11:50:50

                                    Ok parfait merci!

                                    Du coup maintenant j'essaye d'implementer les fonctions d'interruption dans mon projet mais j'ai quelques soucis. Les bibliotheques ne sont pas les memes du coup je dois tout reecrire avec des fonctions differentes.

                                    Pour l'instant j'ai cela pour le timer 2 mais je ne sais pas si c'est correct:

                                    void InitializeLEDs()
                                    {
                                    	__HAL_RCC_GPIOC_CLK_ENABLE();
                                    
                                        GPIO_InitTypeDef gpioStructure;
                                        gpioStructure.Pin = GPIO_PIN_2 | GPIO_PIN_3;
                                        gpioStructure.Mode = GPIO_MODE_OUTPUT_PP;
                                        gpioStructure.Speed = GPIO_SPEED_FREQ_LOW;
                                        HAL_GPIO_Init(GPIOC, &gpioStructure);
                                    
                                        HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2 | GPIO_PIN_3, GPIO_PIN_RESET);
                                    }
                                    
                                    
                                    void InitializeTimer2()
                                    {
                                        __HAL_RCC_TIM2_CLK_ENABLE();
                                    
                                        TIM_Base_InitTypeDef timerInitStructure;
                                        timerInitStructure.Prescaler = 32000;
                                        timerInitStructure.CounterMode = TIM_COUNTERMODE_UP;
                                        timerInitStructure.Period = 9999;	//10-seconds
                                        timerInitStructure.ClockDivision = TIM_CLOCKDIVISION_DIV1;
                                    
                                        TIM_HandleTypeDef timerHandle;
                                        timerHandle.Channel = HAL_TIM_ACTIVE_CHANNEL_2;
                                        timerHandle.Init = timerInitStructure;
                                        timerHandle.Instance = TIM2;
                                    
                                        HAL_TIM_Base_MspInit(&timerHandle);
                                        __HAL_TIM_ENABLE_IT(&timerHandle, TIM_IT_UPDATE);
                                    }
                                    
                                    void EnableTimerInterrupt2()
                                    {
                                    	NVIC_InitTypeDef nvicStructure;
                                    	nvicStructure.NVIC_IRQChannel = TIM2_IRQn;
                                    	nvicStructure.NVIC_IRQChannelPreemptionPriority = 0;
                                    	nvicStructure.NVIC_IRQChannelSubPriority = 1;
                                    	nvicStructure.NVIC_IRQChannelCmd = ENABLE;
                                    	NVIC_Init(&nvicStructure);
                                    }
                                    

                                    Cependant pour la derniere fonction utile au timer (ici le code fonctionnel avec les LEDs sur mon projet de test):

                                    void TIM2_IRQHandler()
                                    {
                                    	if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
                                    	{
                                    		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
                                    		GPIO_ToggleBits(GPIOC, GPIO_Pin_2);
                                    	}
                                    }

                                    Dans ma "nouvelle" bibliotheques j'ai les fonctions suivantes:

                                    /**
                                      ******************************************************************************
                                      * @file    stm32l1xx_hal_tim.h
                                      * @author  MCD Application Team
                                      * @brief   Header file of TIM HAL module.
                                      ******************************************************************************
                                      * @attention
                                      *
                                      * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
                                      *
                                      * Redistribution and use in source and binary forms, with or without modification,
                                      * are permitted provided that the following conditions are met:
                                      *   1. Redistributions of source code must retain the above copyright notice,
                                      *      this list of conditions and the following disclaimer.
                                      *   2. Redistributions in binary form must reproduce the above copyright notice,
                                      *      this list of conditions and the following disclaimer in the documentation
                                      *      and/or other materials provided with the distribution.
                                      *   3. Neither the name of STMicroelectronics nor the names of its contributors
                                      *      may be used to endorse or promote products derived from this software
                                      *      without specific prior written permission.
                                      *
                                      * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
                                      * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                                      * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                                      * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
                                      * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                                      * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                                      * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
                                      * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
                                      * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
                                      * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                                      *
                                      ******************************************************************************
                                      */
                                    
                                    /* Define to prevent recursive inclusion -------------------------------------*/
                                    #ifndef __STM32L1xx_HAL_TIM_H
                                    #define __STM32L1xx_HAL_TIM_H
                                    
                                    #ifdef __cplusplus
                                     extern "C" {
                                    #endif
                                    
                                    /* Includes ------------------------------------------------------------------*/
                                    #include "stm32l1xx_hal_def.h"
                                    
                                    /** @addtogroup STM32L1xx_HAL_Driver
                                      * @{
                                      */
                                    
                                    /** @addtogroup TIM
                                      * @{
                                      */
                                    
                                    /* Exported types ------------------------------------------------------------*/
                                    /** @defgroup TIM_Exported_Types TIM Exported Types
                                      * @{
                                      */
                                    /**
                                      * @brief  TIM Time base Configuration Structure definition
                                      */
                                    typedef struct
                                    {
                                      uint32_t Prescaler;         /*!< Specifies the prescaler value used to divide the TIM clock.
                                                                       This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */
                                    
                                      uint32_t CounterMode;       /*!< Specifies the counter mode.
                                                                       This parameter can be a value of @ref TIM_Counter_Mode */
                                    
                                      uint32_t Period;            /*!< Specifies the period value to be loaded into the active
                                                                       Auto-Reload Register at the next update event.
                                                                       This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF.  */
                                    
                                      uint32_t ClockDivision;     /*!< Specifies the clock division.
                                                                       This parameter can be a value of @ref TIM_ClockDivision */
                                    
                                    } TIM_Base_InitTypeDef;
                                    
                                    /**
                                      * @brief  TIM Output Compare Configuration Structure definition
                                      */
                                    typedef struct
                                    {
                                      uint32_t OCMode;        /*!< Specifies the TIM mode.
                                                                   This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */
                                    
                                      uint32_t Pulse;         /*!< Specifies the pulse value to be loaded into the Capture Compare Register.
                                                                   This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */
                                    
                                      uint32_t OCPolarity;    /*!< Specifies the output polarity.
                                                                   This parameter can be a value of @ref TIM_Output_Compare_Polarity */
                                    
                                      uint32_t OCFastMode;   /*!< Specifies the Fast mode state.
                                                                   This parameter can be a value of @ref TIM_Output_Fast_State
                                                                   @note This parameter is valid only in PWM1 and PWM2 mode. */
                                    
                                      uint32_t OCIdleState;   /*!< Specifies the TIM Output Compare pin state during Idle state.
                                                                   This parameter can be a value of @ref TIM_Output_Compare_Idle_State. */
                                    } TIM_OC_InitTypeDef;
                                    
                                    /**
                                      * @brief  TIM One Pulse Mode Configuration Structure definition
                                      */
                                    typedef struct
                                    {
                                      uint32_t OCMode;        /*!< Specifies the TIM mode.
                                                                   This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */
                                    
                                      uint32_t Pulse;         /*!< Specifies the pulse value to be loaded into the Capture Compare Register.
                                                                   This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */
                                    
                                      uint32_t OCPolarity;    /*!< Specifies the output polarity.
                                                                   This parameter can be a value of @ref TIM_Output_Compare_Polarity */
                                    
                                      uint32_t OCIdleState;   /*!< Specifies the TIM Output Compare pin state during Idle state.
                                                                   This parameter can be a value of @ref TIM_Output_Compare_Idle_State. */
                                    
                                      uint32_t ICPolarity;    /*!< Specifies the active edge of the input signal.
                                                                   This parameter can be a value of @ref TIM_Input_Capture_Polarity */
                                    
                                      uint32_t ICSelection;   /*!< Specifies the input.
                                                                  This parameter can be a value of @ref TIM_Input_Capture_Selection */
                                    
                                      uint32_t ICFilter;      /*!< Specifies the input capture filter.
                                                                  This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
                                    } TIM_OnePulse_InitTypeDef;
                                    
                                    
                                    /**
                                      * @brief  TIM Input Capture Configuration Structure definition
                                      */
                                    typedef struct
                                    {
                                      uint32_t  ICPolarity;  /*!< Specifies the active edge of the input signal.
                                                                   This parameter can be a value of @ref TIM_Input_Capture_Polarity */
                                    
                                      uint32_t ICSelection;  /*!< Specifies the input.
                                                                  This parameter can be a value of @ref TIM_Input_Capture_Selection */
                                    
                                      uint32_t ICPrescaler;  /*!< Specifies the Input Capture Prescaler.
                                                                  This parameter can be a value of @ref TIM_Input_Capture_Prescaler */
                                    
                                      uint32_t ICFilter;     /*!< Specifies the input capture filter.
                                                                  This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
                                    } TIM_IC_InitTypeDef;
                                    
                                    /**
                                      * @brief  TIM Encoder Configuration Structure definition
                                      */
                                    typedef struct
                                    {
                                      uint32_t EncoderMode;   /*!< Specifies the active edge of the input signal.
                                                                   This parameter can be a value of @ref TIM_Encoder_Mode */
                                    
                                      uint32_t IC1Polarity;   /*!< Specifies the active edge of the input signal.
                                                                   This parameter can be a value of @ref TIM_Input_Capture_Polarity */
                                    
                                      uint32_t IC1Selection;  /*!< Specifies the input.
                                                                   This parameter can be a value of @ref TIM_Input_Capture_Selection */
                                    
                                      uint32_t IC1Prescaler;  /*!< Specifies the Input Capture Prescaler.
                                                                   This parameter can be a value of @ref TIM_Input_Capture_Prescaler */
                                    
                                      uint32_t IC1Filter;     /*!< Specifies the input capture filter.
                                                                   This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
                                    
                                      uint32_t IC2Polarity;   /*!< Specifies the active edge of the input signal.
                                                                   This parameter can be a value of @ref TIM_Input_Capture_Polarity */
                                    
                                      uint32_t IC2Selection;  /*!< Specifies the input.
                                                                  This parameter can be a value of @ref TIM_Input_Capture_Selection */
                                    
                                      uint32_t IC2Prescaler;  /*!< Specifies the Input Capture Prescaler.
                                                                   This parameter can be a value of @ref TIM_Input_Capture_Prescaler */
                                    
                                      uint32_t IC2Filter;     /*!< Specifies the input capture filter.
                                                                   This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
                                    } TIM_Encoder_InitTypeDef;
                                    
                                    
                                    /**
                                      * @brief  TIM Clock Configuration Handle Structure definition
                                      */
                                    typedef struct
                                    {
                                      uint32_t ClockSource;     /*!< TIM clock sources
                                                                     This parameter can be a value of @ref TIM_Clock_Source */
                                      uint32_t ClockPolarity;   /*!< TIM clock polarity
                                                                     This parameter can be a value of @ref TIM_Clock_Polarity */
                                      uint32_t ClockPrescaler;  /*!< TIM clock prescaler
                                                                     This parameter can be a value of @ref TIM_Clock_Prescaler */
                                      uint32_t ClockFilter;     /*!< TIM clock filter
                                                                    This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
                                    }TIM_ClockConfigTypeDef;
                                    
                                    /**
                                      * @brief  TIM Clear Input Configuration Handle Structure definition
                                      */
                                    typedef struct
                                    {
                                      uint32_t ClearInputState;      /*!< TIM clear Input state
                                                                          This parameter can be ENABLE or DISABLE */
                                      uint32_t ClearInputSource;     /*!< TIM clear Input sources
                                                                          This parameter can be a value of @ref TIM_ClearInput_Source */
                                      uint32_t ClearInputPolarity;   /*!< TIM Clear Input polarity
                                                                          This parameter can be a value of @ref TIM_ClearInput_Polarity */
                                      uint32_t ClearInputPrescaler;  /*!< TIM Clear Input prescaler
                                                                          This parameter can be a value of @ref TIM_ClearInput_Prescaler */
                                      uint32_t ClearInputFilter;     /*!< TIM Clear Input filter
                                                                         This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
                                    }TIM_ClearInputConfigTypeDef;
                                    
                                    /**
                                      * @brief  TIM Slave configuration Structure definition
                                      */
                                    typedef struct {
                                      uint32_t  SlaveMode;         /*!< Slave mode selection
                                                                      This parameter can be a value of @ref TIM_Slave_Mode */
                                      uint32_t  InputTrigger;      /*!< Input Trigger source
                                                                      This parameter can be a value of @ref TIM_Trigger_Selection */
                                      uint32_t  TriggerPolarity;   /*!< Input Trigger polarity
                                                                      This parameter can be a value of @ref TIM_Trigger_Polarity */
                                      uint32_t  TriggerPrescaler;  /*!< Input trigger prescaler
                                                                      This parameter can be a value of @ref TIM_Trigger_Prescaler */
                                      uint32_t  TriggerFilter;     /*!< Input trigger filter
                                                                      This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */
                                    
                                    }TIM_SlaveConfigTypeDef;
                                    
                                    /**
                                      * @brief  HAL State structures definition
                                      */
                                    typedef enum
                                    {
                                      HAL_TIM_STATE_RESET             = 0x00,    /*!< Peripheral not yet initialized or disabled  */
                                      HAL_TIM_STATE_READY             = 0x01,    /*!< Peripheral Initialized and ready for use    */
                                      HAL_TIM_STATE_BUSY              = 0x02,    /*!< An internal process is ongoing              */
                                      HAL_TIM_STATE_TIMEOUT           = 0x03,    /*!< Timeout state                               */
                                      HAL_TIM_STATE_ERROR             = 0x04     /*!< Reception process is ongoing                */
                                    }HAL_TIM_StateTypeDef;
                                    
                                    /**
                                      * @brief  HAL Active channel structures definition
                                      */
                                    typedef enum
                                    {
                                      HAL_TIM_ACTIVE_CHANNEL_1        = 0x01,    /*!< The active channel is 1     */
                                      HAL_TIM_ACTIVE_CHANNEL_2        = 0x02,    /*!< The active channel is 2     */
                                      HAL_TIM_ACTIVE_CHANNEL_3        = 0x04,    /*!< The active channel is 3     */
                                      HAL_TIM_ACTIVE_CHANNEL_4        = 0x08,    /*!< The active channel is 4     */
                                      HAL_TIM_ACTIVE_CHANNEL_CLEARED  = 0x00     /*!< All active channels cleared */
                                    }HAL_TIM_ActiveChannel;
                                    
                                    /**
                                      * @brief  TIM Time Base Handle Structure definition
                                      */
                                    typedef struct
                                    {
                                      TIM_TypeDef              *Instance;     /*!< Register base address             */
                                      TIM_Base_InitTypeDef     Init;          /*!< TIM Time Base required parameters */
                                      HAL_TIM_ActiveChannel    Channel;       /*!< Active channel                    */
                                      DMA_HandleTypeDef        *hdma[7];      /*!< DMA Handlers array
                                                                                 This array is accessed by a @ref TIM_DMA_Handle_index */
                                      HAL_LockTypeDef          Lock;          /*!< Locking object                    */
                                      __IO HAL_TIM_StateTypeDef   State;      /*!< TIM operation state               */
                                    }TIM_HandleTypeDef;
                                    
                                    /**
                                      * @}
                                      */
                                    
                                    /* Exported constants --------------------------------------------------------*/
                                    /** @defgroup TIM_Exported_Constants TIM Exported Constants
                                      * @{
                                      */
                                    
                                    /** @defgroup TIM_Input_Channel_Polarity TIM Input Channel Polarity
                                      * @{
                                      */
                                    #define  TIM_INPUTCHANNELPOLARITY_RISING      (0x00000000U)                     /*!< Polarity for TIx source */
                                    #define  TIM_INPUTCHANNELPOLARITY_FALLING     (TIM_CCER_CC1P)                   /*!< Polarity for TIx source */
                                    #define  TIM_INPUTCHANNELPOLARITY_BOTHEDGE    (TIM_CCER_CC1P | TIM_CCER_CC1NP)  /*!< Polarity for TIx source */
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_ETR_Polarity TIM ETR Polarity
                                      * @{
                                      */
                                    #define TIM_ETRPOLARITY_INVERTED              (TIM_SMCR_ETP)                    /*!< Polarity for ETR source */
                                    #define TIM_ETRPOLARITY_NONINVERTED           (0x0000U)                         /*!< Polarity for ETR source */
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_ETR_Prescaler TIM ETR Prescaler
                                      * @{
                                      */
                                    #define TIM_ETRPRESCALER_DIV1                 (0x0000U)                         /*!< No prescaler is used */
                                    #define TIM_ETRPRESCALER_DIV2                 (TIM_SMCR_ETPS_0)                 /*!< ETR input source is divided by 2 */
                                    #define TIM_ETRPRESCALER_DIV4                 (TIM_SMCR_ETPS_1)                 /*!< ETR input source is divided by 4 */
                                    #define TIM_ETRPRESCALER_DIV8                 (TIM_SMCR_ETPS)                   /*!< ETR input source is divided by 8 */
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Counter_Mode TIM Counter Mode
                                      * @{
                                      */
                                    #define TIM_COUNTERMODE_UP                 (0x0000U)
                                    #define TIM_COUNTERMODE_DOWN               TIM_CR1_DIR
                                    #define TIM_COUNTERMODE_CENTERALIGNED1     TIM_CR1_CMS_0
                                    #define TIM_COUNTERMODE_CENTERALIGNED2     TIM_CR1_CMS_1
                                    #define TIM_COUNTERMODE_CENTERALIGNED3     TIM_CR1_CMS
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_ClockDivision TIM ClockDivision
                                      * @{
                                      */
                                    #define TIM_CLOCKDIVISION_DIV1                       (0x0000U)
                                    #define TIM_CLOCKDIVISION_DIV2                       (TIM_CR1_CKD_0)
                                    #define TIM_CLOCKDIVISION_DIV4                       (TIM_CR1_CKD_1)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Output_Compare_and_PWM_modes TIM Output Compare and PWM modes
                                      * @{
                                      */
                                    #define TIM_OCMODE_TIMING                   (0x0000U)
                                    #define TIM_OCMODE_ACTIVE                   (TIM_CCMR1_OC1M_0)
                                    #define TIM_OCMODE_INACTIVE                 (TIM_CCMR1_OC1M_1)
                                    #define TIM_OCMODE_TOGGLE                   (TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_1)
                                    #define TIM_OCMODE_PWM1                     (TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2)
                                    #define TIM_OCMODE_PWM2                     (TIM_CCMR1_OC1M)
                                    #define TIM_OCMODE_FORCED_ACTIVE            (TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_2)
                                    #define TIM_OCMODE_FORCED_INACTIVE          (TIM_CCMR1_OC1M_2)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Output_Fast_State TIM Output Fast State
                                      * @{
                                      */
                                    #define TIM_OCFAST_DISABLE                (0x0000U)
                                    #define TIM_OCFAST_ENABLE                 (TIM_CCMR1_OC1FE)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Output_Compare_Polarity TIM Output Compare Polarity
                                      * @{
                                      */
                                    #define TIM_OCPOLARITY_HIGH                (0x0000U)
                                    #define TIM_OCPOLARITY_LOW                 (TIM_CCER_CC1P)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Output_Compare_Idle_State TIM Output Compare Idle State
                                      * @{
                                      */
                                    #define TIM_OCIDLESTATE_SET                (TIM_CR2_OIS1)
                                    #define TIM_OCIDLESTATE_RESET              (0x0000U)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Channel TIM Channel
                                      * @{
                                      */
                                    #define TIM_CHANNEL_1                      (0x0000U)
                                    #define TIM_CHANNEL_2                      (0x0004U)
                                    #define TIM_CHANNEL_3                      (0x0008U)
                                    #define TIM_CHANNEL_4                      (0x000CU)
                                    #define TIM_CHANNEL_ALL                    (0x0018U)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Input_Capture_Polarity TIM Input Capture Polarity
                                      * @{
                                      */
                                    #define  TIM_ICPOLARITY_RISING             TIM_INPUTCHANNELPOLARITY_RISING
                                    #define  TIM_ICPOLARITY_FALLING            TIM_INPUTCHANNELPOLARITY_FALLING
                                    #define  TIM_ICPOLARITY_BOTHEDGE           TIM_INPUTCHANNELPOLARITY_BOTHEDGE
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Input_Capture_Selection TIM Input Capture Selection
                                      * @{
                                      */
                                    #define TIM_ICSELECTION_DIRECTTI           (TIM_CCMR1_CC1S_0)   /*!< TIM Input 1, 2, 3 or 4 is selected to be
                                                                                                                   connected to IC1, IC2, IC3 or IC4, respectively */
                                    #define TIM_ICSELECTION_INDIRECTTI         (TIM_CCMR1_CC1S_1)   /*!< TIM Input 1, 2, 3 or 4 is selected to be
                                                                                                                   connected to IC2, IC1, IC4 or IC3, respectively */
                                    #define TIM_ICSELECTION_TRC                (TIM_CCMR1_CC1S)     /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to TRC */
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Input_Capture_Prescaler TIM Input Capture Prescaler
                                      * @{
                                      */
                                    #define TIM_ICPSC_DIV1                     (0x0000U)                /*!< Capture performed each time an edge is detected on the capture input */
                                    #define TIM_ICPSC_DIV2                     (TIM_CCMR1_IC1PSC_0)     /*!< Capture performed once every 2 events */
                                    #define TIM_ICPSC_DIV4                     (TIM_CCMR1_IC1PSC_1)     /*!< Capture performed once every 4 events */
                                    #define TIM_ICPSC_DIV8                     (TIM_CCMR1_IC1PSC)       /*!< Capture performed once every 8 events */
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_One_Pulse_Mode TIM One Pulse Mode
                                      * @{
                                      */
                                    #define TIM_OPMODE_SINGLE                  (TIM_CR1_OPM)
                                    #define TIM_OPMODE_REPETITIVE              (0x0000U)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Encoder_Mode TIM Encoder Mode
                                      * @{
                                      */
                                    #define TIM_ENCODERMODE_TI1                (TIM_SMCR_SMS_0)
                                    #define TIM_ENCODERMODE_TI2                (TIM_SMCR_SMS_1)
                                    #define TIM_ENCODERMODE_TI12               (TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Interrupt_definition TIM Interrupt Definition
                                      * @{
                                      */
                                    #define TIM_IT_UPDATE           (TIM_DIER_UIE)
                                    #define TIM_IT_CC1              (TIM_DIER_CC1IE)
                                    #define TIM_IT_CC2              (TIM_DIER_CC2IE)
                                    #define TIM_IT_CC3              (TIM_DIER_CC3IE)
                                    #define TIM_IT_CC4              (TIM_DIER_CC4IE)
                                    #define TIM_IT_TRIGGER          (TIM_DIER_TIE)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_DMA_sources TIM DMA Sources
                                      * @{
                                      */
                                    #define TIM_DMA_UPDATE                     (TIM_DIER_UDE)
                                    #define TIM_DMA_CC1                        (TIM_DIER_CC1DE)
                                    #define TIM_DMA_CC2                        (TIM_DIER_CC2DE)
                                    #define TIM_DMA_CC3                        (TIM_DIER_CC3DE)
                                    #define TIM_DMA_CC4                        (TIM_DIER_CC4DE)
                                    #define TIM_DMA_TRIGGER                    (TIM_DIER_TDE)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Event_Source TIM Event Source
                                      * @{
                                      */
                                    #define TIM_EVENTSOURCE_UPDATE              TIM_EGR_UG
                                    #define TIM_EVENTSOURCE_CC1                 TIM_EGR_CC1G
                                    #define TIM_EVENTSOURCE_CC2                 TIM_EGR_CC2G
                                    #define TIM_EVENTSOURCE_CC3                 TIM_EGR_CC3G
                                    #define TIM_EVENTSOURCE_CC4                 TIM_EGR_CC4G
                                    #define TIM_EVENTSOURCE_TRIGGER             TIM_EGR_TG
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Flag_definition TIM Flag Definition
                                      * @{
                                      */
                                    #define TIM_FLAG_UPDATE                    (TIM_SR_UIF)
                                    #define TIM_FLAG_CC1                       (TIM_SR_CC1IF)
                                    #define TIM_FLAG_CC2                       (TIM_SR_CC2IF)
                                    #define TIM_FLAG_CC3                       (TIM_SR_CC3IF)
                                    #define TIM_FLAG_CC4                       (TIM_SR_CC4IF)
                                    #define TIM_FLAG_TRIGGER                   (TIM_SR_TIF)
                                    #define TIM_FLAG_CC1OF                     (TIM_SR_CC1OF)
                                    #define TIM_FLAG_CC2OF                     (TIM_SR_CC2OF)
                                    #define TIM_FLAG_CC3OF                     (TIM_SR_CC3OF)
                                    #define TIM_FLAG_CC4OF                     (TIM_SR_CC4OF)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Clock_Source TIM Clock Source
                                      * @{
                                      */
                                    #define  TIM_CLOCKSOURCE_ETRMODE2    (TIM_SMCR_ETPS_1)
                                    #define  TIM_CLOCKSOURCE_INTERNAL    (TIM_SMCR_ETPS_0)
                                    #define  TIM_CLOCKSOURCE_ITR0        (0x0000U)
                                    #define  TIM_CLOCKSOURCE_ITR1        (TIM_SMCR_TS_0)
                                    #define  TIM_CLOCKSOURCE_ITR2        (TIM_SMCR_TS_1)
                                    #define  TIM_CLOCKSOURCE_ITR3        (TIM_SMCR_TS_0 | TIM_SMCR_TS_1)
                                    #define  TIM_CLOCKSOURCE_TI1ED       (TIM_SMCR_TS_2)
                                    #define  TIM_CLOCKSOURCE_TI1         (TIM_SMCR_TS_0 | TIM_SMCR_TS_2)
                                    #define  TIM_CLOCKSOURCE_TI2         (TIM_SMCR_TS_1 | TIM_SMCR_TS_2)
                                    #define  TIM_CLOCKSOURCE_ETRMODE1    (TIM_SMCR_TS)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Clock_Polarity TIM Clock Polarity
                                      * @{
                                      */
                                    #define TIM_CLOCKPOLARITY_INVERTED           TIM_ETRPOLARITY_INVERTED           /*!< Polarity for ETRx clock sources */
                                    #define TIM_CLOCKPOLARITY_NONINVERTED        TIM_ETRPOLARITY_NONINVERTED        /*!< Polarity for ETRx clock sources */
                                    #define TIM_CLOCKPOLARITY_RISING             TIM_INPUTCHANNELPOLARITY_RISING    /*!< Polarity for TIx clock sources */
                                    #define TIM_CLOCKPOLARITY_FALLING            TIM_INPUTCHANNELPOLARITY_FALLING   /*!< Polarity for TIx clock sources */
                                    #define TIM_CLOCKPOLARITY_BOTHEDGE           TIM_INPUTCHANNELPOLARITY_BOTHEDGE  /*!< Polarity for TIx clock sources */
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Clock_Prescaler TIM Clock Prescaler
                                      * @{
                                      */
                                    #define TIM_CLOCKPRESCALER_DIV1                 TIM_ETRPRESCALER_DIV1     /*!< No prescaler is used */
                                    #define TIM_CLOCKPRESCALER_DIV2                 TIM_ETRPRESCALER_DIV2     /*!< Prescaler for External ETR Clock: Capture performed once every 2 events. */
                                    #define TIM_CLOCKPRESCALER_DIV4                 TIM_ETRPRESCALER_DIV4     /*!< Prescaler for External ETR Clock: Capture performed once every 4 events. */
                                    #define TIM_CLOCKPRESCALER_DIV8                 TIM_ETRPRESCALER_DIV8     /*!< Prescaler for External ETR Clock: Capture performed once every 8 events. */
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_ClearInput_Source TIM ClearInput Source
                                      * @{
                                      */
                                    #define TIM_CLEARINPUTSOURCE_ETR            (0x0001U) 
                                    #define TIM_CLEARINPUTSOURCE_OCREFCLR       (0x0002U) 
                                    #define TIM_CLEARINPUTSOURCE_NONE           (0x0000U)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_ClearInput_Polarity TIM ClearInput Polarity
                                      * @{
                                      */
                                    #define TIM_CLEARINPUTPOLARITY_INVERTED           TIM_ETRPOLARITY_INVERTED               /*!< Polarity for ETRx pin */
                                    #define TIM_CLEARINPUTPOLARITY_NONINVERTED        TIM_ETRPOLARITY_NONINVERTED            /*!< Polarity for ETRx pin */
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_ClearInput_Prescaler TIM ClearInput Prescaler
                                      * @{
                                      */
                                    #define TIM_CLEARINPUTPRESCALER_DIV1                    TIM_ETRPRESCALER_DIV1      /*!< No prescaler is used */
                                    #define TIM_CLEARINPUTPRESCALER_DIV2                    TIM_ETRPRESCALER_DIV2      /*!< Prescaler for External ETR pin: Capture performed once every 2 events. */
                                    #define TIM_CLEARINPUTPRESCALER_DIV4                    TIM_ETRPRESCALER_DIV4      /*!< Prescaler for External ETR pin: Capture performed once every 4 events. */
                                    #define TIM_CLEARINPUTPRESCALER_DIV8                    TIM_ETRPRESCALER_DIV8      /*!< Prescaler for External ETR pin: Capture performed once every 8 events. */
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_OSSR_Off_State_Selection_for_Run_mode_state TIM OSSR Off State Selection for Run mode state
                                      * @{
                                      */
                                    #define TIM_OSSR_ENABLE         (TIM_BDTR_OSSR)
                                    #define TIM_OSSR_DISABLE        (0x0000U)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_OSSI_Off_State_Selection_for_Idle_mode_state TIM OSSI Off State Selection for Idle mode state
                                      * @{
                                      */
                                    #define TIM_OSSI_ENABLE         (TIM_BDTR_OSSI)
                                    #define TIM_OSSI_DISABLE        (0x0000U)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Lock_level TIM Lock level
                                      * @{
                                      */
                                    #define TIM_LOCKLEVEL_OFF       (0x0000U)
                                    #define TIM_LOCKLEVEL_1         (TIM_BDTR_LOCK_0)
                                    #define TIM_LOCKLEVEL_2         (TIM_BDTR_LOCK_1)
                                    #define TIM_LOCKLEVEL_3         (TIM_BDTR_LOCK)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_AOE_Bit_Set_Reset TIM Automatic Output Enable
                                      * @{
                                      */
                                    #define TIM_AUTOMATICOUTPUT_ENABLE           (TIM_BDTR_AOE)
                                    #define TIM_AUTOMATICOUTPUT_DISABLE          (0x0000U)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Master_Mode_Selection TIM Master Mode Selection
                                      * @{
                                      */
                                    #define  TIM_TRGO_RESET            (0x0000U)
                                    #define  TIM_TRGO_ENABLE           (TIM_CR2_MMS_0)
                                    #define  TIM_TRGO_UPDATE           (TIM_CR2_MMS_1)
                                    #define  TIM_TRGO_OC1              ((TIM_CR2_MMS_1 | TIM_CR2_MMS_0))
                                    #define  TIM_TRGO_OC1REF           (TIM_CR2_MMS_2)
                                    #define  TIM_TRGO_OC2REF           ((TIM_CR2_MMS_2 | TIM_CR2_MMS_0))
                                    #define  TIM_TRGO_OC3REF           ((TIM_CR2_MMS_2 | TIM_CR2_MMS_1))
                                    #define  TIM_TRGO_OC4REF           ((TIM_CR2_MMS_2 | TIM_CR2_MMS_1 | TIM_CR2_MMS_0))
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Slave_Mode TIM Slave Mode
                                      * @{
                                      */
                                    #define TIM_SLAVEMODE_DISABLE              (0x0000U)
                                    #define TIM_SLAVEMODE_RESET                (0x0004U)
                                    #define TIM_SLAVEMODE_GATED                (0x0005U)
                                    #define TIM_SLAVEMODE_TRIGGER              (0x0006U)
                                    #define TIM_SLAVEMODE_EXTERNAL1            (0x0007U)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Master_Slave_Mode TIM Master Slave Mode
                                      * @{
                                      */
                                    #define TIM_MASTERSLAVEMODE_ENABLE          (0x0080U)
                                    #define TIM_MASTERSLAVEMODE_DISABLE         (0x0000U)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Trigger_Selection TIM Trigger Selection
                                      * @{
                                      */
                                    #define TIM_TS_ITR0                        (0x0000U)
                                    #define TIM_TS_ITR1                        (0x0010U)
                                    #define TIM_TS_ITR2                        (0x0020U)
                                    #define TIM_TS_ITR3                        (0x0030U)
                                    #define TIM_TS_TI1F_ED                     (0x0040U)
                                    #define TIM_TS_TI1FP1                      (0x0050U)
                                    #define TIM_TS_TI2FP2                      (0x0060U)
                                    #define TIM_TS_ETRF                        (0x0070U)
                                    #define TIM_TS_NONE                        (0xFFFFU)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Trigger_Polarity TIM Trigger Polarity
                                      * @{
                                      */
                                    #define TIM_TRIGGERPOLARITY_INVERTED           TIM_ETRPOLARITY_INVERTED            /*!< Polarity for ETRx trigger sources */
                                    #define TIM_TRIGGERPOLARITY_NONINVERTED        TIM_ETRPOLARITY_NONINVERTED         /*!< Polarity for ETRx trigger sources */
                                    #define TIM_TRIGGERPOLARITY_RISING             TIM_INPUTCHANNELPOLARITY_RISING     /*!< Polarity for TIxFPx or TI1_ED trigger sources */
                                    #define TIM_TRIGGERPOLARITY_FALLING            TIM_INPUTCHANNELPOLARITY_FALLING    /*!< Polarity for TIxFPx or TI1_ED trigger sources */
                                    #define TIM_TRIGGERPOLARITY_BOTHEDGE           TIM_INPUTCHANNELPOLARITY_BOTHEDGE   /*!< Polarity for TIxFPx or TI1_ED trigger sources */
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Trigger_Prescaler TIM Trigger Prescaler
                                      * @{
                                      */
                                    #define TIM_TRIGGERPRESCALER_DIV1             TIM_ETRPRESCALER_DIV1     /*!< No prescaler is used */
                                    #define TIM_TRIGGERPRESCALER_DIV2             TIM_ETRPRESCALER_DIV2     /*!< Prescaler for External ETR Trigger: Capture performed once every 2 events. */
                                    #define TIM_TRIGGERPRESCALER_DIV4             TIM_ETRPRESCALER_DIV4     /*!< Prescaler for External ETR Trigger: Capture performed once every 4 events. */
                                    #define TIM_TRIGGERPRESCALER_DIV8             TIM_ETRPRESCALER_DIV8     /*!< Prescaler for External ETR Trigger: Capture performed once every 8 events. */
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_TI1_Selection TIM TI1 Input Selection
                                      * @{
                                      */
                                    #define TIM_TI1SELECTION_CH1                (0x0000U)
                                    #define TIM_TI1SELECTION_XORCOMBINATION     (TIM_CR2_TI1S)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_DMA_Base_address TIM DMA Base Address
                                      * @{
                                      */
                                    #define TIM_DMABASE_CR1                    (0x00000000U)
                                    #define TIM_DMABASE_CR2                    (0x00000001U)
                                    #define TIM_DMABASE_SMCR                   (0x00000002U)
                                    #define TIM_DMABASE_DIER                   (0x00000003U)
                                    #define TIM_DMABASE_SR                     (0x00000004U)
                                    #define TIM_DMABASE_EGR                    (0x00000005U)
                                    #define TIM_DMABASE_CCMR1                  (0x00000006U)
                                    #define TIM_DMABASE_CCMR2                  (0x00000007U)
                                    #define TIM_DMABASE_CCER                   (0x00000008U)
                                    #define TIM_DMABASE_CNT                    (0x00000009U)
                                    #define TIM_DMABASE_PSC                    (0x0000000AU)
                                    #define TIM_DMABASE_ARR                    (0x0000000BU)
                                    #define TIM_DMABASE_CCR1                   (0x0000000DU)
                                    #define TIM_DMABASE_CCR2                   (0x0000000EU)
                                    #define TIM_DMABASE_CCR3                   (0x0000000FU)
                                    #define TIM_DMABASE_CCR4                   (0x00000010U)
                                    #define TIM_DMABASE_DCR                    (0x00000012U)
                                    #define TIM_DMABASE_OR                     (0x00000013U)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_DMA_Burst_Length TIM DMA Burst Length
                                      * @{
                                      */
                                    #define TIM_DMABURSTLENGTH_1TRANSFER           (0x00000000)
                                    #define TIM_DMABURSTLENGTH_2TRANSFERS          (0x00000100)
                                    #define TIM_DMABURSTLENGTH_3TRANSFERS          (0x00000200)
                                    #define TIM_DMABURSTLENGTH_4TRANSFERS          (0x00000300)
                                    #define TIM_DMABURSTLENGTH_5TRANSFERS          (0x00000400)
                                    #define TIM_DMABURSTLENGTH_6TRANSFERS          (0x00000500)
                                    #define TIM_DMABURSTLENGTH_7TRANSFERS          (0x00000600)
                                    #define TIM_DMABURSTLENGTH_8TRANSFERS          (0x00000700)
                                    #define TIM_DMABURSTLENGTH_9TRANSFERS          (0x00000800)
                                    #define TIM_DMABURSTLENGTH_10TRANSFERS         (0x00000900)
                                    #define TIM_DMABURSTLENGTH_11TRANSFERS         (0x00000A00)
                                    #define TIM_DMABURSTLENGTH_12TRANSFERS         (0x00000B00)
                                    #define TIM_DMABURSTLENGTH_13TRANSFERS         (0x00000C00)
                                    #define TIM_DMABURSTLENGTH_14TRANSFERS         (0x00000D00)
                                    #define TIM_DMABURSTLENGTH_15TRANSFERS         (0x00000E00)
                                    #define TIM_DMABURSTLENGTH_16TRANSFERS         (0x00000F00)
                                    #define TIM_DMABURSTLENGTH_17TRANSFERS         (0x00001000)
                                    #define TIM_DMABURSTLENGTH_18TRANSFERS         (0x00001100)
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_DMA_Handle_index TIM DMA Handle Index
                                      * @{
                                      */
                                    #define TIM_DMA_ID_UPDATE                ((uint16_t) 0x0)       /*!< Index of the DMA handle used for Update DMA requests */
                                    #define TIM_DMA_ID_CC1                   ((uint16_t) 0x1)       /*!< Index of the DMA handle used for Capture/Compare 1 DMA requests */
                                    #define TIM_DMA_ID_CC2                   ((uint16_t) 0x2)       /*!< Index of the DMA handle used for Capture/Compare 2 DMA requests */
                                    #define TIM_DMA_ID_CC3                   ((uint16_t) 0x3)       /*!< Index of the DMA handle used for Capture/Compare 3 DMA requests */
                                    #define TIM_DMA_ID_CC4                   ((uint16_t) 0x4)       /*!< Index of the DMA handle used for Capture/Compare 4 DMA requests */
                                    #define TIM_DMA_ID_TRIGGER               ((uint16_t) 0x6)       /*!< Index of the DMA handle used for Trigger DMA requests */
                                    /**
                                      * @}
                                      */
                                    
                                    /** @defgroup TIM_Channel_CC_State TIM Capture/Compare Channel State
                                      * @{
                                      */
                                    #define TIM_CCx_ENABLE                   (0x0001U)
                                    #define TIM_CCx_DISABLE                  (0x0000U)
                                    /**
                                      * @}
                                      */
                                    
                                    /**
                                      * @}
                                      */
                                    
                                    /* Private Constants -----------------------------------------------------------*/
                                    /** @defgroup TIM_Private_Constants TIM Private Constants
                                      * @{
                                      */
                                    
                                    /* The counter of a timer instance is disabled only if all the CCx
                                       channels have been disabled */
                                    #define TIM_CCER_CCxE_MASK ((uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E))
                                    /**
                                      * @}
                                      */
                                    
                                    /* Private Macros -----------------------------------------------------------*/
                                    /** @defgroup TIM_Private_Macros TIM Private Macros
                                     * @{
                                     */
                                    
                                    #define IS_TIM_COUNTER_MODE(MODE) (((MODE) == TIM_COUNTERMODE_UP)              || \
                                                                       ((MODE) == TIM_COUNTERMODE_DOWN)            || \
                                                                       ((MODE) == TIM_COUNTERMODE_CENTERALIGNED1)  || \
                                                                       ((MODE) == TIM_COUNTERMODE_CENTERALIGNED2)  || \
                                                                       ((MODE) == TIM_COUNTERMODE_CENTERALIGNED3))
                                    
                                    #define IS_TIM_CLOCKDIVISION_DIV(DIV) (((DIV) == TIM_CLOCKDIVISION_DIV1) || \
                                                                           ((DIV) == TIM_CLOCKDIVISION_DIV2) || \
                                                                           ((DIV) == TIM_CLOCKDIVISION_DIV4))
                                    
                                    #define IS_TIM_PWM_MODE(MODE) (((MODE) == TIM_OCMODE_PWM1) || \
                                                                   ((MODE) == TIM_OCMODE_PWM2))
                                    
                                    #define IS_TIM_OC_MODE(MODE) (((MODE) == TIM_OCMODE_TIMING)       || \
                                                              ((MODE) == TIM_OCMODE_ACTIVE)           || \
                                                              ((MODE) == TIM_OCMODE_INACTIVE)         || \
                                                              ((MODE) == TIM_OCMODE_TOGGLE)           || \
                                                              ((MODE) == TIM_OCMODE_FORCED_ACTIVE)    || \
                                                              ((MODE) == TIM_OCMODE_FORCED_INACTIVE))
                                    
                                    #define IS_TIM_FAST_STATE(STATE) (((STATE) == TIM_OCFAST_DISABLE) || \
                                                                      ((STATE) == TIM_OCFAST_ENABLE))
                                    
                                    #define IS_TIM_OC_POLARITY(POLARITY) (((POLARITY) == TIM_OCPOLARITY_HIGH) || \
                                                                          ((POLARITY) == TIM_OCPOLARITY_LOW))
                                    
                                    #define IS_TIM_OCIDLE_STATE(STATE) (((STATE) == TIM_OCIDLESTATE_SET) || \
                                                                        ((STATE) == TIM_OCIDLESTATE_RESET))
                                    
                                    #define IS_TIM_CHANNELS(CHANNEL) (((CHANNEL) == TIM_CHANNEL_1) || \
                                                                      ((CHANNEL) == TIM_CHANNEL_2) || \
                                                                      ((CHANNEL) == TIM_CHANNEL_3) || \
                                                                      ((CHANNEL) == TIM_CHANNEL_4) || \
                                                                      ((CHANNEL) == TIM_CHANNEL_ALL))
                                    
                                    #define IS_TIM_OPM_CHANNELS(CHANNEL) (((CHANNEL) == TIM_CHANNEL_1) || \
                                                                          ((CHANNEL) == TIM_CHANNEL_2))
                                    
                                    #define IS_TIM_IC_POLARITY(POLARITY) (((POLARITY) == TIM_ICPOLARITY_RISING)   || \
                                                                          ((POLARITY) == TIM_ICPOLARITY_FALLING)  || \
                                                                          ((POLARITY) == TIM_ICPOLARITY_BOTHEDGE))
                                    
                                    #define IS_TIM_IC_SELECTION(SELECTION) (((SELECTION) == TIM_ICSELECTION_DIRECTTI) || \
                                                                            ((SELECTION) == TIM_ICSELECTION_INDIRECTTI) || \
                                                                            ((SELECTION) == TIM_ICSELECTION_TRC))
                                    
                                    #define IS_TIM_IC_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ICPSC_DIV1) || \
                                                                            ((PRESCALER) == TIM_ICPSC_DIV2) || \
                                                                            ((PRESCALER) == TIM_ICPSC_DIV4) || \
                                                                            ((PRESCALER) == TIM_ICPSC_DIV8))
                                    
                                    #define IS_TIM_OPM_MODE(MODE) (((MODE) == TIM_OPMODE_SINGLE) || \
                                                                   ((MODE) == TIM_OPMODE_REPETITIVE))
                                    
                                    #define IS_TIM_ENCODER_MODE(MODE) (((MODE) == TIM_ENCODERMODE_TI1) || \
                                                                       ((MODE) == TIM_ENCODERMODE_TI2) || \
                                                                       ((MODE) == TIM_ENCODERMODE_TI12))
                                    
                                    #define IS_TIM_DMA_SOURCE(SOURCE) ((((SOURCE) & 0xFFFF80FFU) == 0x00000000U) && ((SOURCE) != 0x00000000U))
                                    
                                    #define IS_TIM_EVENT_SOURCE(SOURCE) ((((SOURCE) & 0xFFFFFF00U) == 0x00000000U) && ((SOURCE) != 0x00000000U))
                                    
                                    #define IS_TIM_CLOCKSOURCE(CLOCK) (((CLOCK) == TIM_CLOCKSOURCE_INTERNAL) || \
                                                                       ((CLOCK) == TIM_CLOCKSOURCE_ETRMODE2) || \
                                                                       ((CLOCK) == TIM_CLOCKSOURCE_ITR0)     || \
                                                                       ((CLOCK) == TIM_CLOCKSOURCE_ITR1)     || \
                                                                       ((CLOCK) == TIM_CLOCKSOURCE_ITR2)     || \
                                                                       ((CLOCK) == TIM_CLOCKSOURCE_ITR3)     || \
                                                                       ((CLOCK) == TIM_CLOCKSOURCE_TI1ED)    || \
                                                                       ((CLOCK) == TIM_CLOCKSOURCE_TI1)      || \
                                                                       ((CLOCK) == TIM_CLOCKSOURCE_TI2)      || \
                                                                       ((CLOCK) == TIM_CLOCKSOURCE_ETRMODE1))
                                    
                                    #define IS_TIM_CLOCKPOLARITY(POLARITY) (((POLARITY) == TIM_CLOCKPOLARITY_INVERTED)    || \
                                                                            ((POLARITY) == TIM_CLOCKPOLARITY_NONINVERTED) || \
                                                                            ((POLARITY) == TIM_CLOCKPOLARITY_RISING)      || \
                                                                            ((POLARITY) == TIM_CLOCKPOLARITY_FALLING)     || \
                                                                            ((POLARITY) == TIM_CLOCKPOLARITY_BOTHEDGE))
                                    
                                    #define IS_TIM_CLOCKPRESCALER(PRESCALER) (((PRESCALER) == TIM_CLOCKPRESCALER_DIV1) || \
                                                                              ((PRESCALER) == TIM_CLOCKPRESCALER_DIV2) || \
                                                                              ((PRESCALER) == TIM_CLOCKPRESCALER_DIV4) || \
                                                                              ((PRESCALER) == TIM_CLOCKPRESCALER_DIV8))
                                    
                                    #define IS_TIM_CLOCKFILTER(ICFILTER)      ((ICFILTER) <= 0xF)
                                    
                                    #define IS_TIM_CLEARINPUT_SOURCE(SOURCE) (((SOURCE) == TIM_CLEARINPUTSOURCE_ETR)      || \
                                                                              ((SOURCE) == TIM_CLEARINPUTSOURCE_OCREFCLR) || \
                                                                              ((SOURCE) == TIM_CLEARINPUTSOURCE_NONE))
                                    
                                    #define IS_TIM_CLEARINPUT_POLARITY(POLARITY) (((POLARITY) == TIM_CLEARINPUTPOLARITY_INVERTED) || \
                                                                                  ((POLARITY) == TIM_CLEARINPUTPOLARITY_NONINVERTED))
                                    
                                    #define IS_TIM_CLEARINPUT_PRESCALER(PRESCALER)   (((PRESCALER) == TIM_CLEARINPUTPRESCALER_DIV1) || \
                                                                                      ((PRESCALER) == TIM_CLEARINPUTPRESCALER_DIV2) || \
                                                                                      ((PRESCALER) == TIM_CLEARINPUTPRESCALER_DIV4) || \
                                                                                      ((PRESCALER) == TIM_CLEARINPUTPRESCALER_DIV8))
                                    
                                    #define IS_TIM_CLEARINPUT_FILTER(ICFILTER) ((ICFILTER) <= 0xF)
                                    
                                    #define IS_TIM_OSSR_STATE(STATE) (((STATE) == TIM_OSSR_ENABLE) || \
                                                                      ((STATE) == TIM_OSSR_DISABLE))
                                    
                                    #define IS_TIM_OSSI_STATE(STATE) (((STATE) == TIM_OSSI_ENABLE) || \
                                                                      ((STATE) == TIM_OSSI_DISABLE))
                                    
                                    #define IS_TIM_LOCK_LEVEL(LEVEL) (((LEVEL) == TIM_LOCKLEVEL_OFF) || \
                                                                      ((LEVEL) == TIM_LOCKLEVEL_1) || \
                                                                      ((LEVEL) == TIM_LOCKLEVEL_2) || \
                                                                      ((LEVEL) == TIM_LOCKLEVEL_3))
                                    
                                    #define IS_TIM_AUTOMATIC_OUTPUT_STATE(STATE) (((STATE) == TIM_AUTOMATICOUTPUT_ENABLE) || \
                                                                                  ((STATE) == TIM_AUTOMATICOUTPUT_DISABLE))
                                    
                                    #define IS_TIM_TRGO_SOURCE(SOURCE) (((SOURCE) == TIM_TRGO_RESET) || \
                                                                        ((SOURCE) == TIM_TRGO_ENABLE) || \
                                                                        ((SOURCE) == TIM_TRGO_UPDATE) || \
                                                                        ((SOURCE) == TIM_TRGO_OC1) || \
                                                                        ((SOURCE) == TIM_TRGO_OC1REF) || \
                                                                        ((SOURCE) == TIM_TRGO_OC2REF) || \
                                                                        ((SOURCE) == TIM_TRGO_OC3REF) || \
                                                                        ((SOURCE) == TIM_TRGO_OC4REF))
                                    
                                    #define IS_TIM_SLAVE_MODE(MODE) (((MODE) == TIM_SLAVEMODE_DISABLE) || \
                                                                     ((MODE) == TIM_SLAVEMODE_GATED) || \
                                                                     ((MODE) == TIM_SLAVEMODE_RESET) || \
                                                                     ((MODE) == TIM_SLAVEMODE_TRIGGER) || \
                                                                     ((MODE) == TIM_SLAVEMODE_EXTERNAL1))
                                    
                                    #define IS_TIM_MSM_STATE(STATE) (((STATE) == TIM_MASTERSLAVEMODE_ENABLE) || \
                                                                     ((STATE) == TIM_MASTERSLAVEMODE_DISABLE))
                                    
                                    #define IS_TIM_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \
                                                                                 ((SELECTION) == TIM_TS_ITR1) || \
                                                                                 ((SELECTION) == TIM_TS_ITR2) || \
                                                                                 ((SELECTION) == TIM_TS_ITR3) || \
                                                                                 ((SELECTION) == TIM_TS_TI1F_ED) || \
                                                                                 ((SELECTION) == TIM_TS_TI1FP1) || \
                                                                                 ((SELECTION) == TIM_TS_TI2FP2) || \
                                                                                 ((SELECTION) == TIM_TS_ETRF))
                                    
                                    #define IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \
                                                                                               ((SELECTION) == TIM_TS_ITR1) || \
                                                                                               ((SELECTION) == TIM_TS_ITR2) || \
                                                                                               ((SELECTION) == TIM_TS_ITR3) || \
                                                                                               ((SELECTION) == TIM_TS_NONE))
                                    
                                    #define IS_TIM_TRIGGERPOLARITY(POLARITY)     (((POLARITY) == TIM_TRIGGERPOLARITY_INVERTED   ) || \
                                                                                  ((POLARITY) == TIM_TRIGGERPOLARITY_NONINVERTED) || \
                                                                                  ((POLARITY) == TIM_TRIGGERPOLARITY_RISING     ) || \
                                                                                  ((POLARITY) == TIM_TRIGGERPOLARITY_FALLING    ) || \
                                                                                  ((POLARITY) == TIM_TRIGGERPOLARITY_BOTHEDGE   ))
                                    
                                    #define IS_TIM_TRIGGERPRESCALER(PRESCALER)  (((PRESCALER) == TIM_TRIGGERPRESCALER_DIV1) || \
                                                                                 ((PRESCALER) == TIM_TRIGGERPRESCALER_DIV2) || \
                                                                                 ((PRESCALER) == TIM_TRIGGERPRESCALER_DIV4) || \
                                                                                 ((PRESCALER) == TIM_TRIGGERPRESCALER_DIV8))
                                    
                                    #define IS_TIM_TRIGGERFILTER(ICFILTER)     ((ICFILTER) <= 0xF)
                                    
                                    #define IS_TIM_TI1SELECTION(TI1SELECTION)   (((TI1SELECTION) == TIM_TI1SELECTION_CH1) || \
                                                                                 ((TI1SELECTION) == TIM_TI1SELECTION_XORCOMBINATION))
                                    
                                    #define IS_TIM_DMA_BASE(BASE) (((BASE) == TIM_DMABASE_CR1)   || \
                                                                   ((BASE) == TIM_DMABASE_CR2)   || \
                                                                   ((BASE) == TIM_DMABASE_SMCR)  || \
                                                                   ((BASE) == TIM_DMABASE_DIER)  || \
                                                                   ((BASE) == TIM_DMABASE_SR)    || \
                                                                   ((BASE) == TIM_DMABASE_EGR)   || \
                                                                   ((BASE) == TIM_DMABASE_CCMR1) || \
                                                                   ((BASE) == TIM_DMABASE_CCMR2) || \
                                                                   ((BASE) == TIM_DMABASE_CCER)  || \
                                                                   ((BASE) == TIM_DMABASE_CNT)   || \
                                                                   ((BASE) == TIM_DMABASE_PSC)   || \
                                                                   ((BASE) == TIM_DMABASE_ARR)   || \
                                                                   ((BASE) == TIM_DMABASE_CCR1)  || \
                                                                   ((BASE) == TIM_DMABASE_CCR2)  || \
                                                                   ((BASE) == TIM_DMABASE_CCR3)  || \
                                                                   ((BASE) == TIM_DMABASE_CCR4)  || \
                                                                   ((BASE) == TIM_DMABASE_DCR)   || \
                                                                   ((BASE) == TIM_DMABASE_OR))
                                    
                                    #define IS_TIM_DMA_LENGTH(LENGTH) (((LENGTH) == TIM_DMABURSTLENGTH_1TRANSFER) || \
                                                                       ((LENGTH) == TIM_DMABURSTLENGTH_2TRANSFERS) || \
                                                                       ((LENGTH) == TIM_DMABURSTLENGTH_3TRANSFERS) || \
                                                                       ((LENGTH) == TIM_DMABURSTLENGTH_4TRANSFERS) || \
                                                                       ((LENGTH) == TIM_DMABURSTLENGTH_5TRANSFERS) || \
                                                                       ((LENGTH) == TIM_DMABURSTLENGTH_6TRANSFERS) || \
                                                                       ((LENGTH) == TIM_DMABURSTLENGTH_7TRANSFERS) || \
                                                                       ((LENGTH) == TIM_DMABURSTLENGTH_8TRANSFERS) || \
                                                                       ((LENGTH) == TIM_DMABURSTLENGTH_9TRANSFERS) || \
                                                                       ((LENGTH) == TIM_DMABURSTLENGTH_10TRANSFERS) || \
                                                                       ((LENGTH) == TIM_DMABURSTLENGTH_11TRANSFERS) || \
                                                                       ((LENGTH) == TIM_DMABURSTLENGTH_12TRANSFERS) || \
                                                                       ((LENGTH) == TIM_DMABURSTLENGTH_13TRANSFERS) || \
                                                                       ((LENGTH) == TIM_DMABURSTLENGTH_14TRANSFERS) || \
                                                                       ((LENGTH) == TIM_DMABURSTLENGTH_15TRANSFERS) || \
                                                                       ((LENGTH) == TIM_DMABURSTLENGTH_16TRANSFERS) || \
                                                                       ((LENGTH) == TIM_DMABURSTLENGTH_17TRANSFERS) || \
                                                                       ((LENGTH) == TIM_DMABURSTLENGTH_18TRANSFERS))
                                    
                                    #define IS_TIM_IC_FILTER(ICFILTER) ((ICFILTER) <= 0xF)
                                    
                                    /** @brief Set TIM IC prescaler
                                      * @param  __HANDLE__: TIM handle
                                      * @param  __CHANNEL__: specifies TIM Channel
                                      * @param  __ICPSC__: specifies the prescaler value.
                                      * @retval None
                                      */
                                    #define TIM_SET_ICPRESCALERVALUE(__HANDLE__, __CHANNEL__, __ICPSC__) \
                                    (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 |= (__ICPSC__)) :\
                                     ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 |= ((__ICPSC__) << 8)) :\
                                     ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 |= (__ICPSC__)) :\
                                     ((__HANDLE__)->Instance->CCMR2 |= ((__ICPSC__) << 8)))
                                    
                                    /** @brief Reset TIM IC prescaler
                                      * @param  __HANDLE__: TIM handle
                                      * @param  __CHANNEL__: specifies TIM Channel
                                      * @retval None
                                      */
                                    #define TIM_RESET_ICPRESCALERVALUE(__HANDLE__, __CHANNEL__) \
                                    (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC) :\
                                     ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC) :\
                                     ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_IC3PSC) :\
                                     ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_IC4PSC))
                                    
                                    
                                    /** @brief Set TIM IC polarity
                                      * @param  __HANDLE__: TIM handle
                                      * @param  __CHANNEL__: specifies TIM Channel
                                      * @param  __POLARITY__: specifies TIM Channel Polarity
                                      * @retval None
                                      */
                                    #define TIM_SET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__, __POLARITY__) \
                                    (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCER |= (__POLARITY__)) :\
                                     ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCER |= ((__POLARITY__) << 4)) :\
                                     ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCER |= ((__POLARITY__) << 8)) :\
                                     ((__HANDLE__)->Instance->CCER |= (((__POLARITY__) << 12) & TIM_CCER_CC4P)))
                                    
                                    /** @brief Reset TIM IC polarity
                                      * @param  __HANDLE__: TIM handle
                                      * @param  __CHANNEL__: specifies TIM Channel
                                      * @retval None
                                      */
                                    #define TIM_RESET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__) \
                                    (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCER &= (uint16_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP)) :\
                                     ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCER &= (uint16_t)~(TIM_CCER_CC2P | TIM_CCER_CC2NP)) :\
                                     ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCER &= (uint16_t)~(TIM_CCER_CC3P | TIM_CCER_CC3NP)) :\
                                     ((__HANDLE__)->Instance->CCER &= (uint16_t)~TIM_CCER_CC4P))
                                    
                                    /**
                                      * @}
                                      */
                                    
                                    /* Private Functions --------------------------------------------------------*/
                                    
                                    /* Exported macros -----------------------------------------------------------*/
                                    /** @defgroup TIM_Exported_Macros TIM Exported Macros
                                      * @{
                                      */
                                    
                                    /** @brief  Reset TIM handle state
                                      * @param  __HANDLE__: TIM handle.
                                      * @retval None
                                     */
                                    #define __HAL_TIM_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_TIM_STATE_RESET)
                                    
                                    /**
                                      * @brief  Enable the TIM peripheral.
                                      * @param  __HANDLE__: TIM handle
                                      * @retval None
                                     */
                                    #define __HAL_TIM_ENABLE(__HANDLE__)                 ((__HANDLE__)->Instance->CR1|=(TIM_CR1_CEN))
                                    
                                    /**
                                      * @brief  Disable the TIM peripheral.
                                      * @param  __HANDLE__: TIM handle
                                      * @retval None
                                      */
                                    #define __HAL_TIM_DISABLE(__HANDLE__) \
                                                            do { \
                                                              if (((__HANDLE__)->Instance->CCER & TIM_CCER_CCxE_MASK) == 0) \
                                                              { \
                                                                  (__HANDLE__)->Instance->CR1 &= ~(TIM_CR1_CEN); \
                                                              } \
                                                            } while(0)
                                    
                                    /**
                                      * @brief  Enables the specified TIM interrupt.
                                      * @param  __HANDLE__: specifies the TIM Handle.
                                      * @param  __INTERRUPT__: specifies the TIM interrupt source to enable.
                                      *          This parameter can be one of the following values:
                                      *            @arg TIM_IT_UPDATE: Update interrupt
                                      *            @arg TIM_IT_CC1:   Capture/Compare 1 interrupt
                                      *            @arg TIM_IT_CC2:  Capture/Compare 2 interrupt
                                      *            @arg TIM_IT_CC3:  Capture/Compare 3 interrupt
                                      *            @arg TIM_IT_CC4:  Capture/Compare 4 interrupt
                                      *            @arg TIM_IT_COM:   Commutation interrupt
                                      *            @arg TIM_IT_TRIGGER: Trigger interrupt
                                      * @retval None
                                      */
                                    #define __HAL_TIM_ENABLE_IT(__HANDLE__, __INTERRUPT__)    ((__HANDLE__)->Instance->DIER |= (__INTERRUPT__))
                                    
                                    /**
                                      * @brief  Disables the specified TIM interrupt.
                                      * @param  __HANDLE__: specifies the TIM Handle.
                                      * @param  __INTERRUPT__: specifies the TIM interrupt source to disable.
                                      *          This parameter can be one of the following values:
                                      *            @arg TIM_IT_UPDATE: Update interrupt
                                      *            @arg TIM_IT_CC1:   Capture/Compare 1 interrupt
                                      *            @arg TIM_IT_CC2:  Capture/Compare 2 interrupt
                                      *            @arg TIM_IT_CC3:  Capture/Compare 3 interrupt
                                      *            @arg TIM_IT_CC4:  Capture/Compare 4 interrupt
                                      *            @arg TIM_IT_COM:   Commutation interrupt
                                      *            @arg TIM_IT_TRIGGER: Trigger interrupt
                                      * @retval None
                                      */
                                    #define __HAL_TIM_DISABLE_IT(__HANDLE__, __INTERRUPT__)   ((__HANDLE__)->Instance->DIER &= ~(__INTERRUPT__))
                                    
                                    /**
                                      * @brief  Enables the specified DMA request.
                                      * @param  __HANDLE__: specifies the TIM Handle.
                                      * @param  __DMA__: specifies the TIM DMA request to enable.
                                      *          This parameter can be one of the following values:
                                      *            @arg TIM_DMA_UPDATE: Update DMA request
                                      *            @arg TIM_DMA_CC1:   Capture/Compare 1 DMA request
                                      *            @arg TIM_DMA_CC2:  Capture/Compare 2 DMA request
                                      *            @arg TIM_DMA_CC3:  Capture/Compare 3 DMA request
                                      *            @arg TIM_DMA_CC4:  Capture/Compare 4 DMA request
                                      *            @arg TIM_DMA_COM:   Commutation DMA request
                                      *            @arg TIM_DMA_TRIGGER: Trigger DMA request
                                      * @retval None
                                      */
                                    #define __HAL_TIM_ENABLE_DMA(__HANDLE__, __DMA__)         ((__HANDLE__)->Instance->DIER |= (__DMA__))
                                    
                                    /**
                                      * @brief  Disables the specified DMA request.
                                      * @param  __HANDLE__: specifies the TIM Handle.
                                      * @param  __DMA__: specifies the TIM DMA request to disable.
                                      *          This parameter can be one of the following values:
                                      *            @arg TIM_DMA_UPDATE: Update DMA request
                                      *            @arg TIM_DMA_CC1:   Capture/Compare 1 DMA request
                                      *            @arg TIM_DMA_CC2:  Capture/Compare 2 DMA request
                                      *            @arg TIM_DMA_CC3:  Capture/Compare 3 DMA request
                                      *            @arg TIM_DMA_CC4:  Capture/Compare 4 DMA request
                                      *            @arg TIM_DMA_COM:   Commutation DMA request
                                      *            @arg TIM_DMA_TRIGGER: Trigger DMA request
                                      * @retval None
                                      */
                                    #define __HAL_TIM_DISABLE_DMA(__HANDLE__, __DMA__)        ((__HANDLE__)->Instance->DIER &= ~(__DMA__))
                                    
                                    /**
                                      * @brief  Checks whether the specified TIM interrupt flag is set or not.
                                      * @param  __HANDLE__: specifies the TIM Handle.
                                      * @param  __FLAG__: specifies the TIM interrupt flag to check.
                                      *        This parameter can be one of the following values:
                                      *            @arg TIM_FLAG_UPDATE: Update interrupt flag
                                      *            @arg TIM_FLAG_CC1: Capture/Compare 1 interrupt flag
                                      *            @arg TIM_FLAG_CC2: Capture/Compare 2 interrupt flag
                                      *            @arg TIM_FLAG_CC3: Capture/Compare 3 interrupt flag
                                      *            @arg TIM_FLAG_CC4: Capture/Compare 4 interrupt flag
                                      *            @arg TIM_FLAG_COM:  Commutation interrupt flag
                                      *            @arg TIM_FLAG_TRIGGER: Trigger interrupt flag
                                      *            @arg TIM_FLAG_CC1OF: Capture/Compare 1 overcapture flag
                                      *            @arg TIM_FLAG_CC2OF: Capture/Compare 2 overcapture flag
                                      *            @arg TIM_FLAG_CC3OF: Capture/Compare 3 overcapture flag
                                      *            @arg TIM_FLAG_CC4OF: Capture/Compare 4 overcapture flag
                                      * @retval The new state of __FLAG__ (TRUE or FALSE).
                                      */
                                    #define __HAL_TIM_GET_FLAG(__HANDLE__, __FLAG__)          (((__HANDLE__)->Instance->SR &(__FLAG__)) == (__FLAG__))
                                    
                                    /**
                                      * @brief  Clears the specified TIM interrupt flag.
                                      * @param  __HANDLE__: specifies the TIM Handle.
                                      * @param  __FLAG__: specifies the TIM interrupt flag to clear.
                                      *        This parameter can be one of the following values:
                                      *            @arg TIM_FLAG_UPDATE: Update interrupt flag
                                      *            @arg TIM_FLAG_CC1: Capture/Compare 1 interrupt flag
                                      *            @arg TIM_FLAG_CC2: Capture/Compare 2 interrupt flag
                                      *            @arg TIM_FLAG_CC3: Capture/Compare 3 interrupt flag
                                      *            @arg TIM_FLAG_CC4: Capture/Compare 4 interrupt flag
                                      *            @arg TIM_FLAG_COM:  Commutation interrupt flag
                                      *            @arg TIM_FLAG_TRIGGER: Trigger interrupt flag
                                      *            @arg TIM_FLAG_CC1OF: Capture/Compare 1 overcapture flag
                                      *            @arg TIM_FLAG_CC2OF: Capture/Compare 2 overcapture flag
                                      *            @arg TIM_FLAG_CC3OF: Capture/Compare 3 overcapture flag
                                      *            @arg TIM_FLAG_CC4OF: Capture/Compare 4 overcapture flag
                                      * @retval The new state of __FLAG__ (TRUE or FALSE).
                                      */
                                    #define __HAL_TIM_CLEAR_FLAG(__HANDLE__, __FLAG__)        ((__HANDLE__)->Instance->SR = ~(__FLAG__))
                                    
                                    /**
                                      * @brief  Checks whether the specified TIM interrupt has occurred or not.
                                      * @param  __HANDLE__: TIM handle
                                      * @param  __INTERRUPT__: specifies the TIM interrupt source to check.
                                      * @retval The state of TIM_IT (SET or RESET).
                                      */
                                    #define __HAL_TIM_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->DIER & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
                                    
                                    /**
                                      * @brief Clear the TIM interrupt pending bits
                                      * @param  __HANDLE__: TIM handle
                                      * @param  __INTERRUPT__: specifies the interrupt pending bit to clear.
                                      * @retval None
                                      */
                                    #define __HAL_TIM_CLEAR_IT(__HANDLE__, __INTERRUPT__)     ((__HANDLE__)->Instance->SR = ~(__INTERRUPT__))
                                    
                                    /**
                                      * @brief  Indicates whether or not the TIM Counter is used as downcounter
                                      * @param  __HANDLE__: TIM handle.
                                      * @retval False (Counter used as upcounter) or True (Counter used as downcounter)
                                      * @note This macro is particularly usefull to get the counting mode when the timer operates in Center-aligned mode or Encoder
                                    mode.
                                      */
                                    #define __HAL_TIM_IS_TIM_COUNTING_DOWN(__HANDLE__)            (((__HANDLE__)->Instance->CR1 & (TIM_CR1_DIR)) == (TIM_CR1_DIR))
                                    
                                    /**
                                      * @brief  Sets the TIM active prescaler register value on update event.
                                      * @param  __HANDLE__: TIM handle.
                                      * @param  __PRESC__: specifies the active prescaler register new value.
                                      * @retval None
                                      */
                                    #define __HAL_TIM_SET_PRESCALER(__HANDLE__, __PRESC__)        ((__HANDLE__)->Instance->PSC = (__PRESC__))
                                    
                                    /**
                                      * @brief  Sets the TIM Capture Compare Register value on runtime without
                                      *         calling another time ConfigChannel function.
                                      * @param  __HANDLE__: TIM handle.
                                      * @param  __CHANNEL__ : TIM Channels to be configured.
                                      *          This parameter can be one of the following values:
                                      *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
                                      *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
                                      *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
                                      *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
                                      * @param  __COMPARE__: specifies the Capture Compare register new value.
                                      * @retval None
                                      */
                                    #define __HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__) \
                                    (*(__IO uint32_t *)(&((__HANDLE__)->Instance->CCR1) + ((__CHANNEL__) >> 2)) = (__COMPARE__))
                                    
                                    /**
                                      * @brief  Gets the TIM Capture Compare Register value on runtime
                                      * @param  __HANDLE__: TIM handle.
                                      * @param  __CHANNEL__ : TIM Channel associated with the capture compare register
                                      *          This parameter can be one of the following values:
                                      *            @arg TIM_CHANNEL_1: get capture/compare 1 register value
                                      *            @arg TIM_CHANNEL_2: get capture/compare 2 register value
                                      *            @arg TIM_CHANNEL_3: get capture/compare 3 register value
                                      *            @arg TIM_CHANNEL_4: get capture/compare 4 register value
                                      * @retval None
                                      */
                                    #define __HAL_TIM_GET_COMPARE(__HANDLE__, __CHANNEL__) \
                                      (*(__IO uint32_t *)(&((__HANDLE__)->Instance->CCR1) + ((__CHANNEL__) >> 2)))
                                    
                                    /**
                                      * @brief  Sets the TIM Counter Register value on runtime.
                                      * @param  __HANDLE__: TIM handle.
                                      * @param  __COUNTER__: specifies the Counter register new value.
                                      * @retval None
                                      */
                                    #define __HAL_TIM_SET_COUNTER(__HANDLE__, __COUNTER__)  ((__HANDLE__)->Instance->CNT = (__COUNTER__))
                                    
                                    /**
                                      * @brief  Gets the TIM Counter Register value on runtime.
                                      * @param  __HANDLE__: TIM handle.
                                      * @retval None
                                      */
                                    #define __HAL_TIM_GET_COUNTER(__HANDLE__) \
                                       ((__HANDLE__)->Instance->CNT)
                                    
                                    /**
                                      * @brief  Sets the TIM Autoreload Register value on runtime without calling
                                      *         another time any Init function.
                                      * @param  __HANDLE__: TIM handle.
                                      * @param  __AUTORELOAD__: specifies the Counter register new value.
                                      * @retval None
                                      */
                                    #define __HAL_TIM_SET_AUTORELOAD(__HANDLE__, __AUTORELOAD__) \
                                                            do{                                                    \
                                                                  (__HANDLE__)->Instance->ARR = (__AUTORELOAD__);  \
                                                                  (__HANDLE__)->Init.Period = (__AUTORELOAD__);    \
                                                              } while(0)
                                    
                                    /**
                                      * @brief  Gets the TIM Autoreload Register value on runtime
                                      * @param  __HANDLE__: TIM handle.
                                      * @retval None
                                      */
                                    #define __HAL_TIM_GET_AUTORELOAD(__HANDLE__) \
                                       ((__HANDLE__)->Instance->ARR)
                                    
                                    /**
                                      * @brief  Sets the TIM Clock Division value on runtime without calling
                                      *         another time any Init function.
                                      * @param  __HANDLE__: TIM handle.
                                      * @param  __CKD__: specifies the clock division value.
                                      *          This parameter can be one of the following value:
                                      *            @arg TIM_CLOCKDIVISION_DIV1
                                      *            @arg TIM_CLOCKDIVISION_DIV2
                                      *            @arg TIM_CLOCKDIVISION_DIV4
                                      * @retval None
                                      */
                                    #define __HAL_TIM_SET_CLOCKDIVISION(__HANDLE__, __CKD__) \
                                                            do{                                                    \
                                                                  (__HANDLE__)->Instance->CR1 &= (uint16_t)(~TIM_CR1_CKD);  \
                                                                  (__HANDLE__)->Instance->CR1 |= (__CKD__);                   \
                                                                  (__HANDLE__)->Init.ClockDivision = (__CKD__);             \
                                                              } while(0)
                                    
                                    /**
                                      * @brief  Gets the TIM Clock Division value on runtime
                                      * @param  __HANDLE__: TIM handle.
                                      * @retval None
                                      */
                                    #define __HAL_TIM_GET_CLOCKDIVISION(__HANDLE__)  \
                                       ((__HANDLE__)->Instance->CR1 & TIM_CR1_CKD)
                                    
                                    /**
                                      * @brief  Sets the TIM Input Capture prescaler on runtime without calling
                                      *         another time HAL_TIM_IC_ConfigChannel() function.
                                      * @param  __HANDLE__: TIM handle.
                                      * @param  __CHANNEL__ : TIM Channels to be configured.
                                      *          This parameter can be one of the following values:
                                      *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
                                      *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
                                      *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
                                      *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
                                      * @param  __ICPSC__: specifies the Input Capture4 prescaler new value.
                                      *          This parameter can be one of the following values:
                                      *            @arg TIM_ICPSC_DIV1: no prescaler
                                      *            @arg TIM_ICPSC_DIV2: capture is done once every 2 events
                                      *            @arg TIM_ICPSC_DIV4: capture is done once every 4 events
                                      *            @arg TIM_ICPSC_DIV8: capture is done once every 8 events
                                      * @retval None
                                      */
                                    #define __HAL_TIM_SET_ICPRESCALER(__HANDLE__, __CHANNEL__, __ICPSC__) \
                                                            do{                                                    \
                                                                  TIM_RESET_ICPRESCALERVALUE((__HANDLE__), (__CHANNEL__));  \
                                                                  TIM_SET_ICPRESCALERVALUE((__HANDLE__), (__CHANNEL__), (__ICPSC__)); \
                                                              } while(0)
                                    
                                    /**
                                      * @brief  Gets the TIM Input Capture prescaler on runtime
                                      * @param  __HANDLE__: TIM handle.
                                      * @param  __CHANNEL__ : TIM Channels to be configured.
                                      *          This parameter can be one of the following values:
                                      *            @arg TIM_CHANNEL_1: get input capture 1 prescaler value
                                      *            @arg TIM_CHANNEL_2: get input capture 2 prescaler value
                                      *            @arg TIM_CHANNEL_3: get input capture 3 prescaler value
                                      *            @arg TIM_CHANNEL_4: get input capture 4 prescaler value
                                      * @retval None
                                      */
                                    #define __HAL_TIM_GET_ICPRESCALER(__HANDLE__, __CHANNEL__)  \
                                      (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 & TIM_CCMR1_IC1PSC) :\
                                       ((__CHANNEL__) == TIM_CHANNEL_2) ? (((__HANDLE__)->Instance->CCMR1 & TIM_CCMR1_IC2PSC) >> 8) :\
                                       ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 & TIM_CCMR2_IC3PSC) :\
                                       (((__HANDLE__)->Instance->CCMR2 & TIM_CCMR2_IC4PSC)) >> 8)
                                    
                                    /**
                                      * @brief  Set the Update Request Source (URS) bit of the TIMx_CR1 register
                                      * @param  __HANDLE__: TIM handle.
                                      * @note  When the USR bit of the TIMx_CR1 register is set, only counter 
                                      *        overflow/underflow generates an update interrupt or DMA request (if
                                      *        enabled)
                                      * @retval None
                                      */
                                    #define __HAL_TIM_URS_ENABLE(__HANDLE__) \
                                        ((__HANDLE__)->Instance->CR1|= (TIM_CR1_URS))
                                    
                                    /**
                                      * @brief  Reset the Update Request Source (URS) bit of the TIMx_CR1 register
                                      * @param  __HANDLE__: TIM handle.
                                      * @note  When the USR bit of the TIMx_CR1 register is reset, any of the 
                                      *        following events generate an update interrupt or DMA request (if 
                                      *        enabled):
                                      *          (+) Counter overflow/underflow
                                      *          (+) Setting the UG bit
                                      *          (+) Update generation through the slave mode controller
                                      * @retval None
                                      */
                                    #define __HAL_TIM_URS_DISABLE(__HANDLE__) \
                                          ((__HANDLE__)->Instance->CR1&=~(TIM_CR1_URS))
                                    
                                    /**
                                      * @brief  Sets the TIM Capture x input polarity on runtime.
                                      * @param  __HANDLE__: TIM handle.
                                      * @param  __CHANNEL__: TIM Channels to be configured.
                                      *          This parameter can be one of the following values:
                                      *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
                                      *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
                                      *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
                                      *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
                                      * @param  __POLARITY__: Polarity for TIx source   
                                      *            @arg TIM_INPUTCHANNELPOLARITY_RISING: Rising Edge
                                      *            @arg TIM_INPUTCHANNELPOLARITY_FALLING: Falling Edge
                                      *            @arg TIM_INPUTCHANNELPOLARITY_BOTHEDGE: Rising and Falling Edge
                                      * @note  The polarity TIM_INPUTCHANNELPOLARITY_BOTHEDGE is not authorized  for TIM Channel 4.     
                                      * @retval None
                                      */
                                    #define __HAL_TIM_SET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__, __POLARITY__)                          \
                                                           do{                                                                            \
                                                               TIM_RESET_CAPTUREPOLARITY((__HANDLE__), (__CHANNEL__));               \
                                                               TIM_SET_CAPTUREPOLARITY((__HANDLE__), (__CHANNEL__), (__POLARITY__)); \
                                                             }while(0)
                                    
                                    /**
                                      * @}
                                      */
                                    
                                    /* Include TIM HAL Extension module */
                                    #include "stm32l1xx_hal_tim_ex.h"
                                    
                                    /* Exported functions --------------------------------------------------------*/
                                    /** @addtogroup TIM_Exported_Functions
                                      * @{
                                      */
                                    
                                    /** @addtogroup TIM_Exported_Functions_Group1
                                      * @{
                                      */
                                    /* Time Base functions ********************************************************/
                                    HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim);
                                    HAL_StatusTypeDef HAL_TIM_Base_DeInit(TIM_HandleTypeDef *htim);
                                    void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim);
                                    void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *htim);
                                    /* Blocking mode: Polling */
                                    HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim);
                                    HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim);
                                    /* Non-Blocking mode: Interrupt */
                                    HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim);
                                    HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim);
                                    /* Non-Blocking mode: DMA */
                                    HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length);
                                    HAL_StatusTypeDef HAL_TIM_Base_Stop_DMA(TIM_HandleTypeDef *htim);
                                    /**
                                      * @}
                                      */
                                    
                                    /** @addtogroup TIM_Exported_Functions_Group2
                                      * @{
                                      */
                                    /* Timer Output Compare functions **********************************************/
                                    HAL_StatusTypeDef HAL_TIM_OC_Init(TIM_HandleTypeDef *htim);
                                    HAL_StatusTypeDef HAL_TIM_OC_DeInit(TIM_HandleTypeDef *htim);
                                    void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim);
                                    void HAL_TIM_OC_MspDeInit(TIM_HandleTypeDef *htim);
                                    /* Blocking mode: Polling */
                                    HAL_StatusTypeDef HAL_TIM_OC_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    HAL_StatusTypeDef HAL_TIM_OC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    /* Non-Blocking mode: Interrupt */
                                    HAL_StatusTypeDef HAL_TIM_OC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    HAL_StatusTypeDef HAL_TIM_OC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    /* Non-Blocking mode: DMA */
                                    HAL_StatusTypeDef HAL_TIM_OC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length);
                                    HAL_StatusTypeDef HAL_TIM_OC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    
                                    /**
                                      * @}
                                      */
                                    
                                    /** @addtogroup TIM_Exported_Functions_Group3
                                      * @{
                                      */
                                    /* Timer PWM functions *********************************************************/
                                    HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim);
                                    HAL_StatusTypeDef HAL_TIM_PWM_DeInit(TIM_HandleTypeDef *htim);
                                    void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim);
                                    void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef *htim);
                                    /* Blocking mode: Polling */
                                    HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    /* Non-Blocking mode: Interrupt */
                                    HAL_StatusTypeDef HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    HAL_StatusTypeDef HAL_TIM_PWM_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    /* Non-Blocking mode: DMA */
                                    HAL_StatusTypeDef HAL_TIM_PWM_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length);
                                    HAL_StatusTypeDef HAL_TIM_PWM_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    /**
                                      * @}
                                      */
                                    
                                    /** @addtogroup TIM_Exported_Functions_Group4
                                      * @{
                                      */
                                    /* Timer Input Capture functions ***********************************************/
                                    HAL_StatusTypeDef HAL_TIM_IC_Init(TIM_HandleTypeDef *htim);
                                    HAL_StatusTypeDef HAL_TIM_IC_DeInit(TIM_HandleTypeDef *htim);
                                    void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim);
                                    void HAL_TIM_IC_MspDeInit(TIM_HandleTypeDef *htim);
                                    /* Blocking mode: Polling */
                                    HAL_StatusTypeDef HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    HAL_StatusTypeDef HAL_TIM_IC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    /* Non-Blocking mode: Interrupt */
                                    HAL_StatusTypeDef HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    HAL_StatusTypeDef HAL_TIM_IC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    /* Non-Blocking mode: DMA */
                                    HAL_StatusTypeDef HAL_TIM_IC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length);
                                    HAL_StatusTypeDef HAL_TIM_IC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    /**
                                      * @}
                                      */
                                    
                                    /** @addtogroup TIM_Exported_Functions_Group5
                                      * @{
                                      */
                                    /* Timer One Pulse functions ***************************************************/
                                    HAL_StatusTypeDef HAL_TIM_OnePulse_Init(TIM_HandleTypeDef *htim, uint32_t OnePulseMode);
                                    HAL_StatusTypeDef HAL_TIM_OnePulse_DeInit(TIM_HandleTypeDef *htim);
                                    void HAL_TIM_OnePulse_MspInit(TIM_HandleTypeDef *htim);
                                    void HAL_TIM_OnePulse_MspDeInit(TIM_HandleTypeDef *htim);
                                    /* Blocking mode: Polling */
                                    HAL_StatusTypeDef HAL_TIM_OnePulse_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel);
                                    HAL_StatusTypeDef HAL_TIM_OnePulse_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel);
                                    /* Non-Blocking mode: Interrupt */
                                    HAL_StatusTypeDef HAL_TIM_OnePulse_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel);
                                    HAL_StatusTypeDef HAL_TIM_OnePulse_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel);
                                    /**
                                      * @}
                                      */
                                    
                                    /** @addtogroup TIM_Exported_Functions_Group6
                                      * @{
                                      */
                                    /* Timer Encoder functions *****************************************************/
                                    HAL_StatusTypeDef HAL_TIM_Encoder_Init(TIM_HandleTypeDef *htim,  TIM_Encoder_InitTypeDef* sConfig);
                                    HAL_StatusTypeDef HAL_TIM_Encoder_DeInit(TIM_HandleTypeDef *htim);
                                    void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim);
                                    void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef *htim);
                                     /* Blocking mode: Polling */
                                    HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    HAL_StatusTypeDef HAL_TIM_Encoder_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    /* Non-Blocking mode: Interrupt */
                                    HAL_StatusTypeDef HAL_TIM_Encoder_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    HAL_StatusTypeDef HAL_TIM_Encoder_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    /* Non-Blocking mode: DMA */
                                    HAL_StatusTypeDef HAL_TIM_Encoder_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData1, uint32_t *pData2, uint16_t Length);
                                    HAL_StatusTypeDef HAL_TIM_Encoder_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    
                                    /**
                                      * @}
                                      */
                                    
                                    /** @addtogroup TIM_Exported_Functions_Group7
                                      * @{
                                      */
                                    /* Interrupt Handler functions  **********************************************/
                                    void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim);
                                    /**
                                      * @}
                                      */
                                    
                                    /** @addtogroup TIM_Exported_Functions_Group8
                                      * @{
                                      */
                                    /* Control functions  *********************************************************/
                                    HAL_StatusTypeDef HAL_TIM_OC_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef* sConfig, uint32_t Channel);
                                    HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef* sConfig, uint32_t Channel);
                                    HAL_StatusTypeDef HAL_TIM_IC_ConfigChannel(TIM_HandleTypeDef *htim, TIM_IC_InitTypeDef* sConfig, uint32_t Channel);
                                    HAL_StatusTypeDef HAL_TIM_OnePulse_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OnePulse_InitTypeDef* sConfig, uint32_t OutputChannel,  uint32_t InputChannel);
                                    HAL_StatusTypeDef HAL_TIM_ConfigOCrefClear(TIM_HandleTypeDef *htim, TIM_ClearInputConfigTypeDef * sClearInputConfig, uint32_t Channel);
                                    HAL_StatusTypeDef HAL_TIM_ConfigClockSource(TIM_HandleTypeDef *htim, TIM_ClockConfigTypeDef * sClockSourceConfig);
                                    HAL_StatusTypeDef HAL_TIM_ConfigTI1Input(TIM_HandleTypeDef *htim, uint32_t TI1_Selection);
                                    HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchronization(TIM_HandleTypeDef *htim, TIM_SlaveConfigTypeDef * sSlaveConfig);
                                    HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchronization_IT(TIM_HandleTypeDef *htim, TIM_SlaveConfigTypeDef * sSlaveConfig);
                                    HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, uint32_t BurstRequestSrc, \
                                                                                  uint32_t  *BurstBuffer, uint32_t  BurstLength);
                                    HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc);
                                    HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, uint32_t BurstRequestSrc, \
                                                                                  uint32_t  *BurstBuffer, uint32_t  BurstLength);
                                    HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc);
                                    HAL_StatusTypeDef HAL_TIM_GenerateEvent(TIM_HandleTypeDef *htim, uint32_t EventSource);
                                    uint32_t HAL_TIM_ReadCapturedValue(TIM_HandleTypeDef *htim, uint32_t Channel);
                                    
                                    /**
                                      * @}
                                      */
                                    
                                    /** @addtogroup TIM_Exported_Functions_Group9
                                      * @{
                                      */
                                    /* Callback in non blocking modes (Interrupt and DMA) *************************/
                                    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
                                    void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim);
                                    void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim);
                                    void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim);
                                    void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim);
                                    void HAL_TIM_ErrorCallback(TIM_HandleTypeDef *htim);
                                    /**
                                      * @}
                                      */
                                    
                                    /** @addtogroup TIM_Exported_Functions_Group10
                                      * @{
                                      */
                                    /* Peripheral State functions  **************************************************/
                                    HAL_TIM_StateTypeDef HAL_TIM_Base_GetState(TIM_HandleTypeDef *htim);
                                    HAL_TIM_StateTypeDef HAL_TIM_OC_GetState(TIM_HandleTypeDef *htim);
                                    HAL_TIM_StateTypeDef HAL_TIM_PWM_GetState(TIM_HandleTypeDef *htim);
                                    HAL_TIM_StateTypeDef HAL_TIM_IC_GetState(TIM_HandleTypeDef *htim);
                                    HAL_TIM_StateTypeDef HAL_TIM_OnePulse_GetState(TIM_HandleTypeDef *htim);
                                    HAL_TIM_StateTypeDef HAL_TIM_Encoder_GetState(TIM_HandleTypeDef *htim);
                                    
                                    void TIM_DMADelayPulseCplt(DMA_HandleTypeDef *hdma);
                                    void TIM_DMAError(DMA_HandleTypeDef *hdma);
                                    void TIM_DMACaptureCplt(DMA_HandleTypeDef *hdma);
                                    
                                    /**
                                      * @}
                                      */
                                    
                                    /**
                                      * @}
                                      */
                                    
                                    /**
                                      * @}
                                      */
                                    
                                    /**
                                      * @}
                                      */
                                    
                                    #ifdef __cplusplus
                                    }
                                    #endif
                                    
                                    #endif /* __STM32L1xx_HAL_TIM_H */
                                    
                                    /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
                                    

                                    Pour l'instant j'ai ecris comme cela:

                                    void TIM2_IRQHandler()
                                    {
                                    	if(__HAL_TIM_GET_IT_SOURCE(&timerHandle, TIM_IT_UPDATE) != RESET)
                                    	{
                                    		__HAL_TIM_CLEAR_FLAG(&timerHandle, TIM_IT_UPDATE);
                                    		HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_2);
                                    	}
                                    }

                                    Mais je ne sais pas si j'ai utilise les bonnes fonctions, de plus &timerHandle n'est pas reconnu alors que je l'ai initialise dans la fonction precedente :/





                                    -
                                    Edité par tengalice49 16 juillet 2018 à 12:06:13

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      16 juillet 2018 à 17:00:22

                                      Ta variable doit être définie à l'extérieur de la fonction pour être accessibles par les 2 fonctions:

                                      TIM_HandleTypeDef timerHandle;
                                      
                                      void InitializeTimer2()
                                      {
                                          __HAL_RCC_TIM2_CLK_ENABLE();
                                       
                                          TIM_Base_InitTypeDef timerInitStructure;
                                          timerInitStructure.Prescaler = 32000;
                                          timerInitStructure.CounterMode = TIM_COUNTERMODE_UP;
                                          timerInitStructure.Period = 9999;   //10-seconds
                                          timerInitStructure.ClockDivision = TIM_CLOCKDIVISION_DIV1;
                                       
                                          // TIM_HandleTypeDef timerHandle;   // on l'enlève d'ici
                                          timerHandle.Channel = HAL_TIM_ACTIVE_CHANNEL_2;
                                          timerHandle.Init = timerInitStructure;
                                          timerHandle.Instance = TIM2;
                                       
                                          HAL_TIM_Base_MspInit(&timerHandle);
                                          __HAL_TIM_ENABLE_IT(&timerHandle, TIM_IT_UPDATE);
                                      }
                                       
                                      void TIM2_IRQHandler()
                                      {
                                          if(__HAL_TIM_GET_IT_SOURCE(&timerHandle, TIM_IT_UPDATE) != RESET)
                                          {
                                              __HAL_TIM_CLEAR_FLAG(&timerHandle, TIM_IT_UPDATE);
                                              HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_2);
                                          }
                                      }

                                      Mais le tuto que tu avais suivi existe aussi en version HAL: https://visualgdb.com/tutorials/arm/stm32/timers/hal/ 

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        16 juillet 2018 à 23:50:33

                                        Effectivement en suivant le bon tuto c'est plus pratique!

                                        Donc j'ai ecris cela:

                                        static TIM_HandleTypeDef s_TimerInstance = {
                                        		.Instance = TIM2
                                        };
                                        
                                        void InitializeTimer2()
                                        {
                                            __TIM2_CLK_ENABLE();
                                            s_TimerInstance.Init.Prescaler = 32000;
                                            s_TimerInstance.Init.CounterMode = TIM_COUNTERMODE_UP;
                                            s_TimerInstance.Init.Period = 9999;
                                            s_TimerInstance.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
                                            HAL_TIM_Base_Init(&s_TimerInstance);
                                            HAL_TIM_Base_Start(&s_TimerInstance);
                                        }
                                        
                                        void InitializeLEDs()
                                        {
                                        	__GPIOC_CLK_ENABLE();
                                        	GPIO_InitTypeDef GPIO_InitStructure;
                                        
                                        	GPIO_InitStructure.Pin = GPIO_PIN_2;
                                        
                                        	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
                                        	GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
                                        	GPIO_InitStructure.Pull = GPIO_NOPULL;
                                        	HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
                                        }
                                        
                                        void TIM2_IRQHandler()
                                        {
                                        	if (__HAL_TIM_GET_FLAG(&s_TimerInstance, TIM_FLAG_UPDATE) != RESET)
                                        	{
                                        		__HAL_TIM_CLEAR_IT(&s_TimerInstance, TIM_IT_UPDATE);
                                        		HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_2);
                                        	}
                                        }
                                        
                                        void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
                                        {
                                        	HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_2);
                                        }

                                        En appelant les fonctions dans mon main:

                                          HAL_Init();
                                          HAL_SYSTICK_IRQHandler();
                                        
                                          /* Configure the system clock */
                                          SystemClock_Config();
                                        
                                          /* Initialize all configured peripherals */
                                          MX_GPIO_Init();
                                          MX_SPI2_Init();
                                          MX_SPI3_Init();
                                        
                                          //UARTS Initializations
                                          UART_init(UART5_ID,9600);	//GPS
                                          UART_init(UART3_ID,9600);	//SIGFOX
                                        
                                          InitializeLEDs();
                                          InitializeTimer2();
                                        
                                          HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
                                          HAL_NVIC_EnableIRQ(TIM2_IRQn);

                                        Cependant la routine d'interruption n'intervient jamais je ne comprends pas pourquoi :/ 


                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          17 juillet 2018 à 2:42:52

                                          Le seul problème que je vois est que si ton fichier est un fichier .cpp, donc C++, tu dois mettre le extern "C" devant la définition de la fonction "void TIM2_IRQHandler()" comme ce qui est fait dans le tuto pour qu'elle ai la même signature que la fonction qu'elle remplace (celle qui appelle par défaut le DefaultHandler()).

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            17 juillet 2018 à 9:05:26

                                            (VOIR L'EDIT EN BAS)

                                            J'ai ajoute de extern mais ca ne change rien car mon fichier est bien un .c et non un .cpp.

                                            Voici le code entier du main, il y a peut etre des fonctions qui bloquent les interruptions (je pense au contenu du while(1)) ?

                                            /**
                                              ******************************************************************************
                                              * @file           : main.c
                                              * @brief          : Main program body
                                              ******************************************************************************
                                              ** This notice applies to any and all portions of this file
                                              * that are not between comment pairs USER CODE BEGIN and
                                              * USER CODE END. Other portions of this file, whether
                                              * inserted by the user or by software development tools
                                              * are owned by their respective copyright owners.
                                              *
                                              * COPYRIGHT(c) 2018 STMicroelectronics
                                              *
                                              * Redistribution and use in source and binary forms, with or without modification,
                                              * are permitted provided that the following conditions are met:
                                              *   1. Redistributions of source code must retain the above copyright notice,
                                              *      this list of conditions and the following disclaimer.
                                              *   2. Redistributions in binary form must reproduce the above copyright notice,
                                              *      this list of conditions and the following disclaimer in the documentation
                                              *      and/or other materials provided with the distribution.
                                              *   3. Neither the name of STMicroelectronics nor the names of its contributors
                                              *      may be used to endorse or promote products derived from this software
                                              *      without specific prior written permission.
                                              *
                                              * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
                                              * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                                              * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                                              * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
                                              * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                                              * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                                              * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
                                              * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
                                              * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
                                              * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                                              *
                                              ******************************************************************************
                                              */
                                            /* Includes ------------------------------------------------------------------*/
                                            #include "main.h"
                                            #include "app4.h"
                                            #include "stm32l1xx_hal.h"
                                            #include <stdint.h>
                                            #include <stdio.h>
                                            #include <stdlib.h>
                                            #include <string.h>
                                            #include <math.h>
                                            #include "stm32f1_uart.h"
                                            #include "stm32f1_sys.h"
                                            #include "macro_types.h"
                                            #include "adc.h"
                                            #include "uart.h"
                                            #include "gps.h"
                                            #include "pressure_sensor.h"
                                            #include "machine_SD.h"
                                            #include "misc.h"
                                            
                                            #include "stm32l1xx_hal_pwr.h"
                                            #include "stm32l1xx_hal_uart.h"
                                            #include "stm32l1xx_hal_rcc.h"
                                            #include "stm32l1xx_hal_flash.h"
                                            #include "stm32l1xx_hal_cortex.h"
                                            #include "stm32l1xx_hal_spi.h"
                                            #include "stm32l1xx_hal_gpio.h"
                                            #include "stm32l1xx_hal_tim.h"
                                            
                                            #include "stm32l1xx_ll_bus.h"
                                            #include "stm32l1xx_ll_rcc.h"
                                            #include "stm32l1xx_ll_system.h"
                                            #include "stm32l1xx_ll_utils.h"
                                            #include "stm32l1xx_ll_gpio.h"
                                            #include "stm32l1xx_ll_exti.h"
                                            #include "stm32l1xx_ll_usart.h"
                                            
                                            #include "stm32l1xx_ll_utils.h"
                                            #include "stm32l1xx_ll_utils.h"
                                            #if defined(USE_FULL_ASSERT)
                                            #include "stm32_assert.h"
                                            #endif /* USE_FULL_ASSERT */
                                            
                                            
                                            /* USER CODE BEGIN Includes */
                                            
                                            /* USER CODE END Includes */
                                            
                                            /* Private variables ---------------------------------------------------------*/
                                            
                                            I2C_HandleTypeDef hi2c2;
                                            
                                            SPI_HandleTypeDef hspi2;
                                            SPI_HandleTypeDef hspi3;
                                            
                                            UART_HandleTypeDef huart5;
                                            UART_HandleTypeDef huart2;
                                            
                                            /* USER CODE BEGIN PV */
                                            /* Private variables ---------------------------------------------------------*/
                                            double temp1=0;
                                            double temp2=0;
                                            gps_datas_t gps_datas;
                                            /* USER CODE END PV */
                                            
                                            /* Private function prototypes -----------------------------------------------*/
                                            void SystemClock_Config(void);
                                            static void MX_GPIO_Init(void);
                                            //static void MX_I2C2_Init(void);
                                            static void MX_SPI2_Init(void);
                                            static void MX_SPI3_Init(void);
                                            //static void MX_UART5_Init(void);
                                            //static void MX_USART2_UART_Init(void);
                                            float max_temp(float a, float b);
                                            void temperature_max(float a, float b);
                                            void sigfox_send_test(void);
                                            void sigfox_send_frame(double latitude, double longitude, uint16_t altitude, double temperature);
                                            
                                            //void InitializeLEDs();
                                            //void InitializeTimer2();
                                            
                                            /* USER CODE BEGIN PFP */
                                            /* Private function prototypes -----------------------------------------------*/
                                            
                                            /* USER CODE END PFP */
                                            
                                            /* USER CODE BEGIN 0 */
                                            #ifdef __cplusplus
                                            	extern "C"
                                            #endif
                                            static TIM_HandleTypeDef s_TimerInstance = {
                                            		.Instance = TIM2
                                            };
                                            
                                            void InitializeTimer2()
                                            {
                                                __TIM2_CLK_ENABLE();
                                                s_TimerInstance.Init.Prescaler = 32000;
                                                s_TimerInstance.Init.CounterMode = TIM_COUNTERMODE_UP;
                                                s_TimerInstance.Init.Period = 9999;
                                                s_TimerInstance.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
                                                HAL_TIM_Base_Init(&s_TimerInstance);
                                                HAL_TIM_Base_Start(&s_TimerInstance);
                                            }
                                            
                                            void InitializeLEDs()
                                            {
                                            	__GPIOC_CLK_ENABLE();
                                            	GPIO_InitTypeDef GPIO_InitStructure;
                                            
                                            	GPIO_InitStructure.Pin = GPIO_PIN_2;
                                            
                                            	GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
                                            	GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
                                            	GPIO_InitStructure.Pull = GPIO_NOPULL;
                                            	HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
                                            }
                                            
                                            void TIM2_IRQHandler()
                                            {
                                            	if (__HAL_TIM_GET_FLAG(&s_TimerInstance, TIM_FLAG_UPDATE) != RESET)
                                            	{
                                            		__HAL_TIM_CLEAR_IT(&s_TimerInstance, TIM_IT_UPDATE);
                                            		HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_2);
                                            	}
                                            }
                                            
                                            void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
                                            {
                                            	HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_2);
                                            }
                                            /* USER CODE END 0 */
                                            
                                            /**
                                              * @brief  The application entry point.
                                              *
                                              * @retval None
                                              */
                                            int main(void)
                                            {
                                              /* USER CODE BEGIN 1 */
                                            
                                              /* USER CODE END 1 */
                                            
                                              /* MCU Configuration----------------------------------------------------------*/
                                            
                                              /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
                                              HAL_Init();
                                              HAL_SYSTICK_IRQHandler();
                                            
                                              /* USER CODE BEGIN Init */
                                              /* USER CODE END Init */
                                            
                                              /* Configure the system clock */
                                              SystemClock_Config();
                                            
                                              /* USER CODE BEGIN SysInit */
                                            
                                              /* USER CODE END SysInit */
                                            
                                              /* Initialize all configured peripherals */
                                              MX_GPIO_Init();
                                             // MX_I2C2_Init();
                                              MX_SPI2_Init();
                                              MX_SPI3_Init();
                                              /* USER CODE BEGIN 2 */
                                            
                                              //UARTS Initializations
                                              UART_init(UART5_ID,9600);	//GPS
                                              UART_init(UART3_ID,9600);	//SIGFOX
                                            
                                              InitializeLEDs();
                                              InitializeTimer2();
                                            
                                              HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
                                              HAL_NVIC_EnableIRQ(TIM2_IRQn);
                                              /*printf --> UART*/
                                              //SYS_set_std_usart(UART3_ID, UART3_ID, UART3_ID); //all printf are printed into UART3
                                            
                                              /* USER CODE END 2 */
                                            
                                              /* Infinite loop */
                                              /* USER CODE BEGIN WHILE */
                                            
                                              	uint8_t c;
                                              	char mot_test [100];
                                              	sprintf(mot_test,"Bonjour\r\n");
                                              	static char mot_sd_1 [100];
                                              	static char mot_sd_2 [100];
                                              	static char mot_erreur [50];
                                              	static char nom_fichier [20];
                                              	double lat_rmc;
                                              	double long_rmc;
                                            
                                              	//float *temp = 0;
                                              	//uint32_t *pressure = 0;
                                              	//variables for pressure sensor
                                            
                                            
                                              	sprintf(nom_fichier,"0:datas21.txt"); //file name for SD Card
                                            
                                            
                                              while (1) //main loop
                                              {
                                            	  machine_SD_write(FALSE,NULL,NULL); //SD Card initialization
                                            
                                            	  if(UART_data_ready(UART5_ID)) //if GPS receive data
                                            	  {
                                            	  	c = UART_get_next_byte(UART5_ID); //then write the data byte per byte into c
                                            	  	temp1=adc1();	//temperature sensor (ADC)
                                            
                                            	  	  switch(GPS_process_rx(c, &gps_datas))
                                            	  	  {
                                            	  	  	case TRAME_GPRMC:	//if a RMC frame is received
                                            	  	  		sprintf(mot_sd_1,"=> %ld,%ld,Lat:%lf,Long:%lf,",gps_datas.date32,gps_datas.time,gps_datas.latitude_deg, gps_datas.longitude_deg);
                                            	  	  		lat_rmc=gps_datas.latitude_deg;		//lat_rmc and long_rmc are used
                                            	  	  		long_rmc=gps_datas.longitude_deg;	//to send sigfox frame
                                            	  	  		machine_SD_write(FALSE,mot_sd_1,nom_fichier);	//write the data into the SD Card
                                            	  	  		break;
                                            	  	  	case TRAME_GPGGA:	//if a GGA frame is received
                                            	  	  		sprintf(mot_sd_2,"NbSat:%d,Alt:%d,T1:%f <=\r\n",gps_datas.satellites,gps_datas.altitude,temp1);
                                            	  	  		machine_SD_write(FALSE,mot_sd_2,nom_fichier);	//write the data into the SD Car
                                            	  	  		//sigfox_send_frame(lat_rmc,long_rmc,gps_datas.altitude,temp1);	//send data to Sigfox
                                            	  	  		break;
                                            
                                            	  	  	/*errors handler*/
                                            	  	  	case TRAME_INVALID:
                                            	  	 		sprintf(mot_erreur,"=> TRAME_INVALID <=\r\n");
                                            	  	 		machine_SD_write(FALSE,mot_erreur,nom_fichier);
                                            	   			break;
                                            	  	  	case CHECKSUM_INVALID:
                                            	  	  	  	sprintf(mot_erreur,"=> CHECKSUM_INVALID <=\r\n");
                                            	  	  		machine_SD_write(FALSE,mot_erreur,nom_fichier);
                                            	  	  	  	break;
                                            	   		case TRAME_UNKNOW:
                                            	  			sprintf(mot_erreur,"=> TRAME_UNKNOW <=\r\n");
                                            	  			machine_SD_write(FALSE,mot_erreur,nom_fichier);
                                            	  			break;
                                              	  		default:
                                              	  			break;
                                            	  	  }
                                            	  }
                                            
                                              /* USER CODE END WHILE */
                                            
                                              /* USER CODE BEGIN 3 */
                                            
                                              }
                                              /* USER CODE END 3 */
                                            
                                            }
                                            
                                            /*Test function for Sigfox*/
                                            char str[11];
                                            void sigfox_send_test(void){
                                            	sprintf(str,"AT$SF=4444\r"); //String composed of a 4-bytes message via AT Command
                                            	UART_puts(UART3_ID, (uint8_t*)str, sizeof(str));	//Send the message to UART3 (Sigfox module)
                                            	HAL_Delay(10000);	//10-seconds delay
                                            }
                                            
                                            /*Function to send a frame via Sigfox*/
                                            char str_frame[27];
                                            void sigfox_send_frame(double latitude, double longitude, uint16_t altitude, double temperature)
                                            {
                                            	float lat_precision = 0xFFFFFF/360.0;	//precision for latitude
                                            	float long_precision = 0xFFFFFF/180.0;	//precision for longitude
                                            	float alt_precision = 0xFFFF/65535;		//precision for altitude
                                            	float temp_precision = 0xFFFF/200;
                                            
                                            	latitude += 180;						//[-180,180] -> [0,360]
                                            	longitude += 90;						// [-90,90]  -> [0,180]
                                            	temperature += 128;						//[-100,100] -> [0,200]
                                            
                                            	unsigned long latitude_convert = latitude*lat_precision;	//converted values for latitude
                                            	unsigned long longitude_convert = longitude*long_precision;	//					   longitude
                                            	unsigned int altitude_convert = altitude*alt_precision;		//				   and altitude
                                            	unsigned long temperature_convert = temperature*temp_precision;
                                            
                                            	sprintf(str_frame,"AT$SF=%06x%06x%04x%04x\r",latitude_convert,longitude_convert,altitude_convert,
                                            			temperature_convert);								//frame to send
                                            	UART_puts(UART3_ID, (uint8_t*)str_frame, sizeof(str_frame));//send frame to uart 3
                                            	//TODO implement delay in function of altitude!!			//...
                                            	HAL_Delay(30000);											//with a 60-seconds delay
                                            
                                            
                                            }
                                            
                                            /**
                                              * @brief  Max temperature function float
                                              *
                                              * @retval Max temperature
                                              */
                                            float max_temp(float a, float b)
                                            {
                                            	/**Return the maximum value between two float variables
                                            	*/
                                            	return a>b ? a:b; //si a est plus grand que b, alors retrouner a, sinon retourner b
                                            }					  //if a is higher than     b, then return     a, else return     b
                                            
                                            /**
                                              * @brief  Max temperature function printf
                                              *
                                              * @retval None
                                              */
                                            void temperature_max(float a, float b)
                                            {
                                            	printf(a>b ? "Temp 1 max\n" : "Temp 2 max\n"); //si a est plus grand que b, alors "temp1 max", sinon retourner "temp2 max"
                                            }												   //if a is higher than     b, then return "temp1 max", else return "temp2 max"
                                            
                                            /**
                                              * @brief System Clock Configuration
                                              * @retval None
                                              */
                                            void SystemClock_Config(void)
                                            {
                                            
                                              RCC_OscInitTypeDef RCC_OscInitStruct;
                                              RCC_ClkInitTypeDef RCC_ClkInitStruct;
                                            
                                                /**Configure the main internal regulator output voltage
                                                */
                                              __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
                                            
                                                /**Initializes the CPU, AHB and APB busses clocks
                                                */
                                              RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
                                              RCC_OscInitStruct.HSIState = RCC_HSI_ON;
                                              RCC_OscInitStruct.HSICalibrationValue = 16;
                                              RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
                                              RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
                                              RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6;
                                              RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV3;
                                              if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
                                              {
                                                _Error_Handler(__FILE__, __LINE__);
                                              }
                                            
                                                /**Initializes the CPU, AHB and APB busses clocks
                                                */
                                              RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                                                          |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
                                              RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
                                              RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
                                              RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
                                              RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
                                            
                                              if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
                                              {
                                                _Error_Handler(__FILE__, __LINE__);
                                              }
                                            
                                              HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1);
                                            
                                                /**Configure the Systick interrupt time
                                                */
                                              HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
                                            
                                                /**Configure the Systick
                                                */
                                              HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
                                            
                                              /* SysTick_IRQn interrupt configuration */
                                              HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
                                            }
                                            
                                            
                                            
                                            /* SPI2 init function */
                                            static void MX_SPI2_Init(void)
                                            {
                                            
                                              /* SPI2 parameter configuration*/
                                              hspi2.Instance = SPI2;
                                              hspi2.Init.Mode = SPI_MODE_MASTER;
                                              hspi2.Init.Direction = SPI_DIRECTION_2LINES;
                                              hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
                                              hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
                                              hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
                                              hspi2.Init.NSS = SPI_NSS_HARD_OUTPUT;
                                              hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
                                              hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
                                              hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
                                              hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
                                              hspi2.Init.CRCPolynomial = 10;
                                              if (HAL_SPI_Init(&hspi2) != HAL_OK)
                                              {
                                                _Error_Handler(__FILE__, __LINE__);
                                              }
                                            
                                            }
                                            
                                            /* SPI3 init function */
                                            static void MX_SPI3_Init(void)
                                            {
                                            
                                              /* SPI3 parameter configuration*/
                                              hspi3.Instance = SPI3;
                                              hspi3.Init.Mode = SPI_MODE_MASTER;
                                              hspi3.Init.Direction = SPI_DIRECTION_2LINES;
                                              hspi3.Init.DataSize = SPI_DATASIZE_8BIT;
                                              hspi3.Init.CLKPolarity = SPI_POLARITY_LOW;
                                              hspi3.Init.CLKPhase = SPI_PHASE_1EDGE;
                                              hspi3.Init.NSS = SPI_NSS_SOFT;
                                              hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
                                              hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;
                                              hspi3.Init.TIMode = SPI_TIMODE_DISABLE;
                                              hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
                                              hspi3.Init.CRCPolynomial = 10;
                                              if (HAL_SPI_Init(&hspi3) != HAL_OK)
                                              {
                                                _Error_Handler(__FILE__, __LINE__);
                                              }
                                            
                                            }
                                            
                                            
                                            /** Configure pins as
                                                    * Analog
                                                    * Input
                                                    * Output
                                                    * EVENT_OUT
                                                    * EXTI
                                                    * Free pins are configured automatically as Analog (this feature is enabled through
                                                    * the Code Generation settings)
                                                 PA8   ------> RCC_MCO
                                            */
                                            static void MX_GPIO_Init(void)
                                            {
                                            
                                              GPIO_InitTypeDef GPIO_InitStruct;
                                            
                                              /* GPIO Ports Clock Enable */
                                              __HAL_RCC_GPIOC_CLK_ENABLE();
                                              __HAL_RCC_GPIOH_CLK_ENABLE();
                                              __HAL_RCC_GPIOA_CLK_ENABLE();
                                              __HAL_RCC_GPIOB_CLK_ENABLE();
                                              __HAL_RCC_GPIOD_CLK_ENABLE();
                                            
                                              /*Configure GPIO pin Output Level */
                                              HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
                                            
                                              /*Configure GPIO pin : B1_Pin */
                                              GPIO_InitStruct.Pin = B1_Pin;
                                              GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
                                              GPIO_InitStruct.Pull = GPIO_NOPULL;
                                              HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);
                                            
                                              /*Configure GPIO pins : PC2 PC3 PC4 PC5
                                                                       PC6 PC7 PC8 PC9 */
                                              GPIO_InitStruct.Pin = /*GPIO_PIN_2|GPIO_PIN_3|*/GPIO_PIN_4|GPIO_PIN_5
                                                                      |GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
                                              GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
                                              GPIO_InitStruct.Pull = GPIO_NOPULL;
                                              HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
                                            
                                              /*Configure GPIO pins : PA6 PA7
                                                                       PA9 PA10 PA11 PA12
                                                                       PA15 */
                                              GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7
                                                                      |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12
                                                                      |GPIO_PIN_15;
                                              GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
                                              GPIO_InitStruct.Pull = GPIO_NOPULL;
                                              HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
                                            
                                              /*Configure GPIO pin : LD2_Pin */
                                              GPIO_InitStruct.Pin = LD2_Pin;
                                              GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
                                              GPIO_InitStruct.Pull = GPIO_NOPULL;
                                              GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
                                              HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct);
                                            
                                              /*Configure GPIO pins : PB0 PB1 PB2 PB4
                                                                       PB6 PB7 PB8 PB9 */
                                              GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_4
                                                                      |GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
                                              GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
                                              GPIO_InitStruct.Pull = GPIO_NOPULL;
                                              HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
                                            
                                              /*Configure GPIO pin : PA8 */
                                              GPIO_InitStruct.Pin = GPIO_PIN_8;
                                              GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
                                              GPIO_InitStruct.Pull = GPIO_NOPULL;
                                              GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
                                              GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
                                              HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
                                            
                                            }
                                            
                                            
                                            //static void MX_GPIO_Init(void)
                                            
                                            
                                            /* USER CODE BEGIN 4 */
                                            
                                            /* USER CODE END 4 */
                                            
                                            /**
                                              * @brief  This function is executed in case of error occurrence.
                                              * @param  file: The file name as string.
                                              * @param  line: The line in file as a number.
                                              * @retval None
                                              */
                                            void _Error_Handler(char *file, int line)
                                            {
                                              /* USER CODE BEGIN Error_Handler_Debug */
                                              /* User can add his own implementation to report the HAL error return state */
                                              while(1)
                                              {
                                              }
                                              /* USER CODE END Error_Handler_Debug */
                                            }
                                            
                                            #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 CODE BEGIN 6 */
                                              /* User can add his own implementation to report the file name and line number,
                                                 tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
                                              /* USER CODE END 6 */
                                            }
                                            #endif /* USE_FULL_ASSERT */
                                            
                                            /**
                                              * @}
                                              */
                                            
                                            /**
                                              * @}
                                              */
                                            
                                            /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
                                            

                                            EDIT: 

                                            Hmm c'etait une erreur bete de ma part! J'ai mal suivi le tutoriel il y a une ligne que j'avais mal copiee:

                                            HAL_TIM_Base_Start_IT(&s_TimerInstance);


                                            Ligne 139 sur le code precedant!

                                            Du coup maintenant ca fonctionne bien dans mon programme principal, par contre la frequence n'est plus du tout la meme, la LED clignote beaucoup plus vite, je pense que mon micro ne tourne pas a 32MHz mais je ne sais pas ou je peux trouver cette information?

                                            -
                                            Edité par tengalice49 17 juillet 2018 à 10:27:36

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              17 juillet 2018 à 15:58:19

                                              L'horloge semble pourtant configurée en 32Mhz dans la fonction SystemClock_Config. L'horloge interne utilisée HSI16 est à 16Mhz et l'horloge système est de 16MHz * PLLMUL / PLLDIV soit 16*6/3 = 32 Mhz.

                                              Ca fonctionnait a la bonne vitesse avec les autres codes du tuto ?

                                              PS: Apparemment il faut aussi retirer 1 à la valeur du prescaler: 31999 au lieu de 32000, puisque les valeurs valides du prescaler vont de 1 à 65536 correspondant aux valeurs 0 à 65535 du registre (ça ne faisait qu'une erreur de fréquence de timer de 0.03%).

                                              PPS: Ça ne devrait rien changer, mais tu devrais utiliser le même code pour TIM2_IRQHandler que dans le tuto, à savoir appeler uniquement HAL_TIM_IRQHandler, sinon la fonction HAL_TIM_PeriodElapsedCallback n'est jamais appelée, et ça simplifie aussi ton code puisque la gestion des flags est gérée automatiquement par HAL_TIM_IRQHandler.

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                17 juillet 2018 à 21:03:37

                                                C'est bon pour la vitesse, j'avais mis une periode a 99 au lieu de 9999 ^^'

                                                Pour les timer tout fonctionne parfaitement desormais, mais j'ai un soucis (que je n'avais pas avant d'utiliser les timers) sur l'UART.

                                                Le gros du code de mon main est ici:

                                                void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
                                                {
                                                	if(htim->Instance == (TIM2))	//TIMER INTERUPT FOR SD CARD
                                                	{
                                                		HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_2);
                                                		strcat(mot_sd_1,mot_sd_2);
                                                		machine_SD_write(FALSE,mot_sd_1,nom_fichier);	//write the data into the SD Card
                                                	}
                                                	if(htim->Instance == (TIM4))	//TIMER INTERUPT FOR SIGFOX
                                                	{
                                                		HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_3);
                                                		//sigfox_send_test();
                                                		sigfox_send_frame(lat_rmc,long_rmc,alt_gga,temp1);	//send data to Sigfox
                                                	}
                                                }

                                                Dans la fonction sigofx_send_frame(..) j'utilise la fonction suivante pour ecrire sur l'UART:

                                                HAL_USART_Transmit_IT(&huart3, (uint8_t*)str, sizeof(str));

                                                Dont voici le code:

                                                static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart)
                                                {
                                                  uint16_t* tmp=0;
                                                 
                                                  if(husart->State == HAL_USART_STATE_BUSY_TX)
                                                  {
                                                    if(husart->Init.WordLength == USART_WORDLENGTH_9B)
                                                    {
                                                      tmp = (uint16_t*) husart->pTxBuffPtr;
                                                      WRITE_REG(husart->Instance->DR, (uint16_t)(*tmp & (uint16_t)0x01FF));
                                                      if(husart->Init.Parity == USART_PARITY_NONE)
                                                      {
                                                        husart->pTxBuffPtr += 2;
                                                      }
                                                      else
                                                      {
                                                        husart->pTxBuffPtr += 1;
                                                      }
                                                    } 
                                                    else
                                                    { 
                                                      WRITE_REG(husart->Instance->DR, (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0x00FF));
                                                    }
                                                    
                                                    if(--husart->TxXferCount == 0)
                                                    {
                                                      /* Disable the USART Transmit data register empty Interrupt */
                                                      __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
                                                
                                                      /* Enable the USART Transmit Complete Interrupt */    
                                                      __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
                                                    }
                                                    return HAL_OK;
                                                  }
                                                  else
                                                  {
                                                    return HAL_BUSY;
                                                  }
                                                }

                                                Le probleme c'est que c'est que je n'entre jamais dans le premier IF, j'obtiens tout le temps un: return HAL_BUSY;


                                                Est ce que j'ai touche a un mauvais truc sur l'initialisation de mon uart ou c'est du au timer?




                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  18 juillet 2018 à 1:01:43

                                                  Comme la fonction HAL_TIM_PeriodElapsedCallback s'exécute à l'intérieur des routines d'interruptions TIM2 et TIM4, peut-être que tu devrais diminuer leurs priorités par rapport aux interruptions de l'USART3 (et des autres périphériques utilisés) pour que ce dernier puisse continuer à fonctionner à l'intérieur des routines d'interruption des timers.

                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    18 juillet 2018 à 10:16:03

                                                    J'ai reduit les priorites des timers:

                                                    	HAL_NVIC_SetPriority(TIM2_IRQn, 3, 3);
                                                    	HAL_NVIC_SetPriority(TIM4_IRQn, 4, 4);
                                                    	HAL_NVIC_EnableIRQ(TIM2_IRQn);
                                                    	HAL_NVIC_EnableIRQ(TIM4_IRQn);

                                                    J'ai la configuration suivante pour mes UART (UART5 => GPS et USART3 => Module Sigfox pour envoie de donnees)

                                                    void HAL_UART_MspInit(UART_HandleTypeDef *huart)
                                                    {
                                                    	GPIO_InitTypeDef GPIO_InitStruct;
                                                    
                                                    	if(huart->Instance == USART3)
                                                    	{
                                                    		/*Enable the USARTx interface clock*/
                                                    		__HAL_RCC_USART3_CLK_ENABLE();
                                                    
                                                    		/*Enable the clock for the USART GPIOs*/
                                                    		__HAL_RCC_GPIOB_CLK_ENABLE();
                                                    
                                                    		/*Configure USART pins*/
                                                    		GPIO_InitStruct.Pin = GPIO_PIN_10;
                                                    		GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
                                                    		GPIO_InitStruct.Pull = GPIO_PULLUP;
                                                    		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
                                                    		GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
                                                    		HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
                                                    
                                                    		GPIO_InitStruct.Pin = GPIO_PIN_11;
                                                    		GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
                                                    		GPIO_InitStruct.Pull = GPIO_PULLUP;
                                                    		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
                                                    		GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
                                                    		HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
                                                    	}
                                                    
                                                    	else if(huart->Instance == UART5)
                                                    	{
                                                    		/*Enable the USARTx interface clock*/
                                                    		__HAL_RCC_UART5_CLK_ENABLE();
                                                    
                                                    		/*Enable the clock for the USART GPIOs*/
                                                    		__HAL_RCC_GPIOC_CLK_ENABLE();
                                                    		__HAL_RCC_GPIOD_CLK_ENABLE();
                                                    
                                                    		/*Configure UART pins*/
                                                    		GPIO_InitStruct.Pin = GPIO_PIN_12;
                                                    		GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
                                                    		GPIO_InitStruct.Pull = GPIO_PULLUP;
                                                    		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
                                                    		GPIO_InitStruct.Alternate = GPIO_AF8_UART5;
                                                    		HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
                                                    
                                                    		GPIO_InitStruct.Pin = GPIO_PIN_2;
                                                    		GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
                                                    		GPIO_InitStruct.Pull = GPIO_PULLUP;
                                                    		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
                                                    		GPIO_InitStruct.Alternate = GPIO_AF8_UART5;
                                                    		HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
                                                    
                                                    	}
                                                    
                                                    	/*NVIC configuration for interrupt process*/
                                                    	/*
                                                    	HAL_NVIC_SetPriority(USART3_IRQn , 1, 1);
                                                    	HAL_NVIC_EnableIRQ(USART3_IRQn);
                                                    
                                                    	HAL_NVIC_SetPriority(UART5_IRQn , 2, 2);
                                                    	HAL_NVIC_EnableIRQ(UART5_IRQn);*/
                                                    }

                                                    Pour terminer j'initialise mes interruptions dans un autre fichier:

                                                    void UART_init(uart_id_e uart_id, uint32_t baudrate)
                                                    {
                                                    	assert(baudrate > 1000);
                                                    	assert(uart_id < UART_ID_NB);
                                                    
                                                    	buffer_rx_read_index[uart_id] = 0;
                                                    	buffer_rx_write_index[uart_id] = 0;
                                                    	buffer_rx_data_ready[uart_id] = FALSE;
                                                    	/* USARTx configured as follow:
                                                    		- Word Length = 8 Bits
                                                    		- One Stop Bit
                                                    		- No parity
                                                    		- Hardware flow control disabled (RTS and CTS signals)
                                                    		- Receive and transmit enabled
                                                    		- OverSampling: enable
                                                    	*/
                                                    	UART_HandleStructure[uart_id].Instance = (USART_TypeDef*)instance_array[uart_id];
                                                    	UART_HandleStructure[uart_id].Init.BaudRate = baudrate;
                                                    	UART_HandleStructure[uart_id].Init.WordLength = UART_WORDLENGTH_8B;//
                                                    	UART_HandleStructure[uart_id].Init.StopBits = UART_STOPBITS_1;//
                                                    	UART_HandleStructure[uart_id].Init.Parity = UART_PARITY_NONE;//
                                                    	UART_HandleStructure[uart_id].Init.HwFlowCtl = UART_HWCONTROL_NONE;//
                                                    	UART_HandleStructure[uart_id].Init.Mode = UART_MODE_TX_RX;//
                                                    	UART_HandleStructure[uart_id].Init.OverSampling = UART_OVERSAMPLING_16;//
                                                    
                                                    	/*On applique les parametres d'initialisation ci-dessus */
                                                    	HAL_UART_Init(&UART_HandleStructure[uart_id]);
                                                    	
                                                    	/*Activation de l'UART */
                                                    	__HAL_UART_ENABLE(&UART_HandleStructure[uart_id]);
                                                    
                                                    	// On fixe les priorités des interruptions de l'usart PreemptionPriority = 0, SubPriority = 1 et on autorise les interruptions
                                                    	HAL_NVIC_SetPriority(nvic_irq_array[uart_id] , 1, 1);
                                                    	HAL_NVIC_EnableIRQ(nvic_irq_array[uart_id]);
                                                    	HAL_UART_Receive_IT(&UART_HandleStructure[uart_id],&buffer_rx[uart_id][buffer_rx_write_index[uart_id]],1);	//Activation de la réception d'un caractère
                                                    
                                                    	//Config LibC: no buffering
                                                    	setvbuf(stdout, NULL, _IONBF, 0 );
                                                    	setvbuf(stderr, NULL, _IONBF, 0 );
                                                    	setvbuf(stdin, NULL, _IONBF, 0 );
                                                    }

                                                    J'appelle cette fonction dans mon main comme cela:

                                                    //UARTS Initializations
                                                      UART_init(UART5_ID,9600);	//GPS
                                                      UART_init(UART3_ID,9600);	//SIGFOX

                                                    Cependant j'ai toujours le meme probleme, je reste bloque a l'etat "HAL_BUSY" :/




                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      18 juillet 2018 à 22:45:52

                                                      Pour vérifier si c'est vraiment lié aux interruptions, tu pourrais seulement mettre un booléen à 1 dans la fonction HAL_TIM_PeriodElapsedCallback et tester ce booléen dans la boucle du main pour faire l'envoi puis le remettre à 0. Juste parce que je ne suis pas sûr d'expliquer ça correctement:

                                                      static volatile bool tim2_elapsed = false;
                                                      static volatile bool tim4_elapsed = false;
                                                      void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
                                                      {
                                                          if(htim->Instance == (TIM2)) //TIMER INTERUPT FOR SD CARD
                                                          { 
                                                               tim2_elapsed = true;
                                                          }
                                                          if(htim->Instance == (TIM4)) //TIMER INTERUPT FOR SIGFOX
                                                          {
                                                               tim4_elapsed = true;
                                                          }
                                                      }
                                                      
                                                      int main(void) {
                                                         ...
                                                         while(1) {
                                                            if(tim2_elapsed) {
                                                               HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_2);
                                                               strcat(mot_sd_1,mot_sd_2);
                                                               machine_SD_write(FALSE,mot_sd_1,nom_fichier);   //write the data into the SD Card
                                                               tim2_elapsed = false;
                                                            }
                                                            if(tim4_elapsed) {
                                                               HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_3);
                                                               //sigfox_send_test();
                                                               sigfox_send_frame(lat_rmc,long_rmc,alt_gga,temp1);  //send data to Sigfox
                                                               tim4_elapsed = false;
                                                            }      
                                                         }
                                                      }

                                                      Mais d'un autre côté, je ne comprends pas pourquoi tu utilises Transmit_IT au lieu de Transmit si au final tu attends que le transfert soit fini.

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        19 juillet 2018 à 9:35:03

                                                        Salut,

                                                        J'ai implemente ton code avec les booleens et j'ai toujours le meme scenario:

                                                        1) Au premier passage, j'entre bien dans la boucle et j'ai un retour "HAL_OK" mais rien n'est envoye dans l'UART (surement car ce premier passage se fait avant meme son initialisation)

                                                        2) Lors des passages suivants, j'ai toujours un retour "HAL_BUSY"

                                                        A noter que lorsque je je retire la partie du code avec le GPS, j'ai le meme scenario qu'en 1)

                                                        alexisdm a écrit:

                                                        Mais d'un autre côté, je ne comprends pas pourquoi tu utilises Transmit_IT au lieu de Transmit si au final tu attends que le transfert soit fini.

                                                        Pourquoi pas, mais je ne sais pas combien mettre pour le dernier parametre (timeout).

                                                        J'ai essaye cela:

                                                        void sigfox_send_test(void){
                                                        	sprintf(str,"AT$SF=4444\r"); //String composed of a 4-bytes message via AT Command
                                                        	HAL_USART_Transmit(&huart3, (uint8_t*)str, sizeof(str),5000);
                                                        }
                                                        

                                                        En faisant comme cela je passe bien dans toutes les etapes de la fonction HAL_USART_Transmit mais (avec un retour HAL_OK) mais toujours rien de recu sur mon UART :euh: Je commence a me demander si c'est pas un probleme materiel mais j'ai teste avec un adaptateur uart->usb et un terminal, et j'ai bien reussi a envoyer des donnees.


                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          19 juillet 2018 à 12:22:41

                                                          Ce n'est pas ta factorisation des 2 ports UART/USART qui poserait problème ?

                                                          Je crois que tu peux utiliser les fonctions UART (UART_Init, UART_Transmit, UART_Receive et leurs variantes) avec un port USART, mais uniquement avec les structures UART (UART_HandleTypeDef, UART_InitTypeDef) parce que les registres sont censés être compatibles entre les 2 types de ports (et le code généré par STM32CubeMX utilise uniquement les structures UART), mais les structures n'ont pas la même taille (USART_InitTypeDef et USART_HandleTypeDef font 4 octets de plus que leurs équivalents UART), donc certains champs, sont décalés d'une structure à l'autre.

                                                          D'après tes différents codes, tu sembles avoir initialisé le port avec UART_Init, puis tu utilises USART_Transmit...

                                                          tengalice49 a écrit:

                                                          1) Au premier passage, j'entre bien dans la boucle et j'ai un retour "HAL_OK" mais rien n'est envoye dans l'UART (surement car ce premier passage se fait avant meme son initialisation)

                                                          La boucle est à la fin de la fonction main, non ? Pourquoi l'UART ne serait pas initialisé à ce moment puisque l'initialisation se fait dans la fonction main ? 

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            19 juillet 2018 à 13:51:01

                                                            alexisdm a écrit:

                                                            Ce n'est pas ta factorisation des 2 ports UART/USART qui poserait problème ?

                                                            J'ai recommence en ne prenant que des UART et j'ai toujours le meme probleme.

                                                            D'ailleurs, j'ai recree un projet (avec CubeMX) avec seulement l'USART3 et le code pour envoyer ma trame. La premiere fois que j'ai lance le code, j'ai bien recu quelque chose dans l'UART puis apres impossible de recevoir autre chose.

                                                            J'ai modifie le code pour obtenir cela:

                                                            if(tim4_elapsed)	//TIMER INTERUPT FOR SIGFOX
                                                            	  {
                                                            		  HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_3);
                                                            		  if(UART_data_ready(UART3_ID)){
                                                            			  sigfox_send_test();
                                                            		  }
                                                            		  //sigfox_send_frame(lat_rmc,long_rmc,alt_gga,temp1);	//send data to Sigfox
                                                            		  tim4_elapsed = FALSE;
                                                            	  }

                                                            Avec la fonction UART_data_ready:

                                                            /*
                                                             * @brief	Fonction permettant de savoir si le buffer de l'UART demandé est vide ou non.
                                                             * @ret		Retourne VRAI si un ou des caractères sont disponibles dans le buffer.
                                                             * @ret		Retourne FAUX si aucun caractère n'est disponible dans le buffer (le buffer est vide)
                                                             * @param	uart_id est le numéro de l'UART concerné :	UART1_ID, UART2_ID, UART3_ID
                                                             */
                                                            bool_e UART_data_ready(uart_id_e uart_id)
                                                            {
                                                            	assert(uart_id < UART_ID_NB);
                                                            	return buffer_rx_data_ready[uart_id];
                                                            }

                                                            Cette fonction pour l'UART5 (GPS) mais pas pour l'USART3, je ne rentre jamais dans le If.

                                                            alexisdm a écrit:

                                                            La boucle est à la fin de la fonction main, non ? Pourquoi l'UART ne serait pas initialisé à ce moment puisque l'initialisation se fait dans la fonction main ? 


                                                            Oui en effet, j'avais essaye de suivre le programme avec des breakpoints et je pensais que les timers passaient avant l'initialisation mais ce n'est pas le cas.

                                                            Je remet le code du main et le fichier contenant les fonctions uart je dois avoir fais une erreur bete pour que mon uart ne soit meme pas detecte:

                                                            main.c: https://pastebin.com/PB4d5hHC

                                                            uart.c: https://pastebin.com/XW6m8Wzs

                                                            Edit: J'ai trouve ce post ou il semble avoir un probleme similaire au mien mais j'aimerais avoir ton avis avant de me lancer la dedans

                                                            -
                                                            Edité par tengalice49 20 juillet 2018 à 9:40:14

                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                              20 juillet 2018 à 17:20:32

                                                              J'ai essayé de porter ton code sur une autre carte stm32f103, et il semble tourner sans problèmes majeurs. Ça fonctionne aussi avec HAL_UART_Transmit à la place de UART_puts, à condition d'utiliser &UART_HandleStructure[UART3_ID] et pas le &huart3 déclaré par CubeMX qui n'est pas initialisé. D'ailleurs, ça semble bloquer toute réception quand on oublie un appel avec &huart3 dans le code, donc mieux vaudrait supprimer les huart2, 3 et 5 au début de main.c pour éviter toute erreur.

                                                              Par contre:

                                                              char str[11]
                                                              est trop petit, parce que tu utilises sprintf qui a besoin d'écrire le `\0' terminal, de ta chaîne "AT$SF=4444\r" qui fait 11 caractères, l'alternative serait d'utiliser snprintf pour ne pas dépasser la taille du buffer. C'est peut-être la même chose pour sigfox_send_frame.

                                                              tengalice49 a écrit:

                                                              D'ailleurs, j'ai recree un projet (avec CubeMX) avec seulement l'USART3 et le code pour envoyer ma trame. La premiere fois que j'ai lance le code, j'ai bien recu quelque chose dans l'UART puis apres impossible de recevoir autre chose.

                                                              Le "\r" à la fin devrait probablement être un "\n" sinon en fonction du terminal utilisé sur ton PC quand tu fais les tests, ça risque de revenir au début de la même ligne à chaque envoi et donner l'impression que plus rien n'est envoyé.

                                                              Avec cette ligne:

                                                              if(UART_data_ready(UART3_ID))

                                                              rien n'est envoyé si rien n'a été reçu auparavant, c'est vraiment ce que tu cherches à faire ? 



                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              STM32 Gestion des timers

                                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                              • Editeur
                                                              • Markdown