From 7c51dd43cfc95f5ea7a638900cfd17ee9fdb3337 Mon Sep 17 00:00:00 2001 From: Oskar Date: Tue, 25 Nov 2025 19:18:16 +0100 Subject: [PATCH] =?UTF-8?q?S=C3=A9ance=2025/11?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Pilotes/Include/Accelerometre.h | 8 ++ Pilotes/Include/Horloge.h | 16 ++++ Pilotes/Source/Accelerometre.c | 31 ++++++++ Pilotes/Source/Horloge.c | 136 ++++++++++++++++++++++++++++++++ 4 files changed, 191 insertions(+) create mode 100755 Pilotes/Include/Accelerometre.h create mode 100755 Pilotes/Include/Horloge.h create mode 100755 Pilotes/Source/Accelerometre.c create mode 100755 Pilotes/Source/Horloge.c diff --git a/Pilotes/Include/Accelerometre.h b/Pilotes/Include/Accelerometre.h new file mode 100755 index 0000000..912b24d --- /dev/null +++ b/Pilotes/Include/Accelerometre.h @@ -0,0 +1,8 @@ +#include +#include + +void initAccelo(void); +uint16_t * RecupAccelo(void); +void LacheVoile(uint16_t * DATA); +void initLacheur(void); +uint16_t * KattRecupAccelo(void); \ No newline at end of file diff --git a/Pilotes/Include/Horloge.h b/Pilotes/Include/Horloge.h new file mode 100755 index 0000000..0d85934 --- /dev/null +++ b/Pilotes/Include/Horloge.h @@ -0,0 +1,16 @@ +#include +#define PSC_VAL 624 +#define ARR_VAL 0xE0FF + +//DUTY CYCLE +#define DUTYC 70 //Chiffre entre 0 et 100, où 100 est 100% duty cycle +#define POWERMODE 1 // 1 vaut powermode 1, 0 vaut powermode 2 (Powermode pour le config de dutycycle) +//Powermode 1 reste sur la bonne polarité: cad. si DUTY_CYCLE vaut 60 alors le signal reste HIGH pour 60% du periode, inverse pour pwmd2 +//Timer +void Timer_Init(TIM_TypeDef *Timer, unsigned short Autoreload, unsigned short Prescaler); +void MyTimer_ActiveIT(TIM_TypeDef * Timer, char Prio, void(*Interrupt_fonc)(void)); +void TIM2_IRQHandler(void); + +//PWM +void MyTimer_PWM(TIM_TypeDef * Timer , int Channel); +int Set_DutyCycle_PWM(TIM_TypeDef *Timer, int Channel, int DutyC); \ No newline at end of file diff --git a/Pilotes/Source/Accelerometre.c b/Pilotes/Source/Accelerometre.c new file mode 100755 index 0000000..2f13e06 --- /dev/null +++ b/Pilotes/Source/Accelerometre.c @@ -0,0 +1,31 @@ +#include +#include +//#include +#include + +#include + + +void initLacheur(void){ + GPIOB->CRH &= ~(0xF << (0 * 4)); + GPIOB->CRH |= (0xA << (0 * 4)); //On met GPIOB.8 en mode output 2Mhz, alternate pp + Timer_Init(TIM4, 20000 - 1, 71); //Claire m'a aidé +} + + //Recuperer le DATA en X, Z, Y +void LacheVoile(uint16_t * DATA){ + //uint16_t X = DATA[0]; //Z le longe du mât (masten) + //uint16_t Z = DATA[2];// //X le long du sense de voilier + uint16_t Y = DATA[1]; ////Y vers les bords (Tribord/Babord) + if (Y>=0x007B){// exatement à 40 degrés, on lache le 40%. 0xFF*(40deg/90deg) + //Le PWM du moteur est gère par PB7 + MyTimer_PWM(TIM4, 3); //TIM4 CH3 pour PB8 + Set_DutyCycle_PWM(TIM4, 3, 2); //On met Duty cycle à 2% et il reste autour de 90 deg + } +} + + + + + + diff --git a/Pilotes/Source/Horloge.c b/Pilotes/Source/Horloge.c new file mode 100755 index 0000000..fa2f6dd --- /dev/null +++ b/Pilotes/Source/Horloge.c @@ -0,0 +1,136 @@ +#include +#include +#include + + +//Il faut trouver le signal +//On est à Timer 2 + +static void (*TIM2_Appel)(void) = 0; + +void Timer_Init(TIM_TypeDef *Timer, unsigned short Autoreload, unsigned short Prescaler){ + if (Timer == TIM1) { + RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; //L'horloge est enabléd + } else if (Timer == TIM2) { + TIM2->CR1 |= TIM_CR1_CEN; //On enable l'horloge interne + RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; + } else if (Timer == TIM3) { + RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; + } else if (Timer == TIM4) { + RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; + } + Timer->ARR |= Autoreload; + Timer->PSC |= Prescaler; +} + +//La fonction TIM2_IRQHandler s'utilise dans le processeur, on l'a juste redifint, tel qu'à chaque overflow on met un bit 1 dans GPIOA_ODR +void TIM2_IRQHandler(void) { //On redefinit le IRQHandler qui est déjà ecrit dans le code source + if (TIM2->SR & TIM_SR_UIF) { //On met le bit de overflow à un dès qu'on a overflow + TIM2->SR &= ~TIM_SR_UIF; //Remise à zero + + if (TIM2_Appel){TIM2_Appel();} + } +} + + +void MyTimer_ActiveIT(TIM_TypeDef * Timer, char Prio, void(*Interrupt_fonc)(void)){ //On veut créer une fonction qui envoie un signal au cas où il y a debordement, avec une prioritaire, 0 plus importante 15 moins importante + if (Timer == TIM2){ + + TIM2_Appel = Interrupt_fonc; + + NVIC_EnableIRQ(TIM2_IRQn); + NVIC_SetPriority(TIM2_IRQn, Prio); + TIM2->DIER |= TIM_DIER_UIE; //Le registre DIER(Interrupt Enable Register) est mis au bit Update Interrupt, qui se commute lors d'un overflow + TIM2->CR1 |= TIM_CR1_CEN; //Clock Enable + } +} + + +//Fonction qui permet de clignoter le DEL à un pulse volue (Sinusoïdale) +//Si le sinus est haut(haute tension) le Duty Cicle est proche de 100%, +//si le sinus est bas (vers la tension la plus basse) le Duty Cycle est vers 0% +//On s'applique sur un plage de [0V; 3.3V] + + +void MyTimer_PWM(TIM_TypeDef * Timer , int Channel){ + int pwrmd; + #if POWERMODE //Powermode 1 + pwrmd = 0b110; + #else + pwrmd = 0b111; //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 = (ARR_VAL + 1) * DutyC / 100; //ARR_VAL déjà definie + switch (Channel){ + case 1: Timer->CCR1 = CCR_VAL; + case 2: Timer->CCR2 = CCR_VAL; + case 3: Timer->CCR3 = CCR_VAL; + case 4: Timer->CCR4 = CCR_VAL; + default: break; +} +return 0; +Timer->EGR |= TIM_EGR_UG; +}