#include "stm32f10x.h" #include "MyTimer.h" #include "DriverGPIO.h" #include 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); }