BE_VOILIER/Pilotes/Sources/MyPWM.c
Mygi27 d9d147e342 harmonisation des pilotes de l'USART et de la PWM
j'ai utilisé les pilotes de Oskar
2025-12-16 18:17:59 +01:00

167 lines
5.7 KiB
C

#include "stm32f10x.h"
#include "MyTimer.h"
#include "DriverGPIO.h"
#include <stdlib.h>
void My_PWM_Channel_Config(TIM_TypeDef* Timer , char channel){
switch (channel) {
case 1:
// Configuration de CC1
Timer->CCMR1 &= ~TIM_CCMR1_CC1S; // Output
Timer->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1; // Mode PWM 1 (0b110)
Timer->CCMR1 |= TIM_CCMR1_OC1PE; // Preload Enable
Timer->CCR1 = 0;
Timer->CCER |= TIM_CCER_CC1E; // Output Enable
break; // <<-- AJOUTER LE BREAK
case 2:
// Configuration de CC2 (vos registres dans le code initial étaient incohérents)
Timer->CCMR1 &= ~TIM_CCMR1_CC2S; // Output
Timer->CCMR1 |= TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1; // Mode PWM 1 (0b110)
Timer->CCMR1 |= TIM_CCMR1_OC2PE; // Preload Enable
Timer->CCR2 = 0;
Timer->CCER |= TIM_CCER_CC2E; // Output Enable
break;}
Timer->CR1 |= TIM_CR1_ARPE; // Auto-Reload Preload
Timer->BDTR |= TIM_BDTR_MOE; // Main Output Enable (pour les timers avancés TIM1/8)
Timer->EGR |= TIM_EGR_UG;
Timer->CR1 |= TIM_CR1_CEN;
};
void MyTimer_PWM(TIM_TypeDef * Timer , int Channel){
int pwrmd;
#if POWERMODE //Powermode 1
pwrmd = 0b110;
#else
pwrmd = 0b110; //Powermode 2
#endif
if (Channel == 1){
Timer->CCMR1 &= ~(0b111<<4); //On clear les trois bits qui sont de pwm
Timer->CCMR1 |= (pwrmd<<4); //On affecte le powermode au bits de lecture pour le µ-controlleur
Timer->CCMR1 |= TIM_CCMR1_OC1PE; //Update preload, il n'affecte pas le valeur avant que la prochaine cycle
Timer->CCER = TIM_CCER_CC1E; //Enable le pin voulu basculer
}
else if (Channel == 2){
Timer->CCMR1 &= ~(0b111<<12); //Le TIMx_CCMR1 configure deux channels, de bit [6:4] CH1, [14:12] CH2 (OC2M = Output Channel 2 )
Timer->CCMR1 |= (pwrmd<<12);
Timer->CCMR1 |= TIM_CCMR1_OC2PE;
Timer->CCER |= TIM_CCER_CC2E;
}
else if (Channel == 3){
Timer->CCMR1 &= ~(0b111<<4);
Timer->CCMR2 |= (pwrmd<<4);
Timer->CCMR2 |= TIM_CCMR2_OC3PE;
Timer->CCER |= TIM_CCER_CC3E;
}
else if (Channel == 4){
Timer->CCMR1 &= ~(0b111<<12);
Timer->CCMR2 |= (pwrmd<<12);
Timer->CCMR2 |= TIM_CCMR2_OC4PE;
Timer->CCER |= TIM_CCER_CC4E;
}
//En dessous d'ici, on a l'aide du plus gentil chat que je connais
// Enable auto-reload preload -- //Ensures that your initial configuration — PWM mode, duty cycle, period — actually takes effect before the timer starts counting.
Timer->CR1 |= TIM_CR1_ARPE;
// Force update event to load ARR and CCR values immediately
Timer->EGR |= TIM_EGR_UG;
// Start the timer
Timer->CR1 |= TIM_CR1_CEN;
switch (Channel) {
case 1:
if (Timer == TIM1){GPIOA->CRH &= ~(0xF<<0*4); GPIOA->CRH |= (0xA<<0*4); TIM1->BDTR |= 1<<15; }
if (Timer == TIM2){GPIOA->CRL &= ~(0xF<<0*4); GPIOA->CRL |= (0xA<<0*4);}
if (Timer == TIM3){GPIOA->CRL &= ~(0xF<<6*4); GPIOA->CRL |= (0xA<<6*4);}
if (Timer == TIM4){GPIOB->CRL &= ~(0xF<<5*4); GPIOB->CRL |= (0xA<<5*4);}
break;
case 2:
if (Timer == TIM1){GPIOA->CRH &= ~(0xF<<1*4); GPIOA->CRL |= (0xA<<1*4); TIM1->BDTR |= 1<<15;}
if (Timer == TIM2){GPIOA->CRL &= ~(0xF<<1*4); GPIOA->CRL |= (0xA<<1*4);}
if (Timer == TIM3){GPIOA->CRL &= ~(0xF<<7*4); GPIOA->CRL |= (0xA<<7*4);}
if (Timer == TIM4){GPIOB->CRL &= ~(0xF<<7*4); GPIOB->CRL |= (0xA<<7*4);}
break;
case 3:
if (Timer == TIM1){GPIOA->CRH &= ~(0xF<<2*4); GPIOA->CRH |= (0xA<<2*4); TIM1->BDTR |= 1<<15;}
if (Timer == TIM2){GPIOA->CRL &= ~(0xF<<2*4); GPIOA->CRL |= (0xA<<2*4);}
if (Timer == TIM3){GPIOB->CRL &= ~(0xF<<0*4); GPIOB->CRL |= (0xA<<0*4);}
if (Timer == TIM4){GPIOB->CRH &= ~(0xF<<0*4); GPIOB->CRH |= (0xA<<0*4);}
break;
case 4:
if (Timer == TIM1){GPIOA->CRH &= ~(0xF<<3*4); GPIOA->CRH |= (0xA<<3*4); TIM1->BDTR |= 1<<15;}
if (Timer == TIM2){GPIOA->CRL &= ~(0xF<<3*4); GPIOA->CRL |= (0xA<<3*4);}
if (Timer == TIM3){GPIOB->CRL &= ~(0xF<<1*4); GPIOB->CRL |= (0xA<<1*4);}
if (Timer == TIM4){GPIOB->CRH &= ~(0xF<<1*4); GPIOB->CRH |= (0xA<<1*4);}
}
}
//Une fonction qui met le bon PWM volue
int Set_DutyCycle_PWM(TIM_TypeDef *Timer, int Channel, int DutyC){
int CCR_VAL = (Timer->ARR + 1) * DutyC / 100;
switch (Channel){
case 1:
Timer->CCR1 = CCR_VAL;
break;
case 2:
Timer->CCR2 = CCR_VAL;
break;
case 3:
Timer->CCR3 = CCR_VAL;
break;
case 4:
Timer->CCR4 = CCR_VAL;
break;
default:
return -1; // channel invalide
}
Timer->EGR |= TIM_EGR_UG; // update event
return 0;
}
void initPlato(TIM_TypeDef * Timer, int Channel){ // Config du moteur servo
MyGPIO_Init(GPIOB, 5, AltOut_Ppull); //config pin de direction 0 ou 1
if (Timer == TIM3) {
EnableTimer(TIM3);
MyTimer_Base_Init(TIM3, 159, 17); // Pour obtenir fréq de 20kHZ
if (Channel == 3){
MyGPIO_Init(GPIOB, 0, AltOut_Ppull); // Outut push pull alternate, config pin de consigne entre -100 et 100
MyTimer_PWM(TIM3, 3); //TIM3 CH3
}
else{
//printf("Ce pilote n'existe pas");
}
}
else{
//printf("Ce pilote n'existe pas");
}
}
void Update_Motor_PWM(int Consigne, TIM_TypeDef * Timer, int Channel) {
int duty_cycle;
if (Consigne>=0){
MYGPIO_PinOn(GPIOB, 5);
duty_cycle = Consigne;
};
if (Consigne<0){
MYGPIO_PinOff(GPIOB,5);
duty_cycle = -Consigne;
};
Set_DutyCycle_PWM(Timer, Channel, duty_cycle);
}