projet_voilier/Keil_Elise_Yuwei/Local_Sources/adc/Include/MyTimer.c
2021-11-15 12:23:39 +01:00

145 líneas
4,1 KiB
C

#include "MyTimer.h"
void (* PtrF ) ( void ) ; /* déclaration d’un pointeur de fonction */
void MyTimer_Base_Init ( MyTimer_Struct_TypeDef * Timer ) {
if (Timer->Timer == TIM1) RCC->APB2ENR |= RCC_APB2ENR_TIM1EN ; // Active l'horloge locale du périphérique
if (Timer->Timer == TIM2) RCC->APB1ENR |= RCC_APB1ENR_TIM2EN ;
if (Timer->Timer == TIM3) RCC->APB1ENR |= RCC_APB1ENR_TIM3EN ;
if (Timer->Timer == TIM4) RCC->APB1ENR |= RCC_APB1ENR_TIM4EN ;
Timer->Timer->PSC = Timer->PSC; // Réglage de la période du Timer
Timer->Timer->ARR = Timer->ARR;
Timer->Timer->CR1 |= (1 << 0); // Active le compteur
}
void MyTimer_EncoderMode_Conf ( TIM_TypeDef * TIM ) {
TIM->PSC = 0; // Réglage de la période du Timer
TIM->ARR = 360*4;
// CC1S= ‘01’ (TIMx_CCMR1 register, TI1FP1 mapped on TI1)
TIM->CCMR1 &= ~TIM_CCMR1_CC1S;
TIM->CCMR1 |= TIM_CCMR1_CC1S_0;
// CC2S= ‘01’ (TIMx_CCMR2 register, TI2FP2 mapped on TI2)
TIM->CCMR2 &= ~TIM_CCMR1_CC2S;
TIM->CCMR2 |= TIM_CCMR1_CC2S_0;
// CC1P= ‘0’, CC1NP = ‘0’, IC1F =’0000’ (TIMx_CCER register, TI1FP1 noninverted, TI1FP1=TI1)
TIM->CCER &= ~TIM_CCER_CC1P;
TIM->CCER &= ~TIM_CCER_CC1NP;
TIM->CCER &= ~TIM_CCMR1_IC1F;
// CC2P= ‘0’, CC2NP = ‘0’, IC2F =’0000’ (TIMx_CCER register, TI2FP2 noninverted, TI2FP2=TI2)
TIM->CCER &= ~TIM_CCER_CC2P;
TIM->CCER &= ~TIM_CCER_CC2NP;
TIM->CCER &= ~TIM_CCMR1_IC2F; // ou CCMR2 ?
// SMS= ‘011’ (TIMx_SMCR register, both inputs are active on both rising and falling edges)
TIM->SMCR &= ~TIM_SMCR_SMS;
TIM->SMCR |= TIM_SMCR_SMS_0;
TIM->SMCR |= TIM_SMCR_SMS_1;
// CEN = 1 (TIMx_CR1 register, Counter is enabled)
TIM->CR1 |= TIM_CR1_CEN;
}
void MyTimer_ActiveIT ( TIM_TypeDef * Timer , char Prio , void (* IT_function ) ( void ) ) {
char num_IT;
PtrF = IT_function; /* affectation du pointeur */
if (Timer == TIM1) num_IT = 25; // Sélectionne le numéro d'interruption en fonction du timer
else if (Timer == TIM2) num_IT = 28;
else if (Timer == TIM3) num_IT = 29;
else if (Timer == TIM4) num_IT = 30;
Timer->DIER |= (1 << 0); // Valide l'envoi d'une demande d'interruption
NVIC->IP[num_IT] |= (Prio << 4); // Fixe la priorité de l'interruption dans le NVIC
NVIC->ISER[0] |= (1 << num_IT); // Autorise la prise en compte de l'interruption dans le NVIC
}
void MyTimer_PWM( TIM_TypeDef * Timer , char Channel ) {
if (Channel == 1) {
Timer->CCMR1 &= ~TIM_CCMR1_OC1M_0; // Mode 1 de la PWM
Timer->CCMR1 |= TIM_CCMR1_OC1M_1| TIM_CCMR1_OC1M_2;
Timer->CCER |= TIM_CCER_CC1E; // Validation de la sortie du canal
}
else if (Channel == 2) {
Timer->CCMR1 &= ~TIM_CCMR1_OC2M_0;
Timer->CCMR1 |= TIM_CCMR1_OC2M_1| TIM_CCMR1_OC2M_2;
Timer->CCER |= TIM_CCER_CC2E;
}
else if (Channel == 3) {
Timer->CCMR2 &= ~TIM_CCMR2_OC3M_0;
Timer->CCMR2 |= TIM_CCMR2_OC3M_1| TIM_CCMR2_OC3M_2;
Timer->CCER |= TIM_CCER_CC3E;
}
else if (Channel == 4) {
Timer->CCMR2 &= ~TIM_CCMR2_OC4M_0;
Timer->CCMR2 |= TIM_CCMR2_OC4M_1| TIM_CCMR2_OC4M_2;
Timer->CCER |= TIM_CCER_CC4E;
}
}
void Set_Duty_Cycle (TIM_TypeDef * Timer, char Channel, char Duty_Cycle) {
if (Channel == 1) {
Timer->CCR1 = (int) (Timer->ARR)*Duty_Cycle/100;
}
else if (Channel == 2) {
Timer->CCR2 = (int) (Timer->ARR)*Duty_Cycle/100;
}
else if (Channel == 3) {
Timer->CCR3 = (int) (Timer->ARR)*Duty_Cycle/100;
}
else if (Channel == 4) {
Timer->CCR4 = (int) (Timer->ARR)*Duty_Cycle/100;
}
}
/********************************************
**** HANDLERS ****
********************************************/
void TIM1_UP_IRQHandler ( void )
{
TIM1->SR &= ~(1 << 0); // Remet à 0 le flag d'interruption
if (PtrF != 0)
(*PtrF) (); /* appel indirect de la fonction */
}
void TIM2_IRQHandler ( void )
{
//TIM2->SR &= ~(1 << 0);
TIM2->SR &= ~TIM_SR_UIF;
if (PtrF != 0)
(*PtrF) (); /* appel indirect de la fonction */
}
void TIM3_IRQHandler ( void )
{
TIM3->SR &= ~(1 << 0);
if (PtrF != 0)
(*PtrF) (); /* appel indirect de la fonction */
}
void TIM4_IRQHandler ( void )
{
TIM4->SR &= ~(1 << 0);
if (PtrF != 0)
(*PtrF) (); /* appel indirect de la fonction */
}