This commit is contained in:
Marino Benassai 2020-11-06 09:11:56 +01:00
commit 1020d3f997
4 changed files with 231 additions and 189 deletions

View file

@ -1,126 +1,47 @@
// TOUT A FAIRE !! //
/*
indispensable pour pouvoir adresser les registres des périphériques.
Rem : OBLIGATION d'utiliser les définitions utiles contenues dans ce fichier (ex : TIM_CR1_CEN, RCC_APB1ENR_TIM2EN ...)
pour une meilleure lisibilité du code.
Pour les masques, utiliser également les définitions proposée
Rappel : pour mettre à 1 , reg = reg | Mask (ou Mask est le représente le ou les bits à positionner à 1)
pour mettre à 0 , reg = reg&~ Mask (ou Mask est le représente le ou les bits à positionner à 0)
*/
#include "Timer.h" #include "Timer.h"
#include "stm32f1xx_ll_bus.h" // Pour l'activation des horloges #include "stm32f1xx_ll_bus.h" // Pour l'activation des horloges
#include "stm32f1xx_ll_tim.h" #include "stm32f1xx_ll_tim.h" // Pour les timers
/****************************************************************************
* INTERRUPTIONS
***************************************************************************/
// variable pointeur de fonction permettant de mémoriser le callback à appeler depuis // variable pointeur de fonction permettant de mémoriser le callback à appeler depuis
// le handler d'IT // le handler d'IT
void (*Ptr_ItFct_TIM1)(void); void (*it_callback_TIM1)(void);
void (*Ptr_ItFct_TIM2)(void); void (*it_callback_TIM2)(void);
void (*Ptr_ItFct_TIM3)(void); void (*it_callback_TIM3)(void);
void (*Ptr_ItFct_TIM4)(void); void (*it_callback_TIM4)(void);
void TIM1_UP_IRQHandler(void)
/**
* @brief Active l'horloge et règle l'ARR et le PSC du timer visé
* @note Fonction à lancer avant toute autre. Le timer n'est pas encore lancé (voir MyTimerStart)
* @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4
* int Arr : valeur à placer dans ARR
* int Psc : valeur à placer dans PSC
* @retval None
*/
void MyTimer_Conf(TIM_TypeDef * Timer,int Arr, int Psc)
{ {
LL_TIM_InitTypeDef My_LL_Tim_Init_Struct; // rabaisser le flag d'IT
LL_TIM_ClearFlag_UPDATE(TIM1);
// Validation horloge locale (*it_callback_TIM1)();
if (Timer==TIM1) LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
else if (Timer==TIM2) LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
else if (Timer==TIM3) LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3);
else LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM4);
// chargement structure Arr, Psc, Up Count
My_LL_Tim_Init_Struct.Autoreload=Arr;
My_LL_Tim_Init_Struct.Prescaler=Psc;
My_LL_Tim_Init_Struct.ClockDivision=LL_TIM_CLOCKDIVISION_DIV1;
My_LL_Tim_Init_Struct.CounterMode=LL_TIM_COUNTERMODE_UP;
My_LL_Tim_Init_Struct.RepetitionCounter=0;
LL_TIM_Init(Timer,&My_LL_Tim_Init_Struct);
// Blocage IT
LL_TIM_DisableIT_UPDATE(Timer);
// Blocage Timer
LL_TIM_DisableCounter(Timer);
} }
void TIM2_IRQHandler(void)
/**
* @brief Démarre le timer considéré
* @note
* @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4
* @retval None
*/
void MyTimer_Start(TIM_TypeDef * Timer)
{ {
LL_TIM_EnableCounter(Timer); // rabaisser le flag d'IT
LL_TIM_ClearFlag_UPDATE(TIM2);
(*it_callback_TIM2)();
} }
/** void TIM3_IRQHandler(void)
* @brief Arrêt le timer considéré
* @note
* @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4
* @retval None
*/
void MyTimer_Stop(TIM_TypeDef * Timer)
{ {
LL_TIM_DisableCounter(Timer); // rabaisser le flag d'IT
LL_TIM_ClearFlag_UPDATE(TIM3);
(*it_callback_TIM3)();
} }
void TIM4_IRQHandler(void)
/**
* @brief Configure le Timer considéré en interruption sur débordement.
* @note A ce stade, les interruptions ne sont pas validés (voir MyTimer_IT_Enable )
* @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4
* void (*IT_function) (void) : nom (adresse) de la fonction à lancer sur interruption
* int Prio : priorité associée à l'interruption
* @retval None
*/
void MyTimer_IT_Conf(TIM_TypeDef * Timer, void (*IT_function) (void),int Prio)
{ {
// affectation de la fonction // rabaisser le flag d'IT
if (Timer==TIM1) Ptr_ItFct_TIM1=IT_function; LL_TIM_ClearFlag_UPDATE(TIM4);
else if (Timer==TIM2) Ptr_ItFct_TIM2=IT_function; (*it_callback_TIM4)();
else if (Timer==TIM3) Ptr_ItFct_TIM3=IT_function;
else Ptr_ItFct_TIM4=IT_function;
// Blocage IT (il faudra la débloquer voir fct suivante)
LL_TIM_DisableIT_UPDATE(Timer);
// validation du canal NVIC
IRQn_Type TIM_irq;
if (Timer==TIM1) TIM_irq=TIM1_UP_IRQn;
else if (Timer==TIM2) TIM_irq=TIM2_IRQn;
else if (Timer==TIM3) TIM_irq=TIM3_IRQn;
else TIM_irq=TIM4_IRQn;
NVIC_SetPriority(TIM_irq, Prio);
NVIC_EnableIRQ(TIM_irq);
} }
@ -130,9 +51,9 @@ void MyTimer_IT_Conf(TIM_TypeDef * Timer, void (*IT_function) (void),int Prio)
* @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4 * @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4
* @retval None * @retval None
*/ */
void MyTimer_IT_Enable(TIM_TypeDef * Timer) void Timer_IT_enable(TIM_TypeDef * timer)
{ {
LL_TIM_EnableIT_UPDATE(Timer); LL_TIM_EnableIT_UPDATE(timer);
} }
@ -142,41 +63,152 @@ void MyTimer_IT_Enable(TIM_TypeDef * Timer)
* @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4 * @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4
* @retval None * @retval None
*/ */
void MyTimer_IT_Disable(TIM_TypeDef * Timer) void Timer_IT_disable(TIM_TypeDef * timer)
{ {
LL_TIM_DisableIT_UPDATE(Timer); LL_TIM_DisableIT_UPDATE(timer);
} }
/**
/* * @brief Configure le Timer considéré en interruption sur débordement.
============ LES INTERRUPTIONS ================================= * @note A ce stade, les interruptions ne sont pas validés (voir MyTimer_IT_Enable )
* @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4
*/ * void (*IT_function) (void) : nom (adresse) de la fonction à lancer sur interruption
* int Prio : priorité associée à l'interruption
void TIM1_UP_IRQHandler(void) * @retval None
*/
void Timer_IT_conf(TIM_TypeDef * timer, void (*it_callback) (void), int prio)
{ {
// rabaisser le flag d'IT // affectation de la fonction
LL_TIM_ClearFlag_UPDATE(TIM1); if (timer == TIM1) it_callback_TIM1 = it_callback;
(*Ptr_ItFct_TIM1)(); else if (timer == TIM2) it_callback_TIM2 = it_callback;
else if (timer == TIM3) it_callback_TIM3 = it_callback;
else it_callback_TIM4 = it_callback;
// Blocage IT (il faudra la débloquer voir fct suivante)
LL_TIM_DisableIT_UPDATE(timer);
// validation du canal NVIC
IRQn_Type TIM_irq;
if (timer == TIM1) TIM_irq = TIM1_UP_IRQn;
else if (timer == TIM2) TIM_irq = TIM2_IRQn;
else if (timer == TIM3) TIM_irq = TIM3_IRQn;
else TIM_irq = TIM4_IRQn;
NVIC_SetPriority(TIM_irq, prio);
NVIC_EnableIRQ(TIM_irq);
} }
void TIM2_IRQHandler(void) /****************************************************************************
* TIMER
***************************************************************************/
/**
* @brief Démarre le timer considéré et active les interruptions
* @note
* @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4
* @retval None
*/
void Timer_start(TIM_TypeDef * timer)
{ {
// rabaisser le flag d'IT LL_TIM_EnableCounter(timer);
LL_TIM_ClearFlag_UPDATE(TIM2);
(*Ptr_ItFct_TIM2)();
} }
void TIM3_IRQHandler(void) /**
* @brief Arrêt le timer considéré et désactive les interruptions
* @note
* @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4
* @retval None
*/
void Timer_stop(TIM_TypeDef * timer)
{ {
// rabaisser le flag d'IT LL_TIM_DisableCounter(timer);
LL_TIM_ClearFlag_UPDATE(TIM3);
(*Ptr_ItFct_TIM3)();
} }
void TIM4_IRQHandler(void) /**
* @brief Active l'horloge et règle l'ARR et le PSC du timer visé.
* @note Fonction à lancer avant toute autre. Le timer n'est pas encore lancé (voir Timer_start)
* @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4
* int Arr : valeur à placer dans ARR
* int Psc : valeur à placer dans PSC
* @retval None
*/
void Timer_conf(TIM_TypeDef * timer, int arr, int psc)
{ {
// rabaisser le flag d'IT LL_TIM_InitTypeDef init_struct;
LL_TIM_ClearFlag_UPDATE(TIM4);
(*Ptr_ItFct_TIM4)(); // Validation horloge locale
if (timer == TIM1) LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
else if (timer == TIM2) LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
else if (timer == TIM3) LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3);
else LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM4);
// chargement structure Arr, Psc, Up Count
init_struct.Autoreload = arr;
init_struct.Prescaler = psc;
init_struct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
init_struct.CounterMode = LL_TIM_COUNTERMODE_UP;
init_struct.RepetitionCounter = 0;
LL_TIM_Init(timer,&init_struct);
// Blocage interruptions
Timer_IT_disable(timer);
// Blocage Timer
Timer_stop(timer);
}
/****************************************************************************
* PWM INPUT
***************************************************************************/
/****************************************************************************
* PWM OUTPUT
***************************************************************************/
int getArrFromFreq(float freq_khz)
{
return (72000 / freq_khz) - 1;
}
void PWMo_conf(TIM_TypeDef * timer, int channel, float freq_khz, float dutyCycle)
{
const int arr = getArrFromFreq(freq_khz);
Timer_conf(timer, arr, 0);
LL_TIM_OC_InitTypeDef init_struct;
LL_TIM_OC_StructInit(&init_struct);
init_struct.OCMode = LL_TIM_OCMODE_PWM1;
init_struct.OCState = LL_TIM_OCSTATE_ENABLE;
init_struct.CompareValue= dutyCycle * arr;
LL_TIM_OC_Init(timer, channel, &init_struct);
}
void PWMo_setDutyCycle(TIM_TypeDef * timer, int channel, float freq_khz, float dutyCycle)
{
int compare = dutyCycle * getArrFromFreq(freq_khz);
if (channel == LL_TIM_CHANNEL_CH1) LL_TIM_OC_SetCompareCH1(timer, compare);
else if (channel == LL_TIM_CHANNEL_CH2) LL_TIM_OC_SetCompareCH2(timer, compare);
else if (channel == LL_TIM_CHANNEL_CH3) LL_TIM_OC_SetCompareCH3(timer, compare);
else LL_TIM_OC_SetCompareCH4(timer, compare);
}
/****************************************************************************
* ENCODER
***************************************************************************/
void Timer_encoder_conf(TIM_TypeDef * timer, int arr, int psc)
{
}
int Timer_encoder_get(TIM_TypeDef * timer)
{
return 0;
} }

View file

@ -1,15 +1,24 @@
// RIEN A MODIFIER //
#ifndef TIMER_H #ifndef TIMER_H
#define TIMER_H #define TIMER_H
/*
Driver pour Timer 1 à 4 du STM32F103RB
*/
#include "stm32f103xb.h" #include "stm32f103xb.h"
/****************************************************************************
* INTERRUPTIONS
***************************************************************************/
void Timer_IT_enable(TIM_TypeDef * timer);
void Timer_IT_disable(TIM_TypeDef * timer);
void Timer_IT_conf(TIM_TypeDef * timer, void (*it_callback) (void), int prio);
/****************************************************************************
* TIMER
***************************************************************************/
/** /**
* @brief Active l'horloge et règle l'ARR et le PSC du timer visé * @brief Active l'horloge et règle l'ARR et le PSC du timer visé
* @note Fonction à lancer avant toute autre. Le timer n'est pas encore lancé (voir MyTimerStart) * @note Fonction à lancer avant toute autre. Le timer n'est pas encore lancé (voir MyTimerStart)
@ -18,7 +27,7 @@ Driver pour Timer 1
* int Psc : valeur à placer dans PSC * int Psc : valeur à placer dans PSC
* @retval None * @retval None
*/ */
void MyTimer_Conf(TIM_TypeDef * Timer,int Arr, int Psc); void Timer_conf(TIM_TypeDef * timer, int arr, int psc);
/** /**
@ -27,7 +36,7 @@ void MyTimer_Conf(TIM_TypeDef * Timer,int Arr, int Psc);
* @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4 * @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4
* @retval None * @retval None
*/ */
void MyTimer_Start(TIM_TypeDef * Timer); void Timer_start(TIM_TypeDef * timer);
/** /**
@ -36,35 +45,39 @@ void MyTimer_Start(TIM_TypeDef * Timer);
* @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4 * @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4
* @retval None * @retval None
*/ */
void MyTimer_Stop(TIM_TypeDef * Timer); void Timer_stop(TIM_TypeDef * timer);
/****************************************************************************
* PWM INPUT
***************************************************************************/
void PWMi_conf(TIM_TypeDef * timer, int channel);
int PWMi_getDutyCycle(TIM_TypeDef * timer, int channel);
/****************************************************************************
* PWM OUTPUT
***************************************************************************/
void PWMo_conf(TIM_TypeDef * timer, int channel, float freq_khz, float dutyCycle);
/** /**
* @brief Configure le Timer considéré en interruption sur débordement. * @brief Arrêt le timer considéré
* @note A ce stade, les interruptions ne sont pas validés (voir MyTimer_IT_Enable )
* @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4
* void (*IT_function) (void) : nom (adresse) de la fonction à lancer sur interruption
* int Prio : priorité associée à l'interruption
* @retval None
*/
void MyTimer_IT_Conf(TIM_TypeDef * Timer, void (*IT_function) (void),int Prio);
/**
* @brief Autorise les interruptions
* @note * @note
* @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4 * @param TIM_TypeDef Timer : indique le timer à utiliser : TIM1, TIM2, TIM3 ou TIM4
* int channel : Le channel utilisé par la PWM
* float dutyCycle : Valeur entre 0 et 1
* @retval None * @retval None
*/ */
void MyTimer_IT_Enable(TIM_TypeDef * Timer); void PWMo_setDutyCycle(TIM_TypeDef * timer, int channel, float freq_khz, float dutyCycle);
/****************************************************************************
* ENCODER
***************************************************************************/
/** void Timer_encoder_conf(TIM_TypeDef * timer, int arr, int psc);
* @brief Interdit les interruptions
* @note int Timer_encoder_get(TIM_TypeDef * timer);
* @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4
* @retval None
*/
void MyTimer_IT_Disable(TIM_TypeDef * Timer);
#endif #endif

View file

@ -29,23 +29,19 @@ void Chrono_Task_10ms(void);
void Chrono_Conf(TIM_TypeDef * Timer) void Chrono_Conf(TIM_TypeDef * Timer)
{ {
// Reset Time // Reset Time
Chrono_Time.Hund=0; Chrono_Time.Hund = 0;
Chrono_Time.Sec=0; Chrono_Time.Sec = 0;
Chrono_Time.Min=0; Chrono_Time.Min = 0;
// Fixation du Timer // Fixation du Timer
Chrono_Timer=Timer; Chrono_Timer = Timer;
// Réglage Timer pour un débordement à 10ms // Réglage Timer pour un débordement à 10ms
MyTimer_Conf(Chrono_Timer,999, 719); Timer_conf(Chrono_Timer, 999, 719);
// Réglage interruption du Timer avec callback : Chrono_Task_10ms()
MyTimer_IT_Conf(Chrono_Timer, Chrono_Task_10ms,3);
// Validation IT
MyTimer_IT_Enable(Chrono_Timer);
// Réglage des interruptions
Timer_IT_conf(Chrono_Timer, Chrono_Task_10ms, 3);
Timer_IT_enable(Chrono_Timer);
} }
@ -57,7 +53,7 @@ void Chrono_Conf(TIM_TypeDef * Timer)
*/ */
void Chrono_Start(void) void Chrono_Start(void)
{ {
MyTimer_Start(Chrono_Timer); Timer_start(Chrono_Timer);
} }
@ -69,7 +65,7 @@ void Chrono_Start(void)
*/ */
void Chrono_Stop(void) void Chrono_Stop(void)
{ {
MyTimer_Stop(Chrono_Timer); Timer_stop(Chrono_Timer);
} }
@ -82,7 +78,7 @@ void Chrono_Stop(void)
void Chrono_Reset(void) void Chrono_Reset(void)
{ {
// Arrêt Chrono // Arrêt Chrono
MyTimer_Stop(Chrono_Timer); Timer_stop(Chrono_Timer);
// Reset Time // Reset Time
Chrono_Time.Hund=0; Chrono_Time.Hund=0;

View file

@ -32,6 +32,7 @@ void SystemClock_Config(void);
* @retval None * @retval None
*/ */
Time * time;
int main(void) int main(void)
{ {
@ -45,7 +46,7 @@ int main(void)
// Lancement chronomètre // Lancement chronomètre
Chrono_Start(); Chrono_Start();
time = Chrono_Read();
/* Infinite loop */ /* Infinite loop */
while (1) while (1)