From ebda31ee03e3ef2aa889824094d4daf8994000d4 Mon Sep 17 00:00:00 2001 From: Neluji <38362829+Neluji@users.noreply.github.com> Date: Tue, 24 Nov 2020 19:52:32 +0100 Subject: [PATCH] =?UTF-8?q?Comment.=20+=20d=C3=A9but=20mise=20en=20commun?= =?UTF-8?q?=20(GPIO)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MDK-ARM/Project.uvoptx | 32 +++-- MDK-ARM/Project.uvprojx | 10 ++ MyDrivers/GPIO.c | 168 ++++++++++++++++++++++ MyDrivers/GPIO.h | 24 ++++ MyDrivers/MyPWM.h | 29 +++- MyDrivers/MyUSART.c | 39 +----- MyDrivers/MyUSART.h | 26 +--- Services/ADC_antichavirement.c | 101 ++++++++++++++ Services/Moteur.c | 26 +--- Services/Moteur.h | 31 ++++- Services/MyRF.c | 79 +++++------ Services/MyRF.h | 53 ++++++- Services/MySequencer.c | 36 ++++- Services/MySequencer.h | 14 +- Services/MyTimer.c | 248 +++++++++++++++++++++++++++++++++ Services/girouette.c | 113 +++++++++++++++ Src/main.c | 8 +- 17 files changed, 884 insertions(+), 153 deletions(-) create mode 100644 MyDrivers/GPIO.c create mode 100644 MyDrivers/GPIO.h create mode 100644 Services/ADC_antichavirement.c create mode 100644 Services/MyTimer.c create mode 100644 Services/girouette.c diff --git a/MDK-ARM/Project.uvoptx b/MDK-ARM/Project.uvoptx index bd0dccb..1b5bf42 100644 --- a/MDK-ARM/Project.uvoptx +++ b/MDK-ARM/Project.uvoptx @@ -479,7 +479,7 @@ 2 4 1 - 1 + 0 0 0 ..\Services\MySequencer.c @@ -523,7 +523,7 @@ 3 7 1 - 0 + 1 0 0 ..\MyDrivers\MyUSART.c @@ -543,6 +543,18 @@ 0 0 + + 3 + 9 + 1 + 0 + 0 + 0 + ..\MyDrivers\GPIO.c + GPIO.c + 0 + 0 + @@ -553,7 +565,7 @@ 0 4 - 9 + 10 1 0 0 @@ -565,7 +577,7 @@ 4 - 10 + 11 1 0 0 @@ -577,7 +589,7 @@ 4 - 11 + 12 1 0 0 @@ -589,7 +601,7 @@ 4 - 12 + 13 1 0 0 @@ -601,7 +613,7 @@ 4 - 13 + 14 1 0 0 @@ -621,7 +633,7 @@ 0 5 - 14 + 15 5 0 0 @@ -641,7 +653,7 @@ 0 6 - 15 + 16 1 0 0 @@ -661,7 +673,7 @@ 0 7 - 16 + 17 2 0 0 diff --git a/MDK-ARM/Project.uvprojx b/MDK-ARM/Project.uvprojx index 2c1aea2..d91e682 100644 --- a/MDK-ARM/Project.uvprojx +++ b/MDK-ARM/Project.uvprojx @@ -432,6 +432,11 @@ 1 ..\MyDrivers\MySysTick.c + + GPIO.c + 1 + ..\MyDrivers\GPIO.c + @@ -925,6 +930,11 @@ 1 ..\MyDrivers\MySysTick.c + + GPIO.c + 1 + ..\MyDrivers\GPIO.c + diff --git a/MyDrivers/GPIO.c b/MyDrivers/GPIO.c new file mode 100644 index 0000000..d6ec92c --- /dev/null +++ b/MyDrivers/GPIO.c @@ -0,0 +1,168 @@ +#include "stm32f1xx_ll_gpio.h" +#include "stm32f1xx_ll_bus.h" // Pour l'activation des horloges +#include "GPIO.h" + + +void conf_GPIO_girouette(void){ + + //PA5,6,7 + + //Définition + + LL_GPIO_InitTypeDef My_LL_GPIO_Init_Struct; + + //Initialisation + + LL_GPIO_StructInit(&My_LL_GPIO_Init_Struct); + + //GPIOA - PIN 5 (INDEX) + + My_LL_GPIO_Init_Struct.Mode=LL_GPIO_MODE_INPUT; + My_LL_GPIO_Init_Struct.Pin=LL_GPIO_PIN_5; + My_LL_GPIO_Init_Struct.Pull=LL_GPIO_PULL_DOWN; + + LL_GPIO_Init(GPIOA,&My_LL_GPIO_Init_Struct); + + //Initialisation + + LL_GPIO_StructInit(&My_LL_GPIO_Init_Struct); + + //GIOA - PIN 6 (CHA) + + My_LL_GPIO_Init_Struct.Mode=LL_GPIO_MODE_INPUT; + My_LL_GPIO_Init_Struct.Pin=LL_GPIO_PIN_6; + My_LL_GPIO_Init_Struct.Pull=LL_GPIO_PULL_DOWN; + + LL_GPIO_Init(GPIOA,&My_LL_GPIO_Init_Struct); + + //Initialisation + + LL_GPIO_StructInit(&My_LL_GPIO_Init_Struct); + + //GPIOA - PIN 7 (CHB) + + My_LL_GPIO_Init_Struct.Mode=LL_GPIO_MODE_INPUT; + My_LL_GPIO_Init_Struct.Pin=LL_GPIO_PIN_7; + My_LL_GPIO_Init_Struct.Pull=LL_GPIO_PULL_DOWN; + + LL_GPIO_Init(GPIOA,&My_LL_GPIO_Init_Struct); + + //Initialisation + + LL_GPIO_StructInit(&My_LL_GPIO_Init_Struct); + + + //GPIOA - PIN 8 (PWM) + + My_LL_GPIO_Init_Struct.Mode=LL_GPIO_MODE_ALTERNATE; + My_LL_GPIO_Init_Struct.Pin=LL_GPIO_PIN_8; + My_LL_GPIO_Init_Struct.OutputType=LL_GPIO_OUTPUT_PUSHPULL; + + LL_GPIO_Init(GPIOA,&My_LL_GPIO_Init_Struct); + +} + +void conf_GPIO_roulis(void){ + + //PC 0,1 + + //Définition + + LL_GPIO_InitTypeDef My_LL_GPIO_Init_Struct; + + //Initialisation + + LL_GPIO_StructInit(&My_LL_GPIO_Init_Struct); + + //GPIOC - PIN 0 + + My_LL_GPIO_Init_Struct.Mode=LL_GPIO_MODE_ANALOG; + My_LL_GPIO_Init_Struct.Pin=LL_GPIO_PIN_0; + My_LL_GPIO_Init_Struct.Pull=LL_GPIO_PULL_DOWN; + + LL_GPIO_Init(GPIOC,&My_LL_GPIO_Init_Struct); + + //Initialisation + + LL_GPIO_StructInit(&My_LL_GPIO_Init_Struct); + + //GPIOC - PIN 1 + + My_LL_GPIO_Init_Struct.Mode=LL_GPIO_MODE_ANALOG; + My_LL_GPIO_Init_Struct.Pin=LL_GPIO_PIN_1; + My_LL_GPIO_Init_Struct.Pull=LL_GPIO_PULL_DOWN; + + LL_GPIO_Init(GPIOC,&My_LL_GPIO_Init_Struct); + +}; + +void conf_GPIO_RF (void) { + + LL_GPIO_InitTypeDef My_GPIO_Init_Struct; + LL_GPIO_StructInit(&My_GPIO_Init_Struct); + + //RX : TIM4_CH1/2 (PWM In) + //PB.6 en floating input + My_GPIO_Init_Struct.Pin = LL_GPIO_PIN_6; + LL_GPIO_Init(GPIOB, &My_GPIO_Init_Struct); + + //PB.7 en floating input + My_GPIO_Init_Struct.Pin = LL_GPIO_PIN_7; + LL_GPIO_Init(GPIOB, &My_GPIO_Init_Struct); + + LL_GPIO_StructInit(&My_GPIO_Init_Struct); + + //TX : USART1 & Pin EN + //PA.9 en alternate output pp + My_GPIO_Init_Struct.Pin = LL_GPIO_PIN_9; + My_GPIO_Init_Struct.Mode = LL_GPIO_MODE_ALTERNATE; + My_GPIO_Init_Struct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + LL_GPIO_Init(GPIOA, &My_GPIO_Init_Struct); + + //PA.11 en output pp + My_GPIO_Init_Struct.Pin = LL_GPIO_PIN_11; + My_GPIO_Init_Struct.Mode = LL_GPIO_MODE_OUTPUT; + My_GPIO_Init_Struct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + LL_GPIO_Init(GPIOA, &My_GPIO_Init_Struct); + +} + + +void conf_GPIO_Moteur (void) { + + LL_GPIO_InitTypeDef My_GPIO_Init_Struct; + LL_GPIO_StructInit(&My_GPIO_Init_Struct); + + //Pin Sens + //PA.2 en output pp + My_GPIO_Init_Struct.Pin = LL_GPIO_PIN_2; + My_GPIO_Init_Struct.Mode = LL_GPIO_MODE_OUTPUT; + My_GPIO_Init_Struct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + LL_GPIO_Init(GPIOA, &My_GPIO_Init_Struct); + + + LL_GPIO_StructInit(&My_GPIO_Init_Struct); + + //Vitesse : TIM2_CH2 (PWM) + //PA.1 en alternate pp + My_GPIO_Init_Struct.Pin = LL_GPIO_PIN_1; + My_GPIO_Init_Struct.Mode = LL_GPIO_MODE_ALTERNATE; + My_GPIO_Init_Struct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + LL_GPIO_Init(GPIOA, &My_GPIO_Init_Struct); +} + + + +void conf_GPIO(void){ + + //Activation des horloges des GPIOS + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA); + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB); + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOC); + + conf_GPIO_girouette(); + conf_GPIO_roulis(); + conf_GPIO_Moteur(); + conf_GPIO_RF(); + +} diff --git a/MyDrivers/GPIO.h b/MyDrivers/GPIO.h new file mode 100644 index 0000000..9e75fe1 --- /dev/null +++ b/MyDrivers/GPIO.h @@ -0,0 +1,24 @@ +#ifndef GPIO_H +#define GPIO_H + +/* +Configuration de toutes les broches utilisées par les différentes fonctions : +- Moteur : PA.1 et PA.2 +- RF : PB.6, PB.7, PA.9 et PA.11 +- Accéléromètre : PC.0 et PC.1 +- Servo : PA.8 +- Girouette : PA.5, PA.6 et PA.7 +Manque PC.2 = adc batterie +*/ + +#include "stm32f103xb.h" + +/** + * @brief Configure les broches selon leurs utilisations + * @note Fonction à lancer en début de pgm. + * @param None + * @retval None + */ +void conf_GPIO(void); + +#endif diff --git a/MyDrivers/MyPWM.h b/MyDrivers/MyPWM.h index 1cb3719..a54be15 100644 --- a/MyDrivers/MyPWM.h +++ b/MyDrivers/MyPWM.h @@ -1,15 +1,42 @@ #ifndef MYPWM_H #define MYPWM_H +/* +Driver pour la gestion de la PWM de Timers 1 à 4 +*/ + #include "stm32f103xb.h" - +/** + * @brief Configure un signal PWM en mode Output + * @note Penser à appeler Timer_Conf() de Timer.h avant ! + * @param 1 timer, 1 channel + * @retval None + */ void MyPWM_Conf_Output(TIM_TypeDef * Timer, int channel); +/** + * @brief Configure un timer en mode PWM Input + * @note Penser à appeler Timer_Conf() de Timer.h avant ! + * @param 1 timer, 2 channels associés (1&2 ou 3&4) + * @retval None + */ void MyPWM_Conf_Input(TIM_TypeDef * Timer, int channel1, int channel2); +/** + * @brief Définit la durée de l'impulsion à l'état haut + * @note Fct utilisée en émission + * @param 1 timer, la valeur de changement de la PWM, 1 channel associé au timer + * @retval None + */ void MyPWM_Set_Impulse_Duration(TIM_TypeDef * Timer, uint32_t CompareValue, int channel); +/** + * @brief Renvoie le duty cycle de la PWM en entrée + * @note Fct utilisée en réception + * @param 1 timer et 2 channels associés (1&2 ou 3&4) + * @retval renvoie le duty cycle en pour mille pour améliorer la résolution + */ int MyPWM_Duty_Cycle_Permilles(TIM_TypeDef * Timer, int channel1, int channel2); #endif diff --git a/MyDrivers/MyUSART.c b/MyDrivers/MyUSART.c index 5a20a14..6f00083 100644 --- a/MyDrivers/MyUSART.c +++ b/MyDrivers/MyUSART.c @@ -3,12 +3,6 @@ #include "stm32f1xx_ll_usart.h" -/** - * @brief Active l'horloge et règle les paramètres de transmission - * @note Fonction à lancer avant toute autre. - * @param USART_TypeDef UsDollar : indique le usart à utiliser par le uC, USART1, USART2 ou USART3 - * @retval None - */ void MyUSART_Conf(USART_TypeDef * USART, int TransferDir) { LL_USART_InitTypeDef My_LL_USART_Init_Struct; @@ -34,38 +28,9 @@ void MyUSART_Conf(USART_TypeDef * USART, int TransferDir) LL_USART_Enable(USART); } -/** - * @brief Autorise les interruptions de TXE - * @note - * @param USART_TypeDef UsDollar : indique le usart à utiliser par le uC, USART1, USART2 ou USART3 - * @retval None - */ -void MyUSART_IT_Enable(USART_TypeDef * USART) -{ - LL_USART_EnableIT_TXE(USART); -} - -/** - * @brief Interdit les interruptions de TXE - * @note - * @param USART_TypeDef UsDollar : indique le usart à utiliser par le uC, USART1, USART2 ou USART3 - * @retval None - */ -void MyUSART_IT_Disable(USART_TypeDef * USART) -{ - LL_USART_DisableIT_TXE(USART); -} - - -/** - * @brief Transmet 8bits de donnée - * @note - * @param USART_TypeDef UsDollar : indique le usart à utiliser par le uC, USART1, USART2 ou USART3 - * @retval None - */ -void MyUSART_Transmit_Data_8b(USART_TypeDef * USART, int data) +void MyUSART_Transmit_Data_8b(USART_TypeDef * USART, char data) { LL_USART_TransmitData8(USART, data); - while (LL_USART_IsActiveFlag_TC(USART) != 1){} + while (LL_USART_IsActiveFlag_TC(USART) != 1){/*Attendre la fin de l'envoi*/} } diff --git a/MyDrivers/MyUSART.h b/MyDrivers/MyUSART.h index 691a3b3..5132dbe 100644 --- a/MyDrivers/MyUSART.h +++ b/MyDrivers/MyUSART.h @@ -3,42 +3,26 @@ /* Driver pour USART 1 à 3 du STM32F103RB - */ #include "stm32f103xb.h" /** * @brief Active l'horloge et règle les paramètres de transmission - * @note Fonction à lancer avant toute autre. - * @param USART_TypeDef UsDollar : indique le usart à utiliser par le uC, USART1, USART2 ou USART3 + * @note Fonction à lancer en début de pgm. + * @param USART_TypeDef USART : indique l'usart à utiliser par le uC, USART1, USART2 ou USART3 * @retval None */ void MyUSART_Conf(USART_TypeDef * USART, int TransferDir); -/** - * @brief Autorise les interruptions de TXE - * @note - * @param USART_TypeDef UsDollar : indique le usart à utiliser par le uC, USART1, USART2 ou USART3 - * @retval None - */ -void MyUSART_IT_Enable(USART_TypeDef * USART); - -/** - * @brief Interdit les interruptions de TXE - * @note - * @param USART_TypeDef UsDollar : indique le usart à utiliser par le uC, USART1, USART2 ou USART3 - * @retval None - */ -void MyUSART_IT_Disable(USART_TypeDef * USART); - /** * @brief Transmet 8bits de donnée * @note - * @param USART_TypeDef UsDollar : indique le usart à utiliser par le uC, USART1, USART2 ou USART3 + * @param USART_TypeDef USART : indique l'usart à utiliser par le uC, USART1, USART2 ou USART3 + * @param char data : la donnée sur 8bits à transmettre * @retval None */ -void MyUSART_Transmit_Data_8b(USART_TypeDef * USART, int data); +void MyUSART_Transmit_Data_8b(USART_TypeDef * USART, char data); #endif diff --git a/Services/ADC_antichavirement.c b/Services/ADC_antichavirement.c new file mode 100644 index 0000000..78eda8e --- /dev/null +++ b/Services/ADC_antichavirement.c @@ -0,0 +1,101 @@ +#include "ADC_antichavirement.h" +#include "Chrono.h" +#include "MyTimer.h" +#include "stm32f1xx_ll_bus.h" +#include "stm32f1xx_ll_tim.h" +#include "stm32f1xx_ll_adc.h" +#include "stm32f1xx_ll_rcc.h" + +#define seuil_g_pos 1.0 +#define seuil_g_neg -1.0 + +void conf_ADC (void) { + + //ADC_REG + + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC1); + + //Division pour etre < 14 MHz + + LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSRC_PCLK2_DIV_6); + + //Bit ADON à 1 + + LL_ADC_Enable(ADC1); + + //Définition + + LL_ADC_REG_InitTypeDef My_LL_ADC_REG_Init_Struct; + + //Initialisation + + LL_ADC_REG_StructInit(&My_LL_ADC_REG_Init_Struct); + + My_LL_ADC_REG_Init_Struct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_1RANK ; + + LL_ADC_StartCalibration(ADC1); + + //Application a l'ADC1 + + LL_ADC_REG_Init(ADC1,&My_LL_ADC_REG_Init_Struct); + + + //ADC Sampling Time + + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_10, LL_ADC_SAMPLINGTIME_239CYCLES_5); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_11, LL_ADC_SAMPLINGTIME_239CYCLES_5); +} + + +uint32_t X; +uint32_t Y; +float rapport; + +float start_ADC (void) { + + //Conversion X + + LL_ADC_REG_SetSequencerRanks(ADC1,LL_ADC_REG_RANK_1,LL_ADC_CHANNEL_10); + + LL_ADC_Enable(ADC1); + + LL_ADC_REG_StartConversionSWStart(ADC1); + + while ( LL_ADC_IsActiveFlag_EOS(ADC1) == 0); + + X=LL_ADC_REG_ReadConversionData32(ADC1); + + + //Conversion Y + + LL_ADC_REG_SetSequencerRanks(ADC1,LL_ADC_REG_RANK_1,LL_ADC_CHANNEL_11); + + LL_ADC_Enable(ADC1); + + LL_ADC_REG_StartConversionSWStart(ADC1); + + while ( LL_ADC_IsActiveFlag_EOS(ADC1) == 0); + + Y=LL_ADC_REG_ReadConversionData32(ADC1); + + + //Calcul rapport + + rapport = X/Y; + + return rapport; + +} + + +void antichavirement (float rapport) { + + if (rapport >= seuil_g_pos || rapport <= seuil_g_neg){ + + //Voiles à 90° + MyPWM_Set_Impulse_Duration(TIM1,10000*10/100,LL_TIM_CHANNEL_CH1); + + } + + +} diff --git a/Services/Moteur.c b/Services/Moteur.c index 19640e9..0e496b8 100644 --- a/Services/Moteur.c +++ b/Services/Moteur.c @@ -14,31 +14,6 @@ void Moteur_Conf(void) { int Arr = 0x1C1F; int Psc = 0x0; - //Activation horloge GPIO - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA); - - //Config broche PA2 -> Sens - LL_GPIO_InitTypeDef My_GPIO_Init_Struct; - - LL_GPIO_StructInit(&My_GPIO_Init_Struct); - - My_GPIO_Init_Struct.Pin = PinSens; - My_GPIO_Init_Struct.Mode = LL_GPIO_MODE_OUTPUT; - My_GPIO_Init_Struct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; - - LL_GPIO_Init(GPIOPins, &My_GPIO_Init_Struct); - - //Config broche PA1 -> PWM - LL_GPIO_StructInit(&My_GPIO_Init_Struct); - - My_GPIO_Init_Struct.Pin = LL_GPIO_PIN_1; - My_GPIO_Init_Struct.Mode = LL_GPIO_MODE_ALTERNATE; - My_GPIO_Init_Struct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; - - LL_GPIO_Init(GPIOA, &My_GPIO_Init_Struct); - - - //Activation horloge Timer LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); @@ -57,6 +32,7 @@ void Moteur_Conf(void) { void Moteur_Speed(int speedPercentage) { int Arr = 0x1C1F; + //Arrêt du Timer si pas de vitesse if(speedPercentage == 0) { MyTimer_Stop(TimerPWM); } diff --git a/Services/Moteur.h b/Services/Moteur.h index 32cdb88..ad2eb61 100644 --- a/Services/Moteur.h +++ b/Services/Moteur.h @@ -1,18 +1,47 @@ #ifndef MOTEUR_H #define MOTEUR_H +/* +Driver permettant de contrôler le moteur CC qui fait tourner le plateau +La définition des pins utilisées est faites dans un autre fichier (GPIO.c) +Vitesse : + - Timer 2 + - Channel 2 + - Broche PA.1 +Sens : + - Broche PA.2 +*/ + #include "stm32f103xb.h" #define PinSens LL_GPIO_PIN_2 -#define PinPWM LL_GPIO_PIN_1 #define GPIOPins GPIOA #define TimerPWM TIM2 #define channelPWM LL_TIM_CHANNEL_CH2 + +/** + * @brief Configure le moteur + * @note À lancer en début de pgm + * @param None + * @retval None + */ void Moteur_Conf(void); +/** + * @brief Définit la vitesse de rotation du plateau + * @note + * @param int speedPercentage : [0; 100] (%) de la vitesse max + * @retval None + */ void Moteur_Speed(int speedPercentage); +/** + * @brief définit le sens de rotation du plateau + * @note + * @param int sens : 0 pour un sens, un int non nul pour l'autre ({0;1} attendu) + * @retval None + */ void Moteur_Sens(int sens); #endif diff --git a/Services/MyRF.c b/Services/MyRF.c index c65cbaf..db6f37a 100644 --- a/Services/MyRF.c +++ b/Services/MyRF.c @@ -3,7 +3,6 @@ #include "MyPWM.h" #include "MyUSART.h" -#include "stm32f1xx_ll_bus.h" // Pour l'activation des horloges #include "stm32f1xx_ll_tim.h" #include "stm32f1xx_ll_gpio.h" #include "stm32f1xx_ll_usart.h" @@ -12,68 +11,58 @@ void MyRF_Conf(void) { //RX - //Activation horloge du GPIO - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB); - - LL_GPIO_InitTypeDef My_GPIO_Init_Struct; - LL_GPIO_StructInit(&My_GPIO_Init_Struct); - - //PB.6 en floating input - My_GPIO_Init_Struct.Pin = PinCH1; - LL_GPIO_Init(GPIOIn, &My_GPIO_Init_Struct); - - //PB.7 en floating input - My_GPIO_Init_Struct.Pin = PinCH2; - LL_GPIO_Init(GPIOIn, &My_GPIO_Init_Struct); - - - //Configuration et lancment du Timer PWM Input + //Configuration et lancement du Timer PWM Input MyTimer_Conf(TimerCC,0xFFAD,0x15); MyPWM_Conf_Input(TimerCC, channelCC1, channelCC2); MyTimer_Start(TimerCC); //TX - //Activation horloge du GPIO - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA); - - LL_GPIO_StructInit(&My_GPIO_Init_Struct); - - //PA.9 en alternate output pp - My_GPIO_Init_Struct.Pin = PinOut; - My_GPIO_Init_Struct.Mode = LL_GPIO_MODE_ALTERNATE; - My_GPIO_Init_Struct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; - LL_GPIO_Init(GPIOOut, &My_GPIO_Init_Struct); - - //PA.11 en output pp - My_GPIO_Init_Struct.Pin = PinTXEn; - My_GPIO_Init_Struct.Mode = LL_GPIO_MODE_OUTPUT; - My_GPIO_Init_Struct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; - LL_GPIO_Init(GPIOOut, &My_GPIO_Init_Struct); - //Configuration de l'USART MyUSART_Conf(USARTOut, TransferDirTX); } + int MyRF_Input_Duty_Cycle(void) { int duty_cycle_RC = MyPWM_Duty_Cycle_Permilles(TimerCC, channelCC1, channelCC2); + //Seuil de +-10% autour de la valeur centrale if (74 -100 à 100 return (duty_cycle_RC - 75) * 4; } } -void MyRF_Transmit_3s(void) { +void MyRF_Transmit_3s(int bordage_pc, int angle_vent) { - //Récupérer : - char bordage[3] = ""; - char heure[2] = "xx"; - char min[2] = "xx"; - char sec[2] = "xx"; - int allure_ref = 3; + //Conversion bordage int => chaîne de char + char bordage[3] = {bordage_pc/100+48,(bordage_pc%100-bordage_pc%10)/10+48,bordage_pc%100+48}; + //Conversion angle du vent int => dénomination de l'allure + int allure_ref; + if(angle_vent <45) { + allure_ref = 0; + } + else if (angle_vent == 45) { + allure_ref = 1; + } + else if (angle_vent < 60) { + allure_ref = 2; + } + else if (angle_vent < 90) { + allure_ref = 3; + } + else if (angle_vent < 120) { + allure_ref = 4; + } + else if (angle_vent < 160) { + allure_ref = 5; + } + else { + allure_ref = 6; + } char allure[7][16]= {"vent debout.", "au plus près.", "au près.", @@ -82,12 +71,16 @@ void MyRF_Transmit_3s(void) { "au grand largue.", "au vent arrière." }; + + char heure[2] = "xx"; + char min[2] = "xx"; + char sec[2] = "xx"; + char data1[14] = "\" - Bordage : "; char data2[24] = " === Le voilier navigue "; int i; - - + //Activation de l'émetteur RF LL_GPIO_SetOutputPin(GPIOOut ,PinTXEn); diff --git a/Services/MyRF.h b/Services/MyRF.h index e427a70..8627a75 100644 --- a/Services/MyRF.h +++ b/Services/MyRF.h @@ -1,29 +1,68 @@ #ifndef MYRF_H #define MYRF_H +/* +Driver permettant de communiquer via le module RF +La définition des pins utilisées est faites dans un autre fichier (GPIO.c) +RX : + - Timer 4 + - Channels 1 et 2 + - Broches PB.6 et PB.7 +TX : + - USART1 + - Broche PA.9 (Données) et PA.11 (Enable) +*/ + #include "stm32f103xb.h" -#define PinCH1 LL_GPIO_PIN_6 -#define PinCH2 LL_GPIO_PIN_7 -#define PinOut LL_GPIO_PIN_9 -#define PinTXEn LL_GPIO_PIN_11 -#define GPIOIn GPIOB #define GPIOOut GPIOA +#define PinTXEn LL_GPIO_PIN_11 #define TimerCC TIM4 #define channelCC1 LL_TIM_CHANNEL_CH1 #define channelCC2 LL_TIM_CHANNEL_CH2 #define USARTOut USART1 #define TransferDirTX LL_USART_DIRECTION_TX - +/** + * @brief Configure le module RF pour la RX et la TX (Timer4 en PWM In sur CH1/2 et USART1) + * @note À lancer en début de pgm + * @note Période TIM4 = 20ms, Transfer Dir USART = TX + * @param None + * @retval None + */ void MyRF_Conf(void); +/** + * @brief Retourne le rapport cyclique de la PWM en provenance du récepteur RF + * @note Seuil de détection de +-10% autour du 0 + * @param None + * @retval int : [-100; 100] pour correspondre à la plage du moteur + */ int MyRF_Duty_Cycle_Moteur(void); -void MyRF_Transmit_3s(void); +/** + * @brief Transmet un message via l'USART vers l'émetteur RF + * @note Message : "h'" - Bordage : % === Le voilier navigue ." + * @param int bordage_pc : pourcentage du bordage des voiles [0; 100] + * @param int angle_vent : angle du vent par rapport au bateau [0; 180] + * @retval None + */ +void MyRF_Transmit_3s(int bordage_pc, int angle_vent); +/** + * @brief Transmet un message via l'USART vers l'émetteur RF + * @note Message : "/!\ BATTERIE FAIBLE /!\" + * @param None + * @retval None + */ void MyRF_Transmit_Batterie_Faible(void); +/** + * @brief Transmet un message via l'USART vers l'émetteur RF + * @note Message : "/!\ RISQUE DE CHAVIREMENT /!\" + * @param None + * @retval None + */ void MyRF_Transmit_Limite_Roulis(void); #endif diff --git a/Services/MySequencer.c b/Services/MySequencer.c index 5025e9c..88a6599 100644 --- a/Services/MySequencer.c +++ b/Services/MySequencer.c @@ -1,7 +1,10 @@ #include "MySequencer.h" #include "MySysTick.h" +#include "Moteur.h" +#include "MyRF.h" +#include "girouette.h" - +int cnt_3sec = 0; void MySequencer_Conf(void) { @@ -11,6 +14,35 @@ void MySequencer_Conf(void) { } + +/** + * @brief Tâche à lancer toutes les 10ms + * @note None + * @param None + * @retval None + */ void MySequencer_Task_10ms (void) { - __nop(); + + //Incrémentation du compteur pour envoi toutes les 3 secondes + cnt_3sec++; + + //Transmission données toutes les 3 secondes + if(cnt_3sec == 300) { + MyRF_Transmit_3s((int)((Calcul_pourcentage_duree()-5.0)*20.0), (int)(Angle_Vent())); + cnt_3sec = 0; + } + + //Réglage sens et vitesse moteur + int Duty_Cycle = MyRF_Duty_Cycle_Moteur(); + if (Duty_Cycle >= 0) { + Moteur_Speed(Duty_Cycle); + Moteur_Sens(1); + } + else { + Moteur_Speed(-Duty_Cycle); + Moteur_Sens(0); + } + + + } diff --git a/Services/MySequencer.h b/Services/MySequencer.h index fd85424..7aab328 100644 --- a/Services/MySequencer.h +++ b/Services/MySequencer.h @@ -1,10 +1,20 @@ #ifndef MY_SEQ_H #define MY_SEQ_H +/* +Service qui gère le séquenceur principal du pgm +Permet la mise à jour des différentes données du pgm +S'appuie sur le SysTick, réglé pour interruption toutes les 10ms +*/ + #include "stm32f103xb.h" +/** + * @brief configure un séquenceur qui s'exécute toutes les 10ms + * @note Fct à lancer en début de programme + * @param None + * @retval None + */ void MySequencer_Conf(void); -void MySequencer_Task_10ms (void); - #endif diff --git a/Services/MyTimer.c b/Services/MyTimer.c new file mode 100644 index 0000000..062839f --- /dev/null +++ b/Services/MyTimer.c @@ -0,0 +1,248 @@ +// 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 "MyTimer.h" +#include "stm32f1xx_ll_bus.h" // Pour l'activation des horloges +#include "stm32f1xx_ll_tim.h" + + +// variable pointeur de fonction permettant de mémoriser le callback à appeler depuis +// le handler d'IT +void (*Ptr_ItFct_TIM1)(void); +void (*Ptr_ItFct_TIM2)(void); +void (*Ptr_ItFct_TIM3)(void); +void (*Ptr_ItFct_TIM4)(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) +{ + LL_TIM_InitTypeDef My_LL_Tim_Init_Struct; + + // 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 + My_LL_Tim_Init_Struct.Autoreload=0xFFFF; + My_LL_Tim_Init_Struct.Prescaler=0; + 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); + +} + +//CONFIG Timer en compteur + +void MyTimer_girouette_Conf(void) +{ + + LL_TIM_ENCODER_InitTypeDef My_LL_Tim_Init_Struct; + + // Validation horloge locale + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3); + + LL_TIM_ENCODER_StructInit(&My_LL_Tim_Init_Struct); + + LL_TIM_ENCODER_Init(TIM3, &My_LL_Tim_Init_Struct); + + // Réglage Timer 3 + LL_TIM_SetAutoReload(TIM3,0xFFFF); + LL_TIM_SetPrescaler(TIM3,0); + +} + +//CONFIG Timer en PWM + +void MyPWM_Conf_Output(TIM_TypeDef *TIMx, uint32_t Channel) +{ + + LL_TIM_OC_InitTypeDef My_LL_Tim_OC_Init_Struct; + + //Configuration du output channel en PWM + LL_TIM_OC_StructInit(&My_LL_Tim_OC_Init_Struct); + My_LL_Tim_OC_Init_Struct.OCMode = LL_TIM_OCMODE_PWM1; + + LL_TIM_OC_Init(TIMx,Channel,&My_LL_Tim_OC_Init_Struct); + + // Réglage Timer + LL_TIM_SetAutoReload(TIMx,0x707F); + LL_TIM_SetPrescaler(TIMx,0x31); + + //Activation du channel (CH3) pour le timer considéré + LL_TIM_CC_EnableChannel(TIMx, Channel); +} + + +void MyPWM_Set_Impulse_Duration(TIM_TypeDef * Timer, int Percentage, int channel) +{ + static uint32_t Val_ARR; + static uint32_t CompareValue; + + Val_ARR = LL_TIM_GetAutoReload(Timer); + CompareValue = (Val_ARR * Percentage)/10000; + + if (channel==LL_TIM_CHANNEL_CH1) LL_TIM_OC_SetCompareCH1(Timer, CompareValue); + else if (channel==LL_TIM_CHANNEL_CH2) LL_TIM_OC_SetCompareCH2(Timer, CompareValue); + else if (channel==LL_TIM_CHANNEL_CH3) LL_TIM_OC_SetCompareCH3(Timer, CompareValue); + else LL_TIM_OC_SetCompareCH4(Timer, CompareValue); +} + + +/** + * @brief PWM servo moteur + * @note + * @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4 + * @retval None + */ + +void MyTimer_PWMservo_Conf(void) +{ + MyPWM_Conf_Output(TIM4, LL_TIM_CHANNEL_CH3); +} + +/** + * @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); +} + +/** + * @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); +} + + +/** + * @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 + if (Timer==TIM1) Ptr_ItFct_TIM1=IT_function; + else if (Timer==TIM2) Ptr_ItFct_TIM2=IT_function; + 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); + + +} + + +/** + * @brief Autorise les interruptions + * @note + * @param TIM_TypeDef Timer : indique le timer à utiliser par le chronomètre, TIM1, TIM2, TIM3 ou TIM4 + * @retval None + */ +void MyTimer_IT_Enable(TIM_TypeDef * Timer) +{ + LL_TIM_EnableIT_UPDATE(Timer); +} + + +/** + * @brief Interdit les interruptions + * @note + * @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) +{ + LL_TIM_DisableIT_UPDATE(Timer); +} + + +/* +============ LES INTERRUPTIONS ================================= + +*/ + +void TIM1_UP_IRQHandler(void) +{ + // rabaisser le flag d'IT + LL_TIM_ClearFlag_UPDATE(TIM1); + (*Ptr_ItFct_TIM1)(); +} + +void TIM2_IRQHandler(void) +{ + // rabaisser le flag d'IT + LL_TIM_ClearFlag_UPDATE(TIM2); + (*Ptr_ItFct_TIM2)(); +} + +void TIM3_IRQHandler(void) +{ + // rabaisser le flag d'IT + LL_TIM_ClearFlag_UPDATE(TIM3); + (*Ptr_ItFct_TIM3)(); +} + +void TIM4_IRQHandler(void) +{ + // rabaisser le flag d'IT + LL_TIM_ClearFlag_UPDATE(TIM4); + (*Ptr_ItFct_TIM4)(); +} diff --git a/Services/girouette.c b/Services/girouette.c new file mode 100644 index 0000000..4224052 --- /dev/null +++ b/Services/girouette.c @@ -0,0 +1,113 @@ +#include "stm32f1xx_ll_gpio.h" +#include "girouette.h" +#include "MyTimer.h" +#include "stm32f1xx_ll_bus.h" +#include "stm32f1xx_ll_tim.h" +#include "stm32f1xx_ll_adc.h" +#include "stm32f1xx_ll_rcc.h" + +//Configuration de l'interruption exterieure +void exti_ref(void){ + + LL_GPIO_AF_SetEXTISource(LL_GPIO_AF_EXTI_PORTA, LL_GPIO_AF_EXTI_LINE5); + + AFIO->EXTICR[2] |= AFIO_EXTICR2_EXTI5_PA; + + EXTI->IMR |= EXTI_IMR_MR5_Msk; + EXTI->RTSR |= EXTI_RTSR_TR5_Msk; +} + +//Configuration de l'interruption du NVIC +void nvic_exti_conf(void){ + NVIC->IP[23]=2<<4; + NVIC->ISER[0]=1<<23; +} + +//redirection de l'interruption +void EXTI9_5_IRQHandler(void){ + //CNT A ZERO + LL_TIM_SetCounter(TIM3, 0); + //enlever le pin de pending en le mettant a 1 + EXTI->PR |= EXTI_PR_PR5_Msk; +} + + + +//configuration interruption + timer 3 en mode encodeur et 4 en mode PWM +void conf_girouette(void){ + + //interruption + exti_ref(); + nvic_exti_conf(); + + + //Timer en mode encodeur + MyTimer_girouette_Conf(); + + //Timer en mode PWM + MyPWM_Conf_Output(TIM1,LL_TIM_CHANNEL_CH1); + + //Activation Timer 1 + LL_TIM_EnableAllOutputs(TIM1); + +} + + +//Calcul position-angle + +float pos_Min=0; +float pos_Max=135; +float pos_actuelle; + +float duree_Min=1; +float duree_Max=2; +float duree_calc; + +float Periode=20; +float Pourcentage_Min; +float Pourcentage_Max; + +float Pourcentage_calc; + +float Calcul_pourcentage_duree (void){ + + pos_actuelle=LL_TIM_GetCounter(TIM3); + + //Calcul pourcentage min et max + Pourcentage_Min=duree_Min/Periode; + Pourcentage_Max=duree_Max/Periode; + + //Calcul fctn affine + if (pos_actuelle <= 360){ + if (pos_actuelle > 90 && pos_actuelle < 270) { + duree_calc=((duree_Max-duree_Min)/(pos_Max-pos_Min))*pos_actuelle+duree_Min; + } + else if (pos_actuelle > 270){ + duree_calc=duree_Max; + } + else { + duree_calc=duree_Min; + } + } + + /*if (pos_actuelle > 360 && pos_actuelle < 720){ + if (pos_actuelle > 450 && pos_actuelle < 630) { + duree_calc=((duree_Max-duree_Min)/(pos_Max-pos_Min))*(720-pos_actuelle)+duree_Min; + } + else if (pos_actuelle < 450){ + duree_calc=duree_Max; + } + else { + duree_calc=duree_Min; + } + }*/ + + //Calcul pourcentage + Pourcentage_calc=((Pourcentage_Max-Pourcentage_Min)/(duree_Max-duree_Min))*duree_calc; + + return Pourcentage_calc; +} + +float Angle_Vent(void) { + return pos_actuelle/2.0; +} diff --git a/Src/main.c b/Src/main.c index 8ac31fa..a7a0fb5 100644 --- a/Src/main.c +++ b/Src/main.c @@ -19,13 +19,12 @@ #include "stm32f1xx_ll_rcc.h" // utile dans la fonction SystemClock_Config #include "stm32f1xx_ll_utils.h" // utile dans la fonction SystemClock_Config #include "stm32f1xx_ll_system.h" // utile dans la fonction SystemClock_Config -#include "stm32f1xx_ll_gpio.h" -#include "MyTimer.h" -#include "MyPWM.h" + #include "MyRF.h" #include "Moteur.h" -#include "MySysTick.h" #include "MySequencer.h" +#include "girouette.h" + void SystemClock_Config(void); @@ -44,6 +43,7 @@ int main(void) SystemClock_Config(); MyRF_Conf(); + Moteur_Conf(); MySequencer_Conf(); /* Infinite loop */