/** ****************************************************************************** * @file motor.c * @author Lucien Senaneuch * @version V1.0 * @date 16-mai-2016 * @brief Gestion des moteurs du robots * Ce fichier contient les fonctions lié à la gestions du moteur : * - L'initialisation des PIN utilisé par les moteurs et encodeurs * - L'initialisation du Timer2 servant de bases de temps aux PWM pour * moteur1 et moteur2 * - L'initialisation du Timer3 servant à échantilloner les capteurs magnétique de position * des 2 moteurs. * - La commandes des moteurs dans leurs 3 modes de fonctionnement (AVANT, ARRIERE, FREIN) * et de leurs vitesse (valeur de PWM entre 0 et 255). * * @note TABLE DE VERITEE DU DRIVER MOTEUR * * ENABLE | INPUTS | Moteurs * | | * 0 | X | Roue Libre *-------------------------------------------------------------------- * | CMDA & !CMDB | Avant * 1 | !CMDA & CMDB | Arrière * | CMDA = CMDB | Frein ****************************************************************************** ****************************************************************************** */ #include #include "system_dumby.h" #include "motor.h" /** * @brief Variables globales nombre d'incrémentation de capteur de position de la roue droite. * @note tourPositionG correspond exactement à la même valeur. */ uint16_t tourD = 0; /** * @brief Variables globales nombre d'incrémentation de capteur de position de la roue gauche. * @note tourPositionG correspond exactement à la même valeur. */ uint16_t tourG = 0; uint16_t tourPositionD; uint16_t tourPositionG; /** * @brief Variables globales des consignes de vitesses du moteur droit. * @note Variables utilisées dans le programme principal main.c */ uint16_t G_speedRight=20; /** * @brief Variables globales des consignes de vitesses du moteur gauche. * @note Variables utilisées dans le programme principal main.c */ uint16_t G_speedLeft=20; /** * @brief Variables globales des consignes de position du moteur gauche. * @note Variables utilisées dans le programme principal main.c */ uint16_t G_lapsLeft; /** * @brief Variables globales des consignes de position du moteur droit. * @note Variables utilisées dans le programme principal main.c */ uint16_t G_lapsRight; float integration1 = 0; float integration2 = 0; /** * @brief Coefficient PI */ const float kp = 15; /** * @brief Coefficient PI */ const float ki = 1.5; /** * @brief Valeurs de vitesse */ float motD = 0, motG = 0; /** * @brief erreurs entre vitesse réelle et moteur (droite) */ int erreurD; /** * @brief erreurs entre vitesse réelle et moteur (gauche) */ int erreurG; uint16_t asservissement; uint16_t regulation_vitesseD, regulation_vitesseG; /** @addtogroup Projects * @{ */ /** @addtogroup Robot Motor * @{ */ /** @addtogroup Init Init GPIO - IT - Timers * @{ */ /** * @brief Assigne et définis le GPIO nécessaire pour le moteur. * * La fonction MAP_MotorPin va venir configurer le E/S du GPIO pour correspondre avec * le schéma électrique en ressource. * @note 2 pwm en alternate fonction : PA1,PA2. 4 entr�e timer. * PA8,PA9,PA10,PA11. 4 sortie ppull PB12,PB13,PB14,PB15 * * @param None * @retval None * */ void motorConfigure(void) { GPIO_InitTypeDef Init_Structure; TIM_TimeBaseInitTypeDef TIM2_TempsPWMsettings; TIM_OCInitTypeDef TIM2_Configure; TIM_ICInitTypeDef TIM_ICInitStructure; NVIC_InitTypeDef NVIC_InitStructure; // Configure les PIN A1 et A2 en output / alternate fonction Init_Structure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2; Init_Structure.GPIO_Speed = GPIO_Speed_50MHz; Init_Structure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &Init_Structure); // Configure les PIN B12,B13,B14, et B15 en output ppull. Init_Structure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; Init_Structure.GPIO_Speed = GPIO_Speed_50MHz; Init_Structure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &Init_Structure); // Configure les PIN A12 en output ppull - enable encodeurs Init_Structure.GPIO_Pin = GPIO_Pin_12; Init_Structure.GPIO_Speed = GPIO_Speed_50MHz; Init_Structure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &Init_Structure); // Configure les PIN A8,A9,A10, et A11 en input floating. Init_Structure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11; Init_Structure.GPIO_Speed = GPIO_Speed_50MHz; Init_Structure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &Init_Structure); // Configuration du timer 2 (pwm moteurs* // On souhaite une résolution du PWM de 256 valeurs MOTOR1 TIM2 TIM2_TempsPWMsettings.TIM_Period = 255; TIM2_TempsPWMsettings.TIM_Prescaler = 0; TIM2_TempsPWMsettings.TIM_ClockDivision=0; TIM2_TempsPWMsettings.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM2_TempsPWMsettings); // Configuration du PWM sur le timer 2 TIM2_Configure.TIM_OCMode=TIM_OCMode_PWM2; TIM2_Configure.TIM_OutputState = TIM_OutputState_Enable; TIM2_Configure.TIM_OutputNState = TIM_OutputNState_Enable; TIM2_Configure.TIM_Pulse = 256; // Constante initialisée à 256, pour un rapport cyclique nul TIM2_Configure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC3Init(TIM2, &TIM2_Configure); TIM_OC3PreloadConfig(TIM2,TIM_OCPreload_Enable); TIM_OC2Init(TIM2, &TIM2_Configure); TIM_OC2PreloadConfig(TIM2,TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM2, ENABLE); // Enable Counter TIM_Cmd(TIM2, ENABLE); TIM_CtrlPWMOutputs(TIM2,ENABLE); // Configuration de la capture de l'encodeur 1 TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_ICInit(TIM1, &TIM_ICInitStructure); TIM_Cmd(TIM1, ENABLE); TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE); // Configuration de la capture de l'encodeur 1 TIM_ICInitStructure.TIM_Channel = TIM_Channel_3; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_ICInit(TIM1, &TIM_ICInitStructure); TIM_Cmd(TIM1, ENABLE); TIM_ITConfig(TIM1, TIM_IT_CC3, ENABLE); // Enable the TIM1 Capture interrupt NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // RAZ des variables regulation_vitesseD = 0; regulation_vitesseG = 0; asservissement =0; } /** * @} */ /** @addtogroup Regulation Reg Speed * @{ */ /** * @brief Commande de plus haut niveau pour contrôler le moteur droit. * * @param Mode de fonctionnement du moteur, peut être égal aux constantes BRAKE, FORWARD, REVERSE définis dans moteur.h * @param Consigne de vitesse du moteur, défini par un pwm entre 0 et 255. * @retval None */ void motorCmdRight(char mod, uint16_t pwm) { pwm = 256 - pwm; switch (mod) { case BRAKE: GPIO_SetBits(GPIOB, GPIO_Pin_12); GPIO_SetBits(GPIOB, GPIO_Pin_13); break; case FORWARD: GPIO_SetBits(GPIOB, GPIO_Pin_12); GPIO_ResetBits(GPIOB, GPIO_Pin_13); break; case REVERSE: GPIO_SetBits(GPIOB, GPIO_Pin_13); GPIO_ResetBits(GPIOB, GPIO_Pin_12); break; default: GPIO_ResetBits(GPIOB, 12); GPIO_ResetBits(GPIOB, 13); } TIM_SetCompare3(TIM2, pwm); } /** * @brief Commande de plus haut niveau pour contrôler le moteur Gauche. * * @param Mode de fonctionnement du moteur, peut être égal aux constantes BRAKE, FORWARD, REVERSE définis dans moteur.h * @param Consigne de vitesse du moteur, défini par un pwm entre 0 et 255. * @retval None */ void motorCmdLeft(char mod, uint16_t pwm) { pwm = 256 - pwm; switch (mod) { case BRAKE: GPIO_SetBits(GPIOB, GPIO_Pin_14); GPIO_SetBits(GPIOB, GPIO_Pin_15); break; case FORWARD: GPIO_SetBits(GPIOB, GPIO_Pin_15); GPIO_ResetBits(GPIOB, GPIO_Pin_14); break; case REVERSE: GPIO_SetBits(GPIOB, GPIO_Pin_14); GPIO_ResetBits(GPIOB, GPIO_Pin_15); break; default: GPIO_ResetBits(GPIOB, GPIO_Pin_14); GPIO_ResetBits(GPIOB, GPIO_Pin_15); } TIM_SetCompare2(TIM2, pwm); } /** * @brief Commande de plus haut niveau pour contrôler la vitesse moteur Gauche. * * @param Consigne de vitesse du moteur, défini par un pwm entre 0 et 255. * @retval None */ void motorSpeedUpdateLeft(uint16_t pwm) { pwm = 256 - pwm; TIM_SetCompare2(TIM2, pwm); } /** * @brief Commande de plus haut niveau pour contrôler la vitesse moteur Droit. * * @param Consigne de vitesse du moteur, défini par un pwm entre 0 et 255. * @retval None */ void motorSpeedUpdateRight(uint16_t pwm) { pwm = 256 - pwm; TIM_SetCompare3(TIM2, pwm); } /** * @brief Régulation des deux moteurs. * * Modifie le le mode de fonctionnement des roues, puis * va mettre à jour les variables globale G_laps* et G_speed* * utilisé dans main.c pour l'asservissement. * * @param Mode de fonctionnement la roue droite (BRAKE, REVERSE, FORWARD) * @param Mode de fonctionnement la roue droite (BRAKE, REVERSE, FORWARD) * @param Nombre de tour de roue droite à effectuer. * @param Nombre de tour de roue gauche à effectuer. * @param Vitesse de la roue de droite. * @param Vitesse de la roue de gauche. * * @retval None */ void motorRegulation(char modRight, char modLeft, uint16_t lapsRight, uint16_t lapsLeft, uint16_t speedRight, uint16_t speedLeft) { /*Moteur Droit*/ switch (modRight) { case BRAKE: GPIO_SetBits(GPIOB, GPIO_Pin_12); GPIO_SetBits(GPIOB, GPIO_Pin_13); break; case FORWARD: GPIO_SetBits(GPIOB, GPIO_Pin_12); GPIO_ResetBits(GPIOB, GPIO_Pin_13); break; case REVERSE: GPIO_SetBits(GPIOB, GPIO_Pin_13); GPIO_ResetBits(GPIOB, GPIO_Pin_12); break; default: GPIO_ResetBits(GPIOB, 12); GPIO_ResetBits(GPIOB, 13); } /* Moteur Gauche */ switch (modLeft) { case BRAKE: GPIO_SetBits(GPIOB, GPIO_Pin_14); GPIO_SetBits(GPIOB, GPIO_Pin_15); break; case FORWARD: GPIO_SetBits(GPIOB, GPIO_Pin_15); GPIO_ResetBits(GPIOB, GPIO_Pin_14); break; case REVERSE: GPIO_SetBits(GPIOB, GPIO_Pin_14); GPIO_ResetBits(GPIOB, GPIO_Pin_15); break; default: GPIO_ResetBits(GPIOB, GPIO_Pin_14); GPIO_ResetBits(GPIOB, GPIO_Pin_15); } if ((speedRight == 0 && lapsRight > 0) || (speedLeft == 0 && lapsLeft > 0)) { while (1); } G_lapsLeft = lapsLeft; G_speedLeft = speedLeft; G_lapsRight = lapsRight; G_speedRight = speedRight; asservissement = 1; tourPositionD = 0; tourPositionG = 0; } /** * @brief Gestion de l'interuption des capteurs de positions. * * Fonction de callback permettant d'incrémenter le nombre * de tour des deux roues. * * @param None * @retval None */ void TIM1_CC_IRQHandler(void) { if (TIM_GetITStatus(TIM1, TIM_IT_CC1) == SET) { TIM_ClearITPendingBit(TIM1, TIM_IT_CC1); tourD++; tourPositionD++; } if (TIM_GetITStatus(TIM1, TIM_IT_CC3) == SET) { TIM_ClearITPendingBit(TIM1, TIM_IT_CC3); tourG++; tourPositionG++; } } /** * @brief Gestion de l'asservissement des moteurs * * @param None * @retval None */ void motorManagement(void) { if (regulation_vitesseD) { erreurD = (signed int) G_speedRight - (signed int) tourD; motD = kp * erreurD + integration1; integration1 += ki * erreurD; if (motD > 255) motD = 255; if (motD < 0) motD = 0; motD = (uint16_t) motD; motorSpeedUpdateRight(motD); tourD = 0; regulation_vitesseD = 0; if (G_lapsRight - tourPositionD < 0) { motorCmdRight(BRAKE, 255); } } if (regulation_vitesseG) { erreurG = (signed int) G_speedLeft - (signed int) tourG; motG = kp * erreurG + integration2; integration2 += ki * erreurG; if (motG > 255) motG = 255; if (motG < 0) motG = 0; motG = (uint16_t) motG; motorSpeedUpdateLeft(motG); tourG = 0; regulation_vitesseG = 0; if (G_lapsLeft - tourPositionG < 0) { motorCmdLeft(BRAKE, 255); } } if (G_lapsLeft - tourPositionG < 0 && G_lapsRight - tourPositionD < 0 && asservissement == 1) { motorCmdLeft(BRAKE, 255); motorCmdRight(BRAKE, 255); asservissement = 0; erreurD = 0; erreurG = 0; integration1 = 0; integration2 = 0; Dumber.busyState = FALSE; Dumber.cpt_inactivity = 0; } } /** * @} */ /** * @} */ /** * @} */ /*void regulationCBK(void) { if (regulation_vitesseD == 1) { erreurD = (signed int)G_speedRight - (signed int)tourD; motD = kp * erreurD +integration1; integration1 += ki * erreurD; if (motD>255) motD=255; if (motD<0) motD=0; motD=(uint16_t)motD; majVitesseMotorD(motD); tourD = 0; regulation_vitesseD=0; if (G_lapsRight-tourPositionD < 0) cmdRightMotor(BRAKE,0); } if (regulation_vitesseG == 1) { erreurG = (signed int)G_speedLeft - (signed int)tourG; motG = kp* erreurG + integration2; integration2 += ki * erreurG; if(motG>255) motG=255; if(motG<0) motG=0; motG=(uint16_t)motG; majVitesseMotorG(motG); tourG = 0; regulation_vitesseG=0; if (G_lapsLeft-tourPositionG < 0) cmdLeftMotor(BRAKE,0); } if (G_lapsLeft-tourPositionG < 0 && G_lapsRight-tourPositionD < 0 && asservissement == 1) { cmdLeftMotor(BRAKE,0); cmdRightMotor(BRAKE,0); asservissement = 0; erreurD=0; erreurG=0; integration1=0; integration2=0; Dumber.busyState=FALSE; Dumber.cpt_inactivity = 0; } }*/